PK!(vv(system/httpheaders/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\Httpheaders\Extension\Httpheaders; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $plugin = new Httpheaders( $container->get(DispatcherInterface::class), (array) PluginHelper::getPlugin('system', 'httpheaders'), Factory::getApplication() ); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!*}9!!/system/httpheaders/postinstall/introduction.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ use Joomla\CMS\Factory; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Checks if the plugin is enabled. If not it returns true, meaning that the * message concerning the HTTPHeaders Plugin should be displayed. * * @return integer * * @since 4.0.0 */ function httpheaders_postinstall_condition() { return !Joomla\CMS\Plugin\PluginHelper::isEnabled('system', 'httpheaders'); } /** * Enables the HTTPHeaders plugin * * @return void * * @since 4.0.0 */ function httpheaders_postinstall_action() { // Enable the plugin $db = Factory::getDbo(); $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) ->set($db->quoteName('enabled') . ' = 1') ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) ->where($db->quoteName('element') . ' = ' . $db->quote('httpheaders')); $db->setQuery($query); $db->execute(); $query = $db->getQuery(true) ->select('extension_id') ->from($db->quoteName('#__extensions')) ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) ->where($db->quoteName('element') . ' = ' . $db->quote('httpheaders')); $db->setQuery($query); $extensionId = $db->loadResult(); $url = 'index.php?option=com_plugins&task=plugin.edit&extension_id=' . $extensionId; Factory::getApplication()->redirect($url); } PK! --"system/httpheaders/httpheaders.xmlnu[ plg_system_httpheaders Joomla! Project 2017-10 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.0.0 PLG_SYSTEM_HTTPHEADERS_XML_DESCRIPTION Joomla\Plugin\System\Httpheaders postinstall services src
language/en-GB/plg_system_httpheaders.ini language/en-GB/plg_system_httpheaders.sys.ini
PK!mW{<{<0system/httpheaders/src/Extension/Httpheaders.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Httpheaders\Extension; use Joomla\CMS\Application\CMSApplicationInterface; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Uri\Uri; use Joomla\Database\DatabaseAwareTrait; use Joomla\Event\DispatcherInterface; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Plugin class for HTTP Headers * * @since 4.0.0 */ final class Httpheaders extends CMSPlugin implements SubscriberInterface { use DatabaseAwareTrait; /** * The generated csp nonce value * * @var string * @since 4.0.0 */ private $cspNonce; /** * The list of the supported HTTP headers * * @var array * @since 4.0.0 */ private $supportedHttpHeaders = [ 'strict-transport-security', 'content-security-policy', 'content-security-policy-report-only', 'x-frame-options', 'referrer-policy', 'expect-ct', 'feature-policy', 'cross-origin-opener-policy', 'report-to', 'permissions-policy', 'nel', ]; /** * The list of valid directives based on: https://www.w3.org/TR/CSP3/#csp-directives * * @var array * @since 4.0.0 */ private $validDirectives = [ 'child-src', 'connect-src', 'default-src', 'font-src', 'frame-src', 'img-src', 'manifest-src', 'media-src', 'prefetch-src', 'object-src', 'script-src', 'script-src-elem', 'script-src-attr', 'style-src', 'style-src-elem', 'style-src-attr', 'worker-src', 'base-uri', 'plugin-types', 'sandbox', 'form-action', 'frame-ancestors', 'navigate-to', 'report-uri', 'report-to', 'block-all-mixed-content', 'upgrade-insecure-requests', 'require-sri-for', ]; /** * The list of directives without a value * * @var array * @since 4.0.0 */ private $noValueDirectives = [ 'block-all-mixed-content', 'upgrade-insecure-requests', ]; /** * The list of directives supporting nonce * * @var array * @since 4.0.0 */ private $nonceDirectives = [ 'script-src', 'style-src', ]; /** * @param DispatcherInterface $dispatcher The object to observe -- event dispatcher. * @param array $config An optional associative array of configuration settings. * @param CMSApplicationInterface $app The app * * @since 4.0.0 */ public function __construct(DispatcherInterface $dispatcher, $config, CMSApplicationInterface $app) { parent::__construct($dispatcher, $config); $this->setApplication($app); $nonceEnabled = (int) $this->params->get('nonce_enabled', 0); // Nonce generation when it's enabled if ($nonceEnabled) { $this->cspNonce = base64_encode(bin2hex(random_bytes(64))); } // Set the nonce, when not set we set it to NULL which is checked down the line $this->getApplication()->set('csp_nonce', $this->cspNonce); } /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.0.0 */ public static function getSubscribedEvents(): array { return [ 'onAfterInitialise' => 'setHttpHeaders', 'onAfterRender' => 'applyHashesToCspRule', ]; } /** * The `applyHashesToCspRule` method makes sure the csp hashes are added to the csp header when enabled * * @return void * * @since 4.0.0 */ public function applyHashesToCspRule(Event $event): void { // CSP is only relevant on html pages. Let's early exit here. if ($this->getApplication()->getDocument()->getType() !== 'html') { return; } $scriptHashesEnabled = (int) $this->params->get('script_hashes_enabled', 0); $styleHashesEnabled = (int) $this->params->get('style_hashes_enabled', 0); // Early exit when both options are disabled if (!$scriptHashesEnabled && !$styleHashesEnabled) { return; } $headData = $this->getApplication()->getDocument()->getHeadData(); $scriptHashes = []; $styleHashes = []; if ($scriptHashesEnabled) { // Generate the hashes for the script-src $inlineScripts = is_array($headData['script']) ? $headData['script'] : []; foreach ($inlineScripts as $type => $scripts) { foreach ($scripts as $hash => $scriptContent) { $scriptHashes[] = "'sha256-" . base64_encode(hash('sha256', $scriptContent, true)) . "'"; } } } if ($styleHashesEnabled) { // Generate the hashes for the style-src $inlineStyles = is_array($headData['style']) ? $headData['style'] : []; foreach ($inlineStyles as $type => $styles) { foreach ($styles as $hash => $styleContent) { $styleHashes[] = "'sha256-" . base64_encode(hash('sha256', $styleContent, true)) . "'"; } } } // Replace the hashes in the csp header when set. $headers = $this->getApplication()->getHeaders(); foreach ($headers as $id => $headerConfiguration) { if ( strtolower($headerConfiguration['name']) === 'content-security-policy' || strtolower($headerConfiguration['name']) === 'content-security-policy-report-only' ) { $newHeaderValue = $headerConfiguration['value']; if (!empty($scriptHashes)) { $newHeaderValue = str_replace('{script-hashes}', implode(' ', $scriptHashes), $newHeaderValue); } else { $newHeaderValue = str_replace('{script-hashes}', '', $newHeaderValue); } if (!empty($styleHashes)) { $newHeaderValue = str_replace('{style-hashes}', implode(' ', $styleHashes), $newHeaderValue); } else { $newHeaderValue = str_replace('{style-hashes}', '', $newHeaderValue); } $this->getApplication()->setHeader($headerConfiguration['name'], $newHeaderValue, true); } } } /** * The `setHttpHeaders` method handle the setting of the configured HTTP Headers * * @return void * * @since 4.0.0 */ public function setHttpHeaders(Event $event): void { // Set the default header when they are enabled $this->setStaticHeaders(); // Handle CSP Header configuration $cspEnabled = (int) $this->params->get('contentsecuritypolicy', 0); $cspClient = (string) $this->params->get('contentsecuritypolicy_client', 'site'); // Check whether CSP is enabled and enabled by the current client if ($cspEnabled && ($this->getApplication()->isClient($cspClient) || $cspClient === 'both')) { $this->setCspHeader(); } } /** * Set the CSP header when enabled * * @return void * * @since 4.0.0 */ private function setCspHeader(): void { $cspReadOnly = (int) $this->params->get('contentsecuritypolicy_report_only', 1); $cspHeader = $cspReadOnly === 0 ? 'content-security-policy' : 'content-security-policy-report-only'; // In custom mode we compile the header from the values configured $cspValues = $this->params->get('contentsecuritypolicy_values', []); $nonceEnabled = (int) $this->params->get('nonce_enabled', 0); $scriptHashesEnabled = (int) $this->params->get('script_hashes_enabled', 0); $strictDynamicEnabled = (int) $this->params->get('strict_dynamic_enabled', 0); $styleHashesEnabled = (int) $this->params->get('style_hashes_enabled', 0); $frameAncestorsSelfEnabled = (int) $this->params->get('frame_ancestors_self_enabled', 1); $frameAncestorsSet = false; foreach ($cspValues as $cspValue) { // Handle the client settings foreach header if (!$this->getApplication()->isClient($cspValue->client) && $cspValue->client != 'both') { continue; } // Handle non value directives if (in_array($cspValue->directive, $this->noValueDirectives)) { $newCspValues[] = trim($cspValue->directive); continue; } // We can only use this if this is a valid entry if ( in_array($cspValue->directive, $this->validDirectives) && !empty($cspValue->value) ) { if (in_array($cspValue->directive, $this->nonceDirectives) && $nonceEnabled) { /** * That line is for B/C we do no longer require to add the nonce tag * but add it once the setting is enabled so this line here is needed * to remove the outdated tag that was required until 4.2.0 */ $cspValue->value = str_replace('{nonce}', '', $cspValue->value); // Append the nonce when the nonce setting is enabled $cspValue->value = "'nonce-" . $this->cspNonce . "' " . $cspValue->value; } // Append the script hashes placeholder if ($scriptHashesEnabled && strpos($cspValue->directive, 'script-src') === 0) { $cspValue->value = '{script-hashes} ' . $cspValue->value; } // Append the style hashes placeholder if ($styleHashesEnabled && strpos($cspValue->directive, 'style-src') === 0) { $cspValue->value = '{style-hashes} ' . $cspValue->value; } if ($cspValue->directive === 'frame-ancestors') { $frameAncestorsSet = true; } // Add strict-dynamic to the script-src directive when enabled if ( $strictDynamicEnabled && $cspValue->directive === 'script-src' && strpos($cspValue->value, 'strict-dynamic') === false ) { $cspValue->value = "'strict-dynamic' " . $cspValue->value; } $newCspValues[] = trim($cspValue->directive) . ' ' . trim($cspValue->value); } } if ($frameAncestorsSelfEnabled && !$frameAncestorsSet) { $newCspValues[] = "frame-ancestors 'self'"; } if (empty($newCspValues)) { return; } $this->getApplication()->setHeader($cspHeader, trim(implode('; ', $newCspValues))); } /** * Get the configured static headers. * * @return array We return the array of static headers with its values. * * @since 4.0.0 */ private function getStaticHeaderConfiguration(): array { $staticHeaderConfiguration = []; // X-frame-options if ($this->params->get('xframeoptions', 1) === 1) { $staticHeaderConfiguration['x-frame-options#both'] = 'SAMEORIGIN'; } // Referrer-policy $referrerPolicy = (string) $this->params->get('referrerpolicy', 'strict-origin-when-cross-origin'); if ($referrerPolicy !== 'disabled') { $staticHeaderConfiguration['referrer-policy#both'] = $referrerPolicy; } // Cross-Origin-Opener-Policy $coop = (string) $this->params->get('coop', 'same-origin'); if ($coop !== 'disabled') { $staticHeaderConfiguration['cross-origin-opener-policy#both'] = $coop; } // Generate the strict-transport-security header and make sure the site is SSL if ($this->params->get('hsts', 0) === 1 && Uri::getInstance()->isSsl() === true) { $hstsOptions = []; $hstsOptions[] = 'max-age=' . (int) $this->params->get('hsts_maxage', 31536000); if ($this->params->get('hsts_subdomains', 0) === 1) { $hstsOptions[] = 'includeSubDomains'; } if ($this->params->get('hsts_preload', 0) === 1) { $hstsOptions[] = 'preload'; } $staticHeaderConfiguration['strict-transport-security#both'] = implode('; ', $hstsOptions); } // Generate the additional headers $additionalHttpHeaders = $this->params->get('additional_httpheader', []); foreach ($additionalHttpHeaders as $additionalHttpHeader) { // Make sure we have a key and a value if (empty($additionalHttpHeader->key) || empty($additionalHttpHeader->value)) { continue; } // Make sure the header is a valid and supported header if (!in_array(strtolower($additionalHttpHeader->key), $this->supportedHttpHeaders)) { continue; } // Make sure we do not add one header twice but we support to set a different header per client. if ( isset($staticHeaderConfiguration[$additionalHttpHeader->key . '#' . $additionalHttpHeader->client]) || isset($staticHeaderConfiguration[$additionalHttpHeader->key . '#both']) ) { continue; } // Allow the custom csp headers to use the random $cspNonce in the rules if (in_array(strtolower($additionalHttpHeader->key), ['content-security-policy', 'content-security-policy-report-only'])) { $additionalHttpHeader->value = str_replace('{nonce}', "'nonce-" . $this->cspNonce . "'", $additionalHttpHeader->value); } $staticHeaderConfiguration[$additionalHttpHeader->key . '#' . $additionalHttpHeader->client] = $additionalHttpHeader->value; } return $staticHeaderConfiguration; } /** * Set the static headers when enabled * * @return void * * @since 4.0.0 */ private function setStaticHeaders(): void { $staticHeaderConfiguration = $this->getStaticHeaderConfiguration(); if (empty($staticHeaderConfiguration)) { return; } foreach ($staticHeaderConfiguration as $headerAndClient => $value) { $headerAndClient = explode('#', $headerAndClient); $header = $headerAndClient[0]; $client = $headerAndClient[1] ?? 'both'; if (!$this->getApplication()->isClient($client) && $client != 'both') { continue; } $this->getApplication()->setHeader($header, $value, true); } } } PK!7{/,%system/remember/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\Remember\Extension\Remember; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Remember( $dispatcher, (array) PluginHelper::getPlugin('system', 'remember') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!YYsystem/remember/remember.xmlnu[ plg_system_remember Joomla! Project 2007-04 (C) 2007 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_REMEMBER_XML_DESCRIPTION Joomla\Plugin\System\Remember services src language/en-GB/plg_system_remember.ini language/en-GB/plg_system_remember.sys.ini PK!~[***system/remember/src/Extension/Remember.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Remember\Extension; use Joomla\CMS\Log\Log; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\User\UserHelper; use Joomla\Database\DatabaseAwareTrait; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! System Remember Me Plugin * * @since 1.5 */ final class Remember extends CMSPlugin { use DatabaseAwareTrait; /** * Remember me method to run onAfterInitialise * Only purpose is to initialise the login authentication process if a cookie is present * * @return void * * @since 1.5 * * @throws InvalidArgumentException */ public function onAfterInitialise() { // No remember me for admin. if (!$this->getApplication()->isClient('site')) { return; } // Check for a cookie if user is not logged in if ($this->getApplication()->getIdentity()->guest) { $cookieName = 'joomla_remember_me_' . UserHelper::getShortHashedUserAgent(); // Check for the cookie if ($this->getApplication()->getInput()->cookie->get($cookieName)) { $this->getApplication()->login(['username' => ''], ['silent' => true]); } } } /** * Imports the authentication plugin on user logout to make sure that the cookie is destroyed. * * @param array $user Holds the user data. * @param array $options Array holding options (remember, autoregister, group). * * @return boolean */ public function onUserLogout($user, $options) { // No remember me for admin if (!$this->getApplication()->isClient('site')) { return true; } $cookieName = 'joomla_remember_me_' . UserHelper::getShortHashedUserAgent(); // Check for the cookie if ($this->getApplication()->getInput()->cookie->get($cookieName)) { // Make sure authentication group is loaded to process onUserAfterLogout event PluginHelper::importPlugin('authentication'); } return true; } /** * Method is called before user data is stored in the database * Invalidate all existing remember-me cookies after a password change * * @param array $user Holds the old user data. * @param boolean $isnew True if a new user is stored. * @param array $data Holds the new user data. * * @return boolean * * @since 3.8.6 */ public function onUserBeforeSave($user, $isnew, $data) { // Irrelevant on new users if ($isnew) { return true; } // Irrelevant, because password was not changed by user if (empty($data['password_clear'])) { return true; } // But now, we need to do something - Delete all tokens for this user! $db = $this->getDatabase(); $query = $db->getQuery(true) ->delete($db->quoteName('#__user_keys')) ->where($db->quoteName('user_id') . ' = :userid') ->bind(':userid', $user['username']); try { $db->setQuery($query)->execute(); } catch (\RuntimeException $e) { // Log an alert for the site admin Log::add( sprintf('Failed to delete cookie token for user %s with the following error: %s', $user['username'], $e->getMessage()), Log::WARNING, 'security' ); } return true; } } PK!K44&system/highlight/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\Highlight\Extension\Highlight; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Highlight( $dispatcher, (array) PluginHelper::getPlugin('system', 'highlight') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!*e}ffsystem/highlight/highlight.xmlnu[ plg_system_highlight Joomla! Project 2011-08 (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_SYSTEM_HIGHLIGHT_XML_DESCRIPTION Joomla\Plugin\System\Highlight services src language/en-GB/plg_system_highlight.ini language/en-GB/plg_system_highlight.sys.ini PK!u&^^,system/highlight/src/Extension/Highlight.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Highlight\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\Finder\Administrator\Indexer\Result; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * System plugin to highlight terms. * * @since 2.5 */ final class Highlight extends CMSPlugin { /** * Method to catch the onAfterDispatch event. * * This is where we setup the click-through content highlighting for. * The highlighting is done with JavaScript so we just * need to check a few parameters and the JHtml behavior will do the rest. * * @return void * * @since 2.5 */ public function onAfterDispatch() { // Check that we are in the site application. if (!$this->getApplication()->isClient('site')) { return; } // Set the variables. $input = $this->getApplication()->getInput(); $extension = $input->get('option', '', 'cmd'); // Check if the highlighter is enabled. if (!ComponentHelper::getParams($extension)->get('highlight_terms', 1)) { return; } // Check if the highlighter should be activated in this environment. if ($input->get('tmpl', '', 'cmd') === 'component' || $this->getApplication()->getDocument()->getType() !== 'html') { return; } // Get the terms to highlight from the request. $terms = $input->request->get('highlight', null, 'base64'); $terms = $terms ? json_decode(base64_decode($terms)) : null; // Check the terms. if (empty($terms)) { return; } // Clean the terms array. $filter = InputFilter::getInstance(); $cleanTerms = []; foreach ($terms as $term) { $cleanTerms[] = htmlspecialchars($filter->clean($term, 'string')); } /** @var \Joomla\CMS\Document\HtmlDocument $doc */ $doc = $this->getApplication()->getDocument(); // Activate the highlighter. if (!empty($cleanTerms)) { $doc->getWebAssetManager()->useScript('highlight'); $doc->addScriptOptions( 'highlight', [[ 'class' => 'js-highlight', 'highLight' => $cleanTerms, ]] ); } // Adjust the component buffer. $buf = $doc->getBuffer('component'); $buf = '
' . $buf . '
'; $doc->setBuffer($buf, 'component'); } /** * Method to catch the onFinderResult event. * * @param Result $item The search result * @param object $query The search query of this result * * @return void * * @since 4.0.0 */ public function onFinderResult($item, $query) { static $params; if (is_null($params)) { $params = ComponentHelper::getParams('com_finder'); } // Get the route with highlighting information. if ( !empty($query->highlight) && empty($item->mime) && $params->get('highlight_terms', 1) ) { $item->route .= '&highlight=' . base64_encode(json_encode($query->highlight)); } } } PK!Ərsystem/stats/stats.xmlnu[ plg_system_stats Joomla! Project 2013-11 (C) 2013 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.5.0 PLG_SYSTEM_STATS_XML_DESCRIPTION Joomla\Plugin\System\Stats layouts services src language/en-GB/plg_system_stats.ini language/en-GB/plg_system_stats.sys.ini
PK!z:"system/stats/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\Stats\Extension\Stats; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Stats( $dispatcher, (array) PluginHelper::getPlugin('system', 'stats') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!W%88 system/stats/layouts/message.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\Registry\Registry; extract($displayData); /** * Layout variables * ----------------- * @var PlgSystemStats $plugin Plugin rendering this layout * @var Registry $pluginParams Plugin parameters * @var array $statsData Array containing the data that will be sent to the stats server */ ?> PK!'system/stats/layouts/field/uniqueid.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; extract($displayData); /** * Layout variables * ----------------- * @var string $autocomplete Autocomplete attribute for the field. * @var boolean $autofocus Is autofocus enabled? * @var string $class Classes for the input. * @var string $description Description of the field. * @var boolean $disabled Is this field disabled? * @var string $group Group the field belongs to. section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $options Options available for this field. */ ?> PK!q^  #system/stats/layouts/field/data.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */ $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); $wa->registerAndUseScript('plg_system_stats.stats', 'plg_system_stats/stats.js', [], ['defer' => true], ['core']); extract($displayData); /** * Layout variables * ----------------- * @var string $autocomplete Autocomplete attribute for the field. * @var boolean $autofocus Is autofocus enabled? * @var string $class Classes for the input. * @var string $description Description of the field. * @var boolean $disabled Is this field disabled? * @var string $group Group the field belongs to. section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $options Options available for this field. * @var array $statsData Statistics that will be sent to the stats server */ ?> render('stats', compact('statsData')); ?> PK!3-iisystem/stats/layouts/stats.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; extract($displayData); /** * Layout variables * ----------------- * @var array $statsData Array containing the data that will be sent to the stats server */ $versionFields = ['php_version', 'db_version', 'cms_version']; ?> $value) : ?>
PK!BZDZD$system/stats/src/Extension/Stats.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Stats\Extension; use Joomla\CMS\Cache\Cache; use Joomla\CMS\Http\HttpFactory; use Joomla\CMS\Layout\FileLayout; use Joomla\CMS\Log\Log; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\User\UserHelper; use Joomla\Database\DatabaseAwareTrait; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects // Uncomment the following line to enable debug mode for testing purposes. Note: statistics will be sent on every page load // define('PLG_SYSTEM_STATS_DEBUG', 1); /** * Statistics system plugin. This sends anonymous data back to the Joomla! Project about the * PHP, SQL, Joomla and OS versions * * @since 3.5 */ final class Stats extends CMSPlugin { use DatabaseAwareTrait; /** * Indicates sending statistics is always allowed. * * @var integer * * @since 3.5 */ public const MODE_ALLOW_ALWAYS = 1; /** * Indicates sending statistics is never allowed. * * @var integer * * @since 3.5 */ public const MODE_ALLOW_NEVER = 3; /** * URL to send the statistics. * * @var string * * @since 3.5 */ protected $serverUrl = 'https://developer.joomla.org/stats/submit'; /** * Unique identifier for this site * * @var string * * @since 3.5 */ protected $uniqueId; /** * Listener for the `onAfterInitialise` event * * @return void * * @since 3.5 */ public function onAfterInitialise() { if (!$this->getApplication()->isClient('administrator') || !$this->isAllowedUser()) { return; } if ($this->isCaptiveMFA()) { return; } if (!$this->isDebugEnabled() && !$this->isUpdateRequired()) { return; } if ($this->getApplication()->getInput()->getVar('tmpl') === 'component') { return; } // Load plugin language files only when needed (ex: they are not needed in site client). $this->loadLanguage(); } /** * Listener for the `onAfterDispatch` event * * @return void * * @since 4.0.0 */ public function onAfterDispatch() { if (!$this->getApplication()->isClient('administrator') || !$this->isAllowedUser()) { return; } if ($this->isCaptiveMFA()) { return; } if (!$this->isDebugEnabled() && !$this->isUpdateRequired()) { return; } if ($this->getApplication()->getInput()->getVar('tmpl') === 'component') { return; } if ($this->getApplication()->getDocument()->getType() !== 'html') { return; } $this->getApplication()->getDocument()->getWebAssetManager() ->registerAndUseScript('plg_system_stats.message', 'plg_system_stats/stats-message.js', [], ['defer' => true], ['core']); } /** * User selected to always send data * * @return void * * @since 3.5 * * @throws \Exception If user is not allowed. * @throws \RuntimeException If there is an error saving the params or sending the data. */ public function onAjaxSendAlways() { if (!$this->isAllowedUser() || !$this->isAjaxRequest()) { throw new \Exception($this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_ACCESS_DENIED'), 403); } $this->params->set('mode', static::MODE_ALLOW_ALWAYS); if (!$this->saveParams()) { throw new \RuntimeException('Unable to save plugin settings', 500); } echo json_encode(['sent' => (int) $this->sendStats()]); } /** * User selected to never send data. * * @return void * * @since 3.5 * * @throws \Exception If user is not allowed. * @throws \RuntimeException If there is an error saving the params. */ public function onAjaxSendNever() { if (!$this->isAllowedUser() || !$this->isAjaxRequest()) { throw new \Exception($this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_ACCESS_DENIED'), 403); } $this->params->set('mode', static::MODE_ALLOW_NEVER); if (!$this->saveParams()) { throw new \RuntimeException('Unable to save plugin settings', 500); } if (!$this->disablePlugin()) { throw new \RuntimeException('Unable to disable the statistics plugin', 500); } echo json_encode(['sent' => 0]); } /** * Send the stats to the server. * On first load | on demand mode it will show a message asking users to select mode. * * @return void * * @since 3.5 * * @throws \Exception If user is not allowed. * @throws \RuntimeException If there is an error saving the params, disabling the plugin or sending the data. */ public function onAjaxSendStats() { if (!$this->isAllowedUser() || !$this->isAjaxRequest()) { throw new \Exception($this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_ACCESS_DENIED'), 403); } // User has not selected the mode. Show message. if ((int) $this->params->get('mode') !== static::MODE_ALLOW_ALWAYS) { $data = [ 'sent' => 0, 'html' => $this->getRenderer('message')->render($this->getLayoutData()), ]; echo json_encode($data); return; } if (!$this->saveParams()) { throw new \RuntimeException('Unable to save plugin settings', 500); } echo json_encode(['sent' => (int) $this->sendStats()]); } /** * Get the data through events * * @param string $context Context where this will be called from * * @return array * * @since 3.5 */ public function onGetStatsData($context) { return $this->getStatsData(); } /** * Debug a layout of this plugin * * @param string $layoutId Layout identifier * @param array $data Optional data for the layout * * @return string * * @since 3.5 */ public function debug($layoutId, $data = []) { $data = array_merge($this->getLayoutData(), $data); return $this->getRenderer($layoutId)->debug($data); } /** * Get the data for the layout * * @return array * * @since 3.5 */ private function getLayoutData() { return [ 'plugin' => $this, 'pluginParams' => $this->params, 'statsData' => $this->getStatsData(), ]; } /** * Get the layout paths * * @return array * * @since 3.5 */ private function getLayoutPaths() { $template = $this->getApplication()->getTemplate(); return [ JPATH_ADMINISTRATOR . '/templates/' . $template . '/html/layouts/plugins/' . $this->_type . '/' . $this->_name, JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/layouts', ]; } /** * Get the plugin renderer * * @param string $layoutId Layout identifier * * @return \Joomla\CMS\Layout\LayoutInterface * * @since 3.5 */ private function getRenderer($layoutId = 'default') { $renderer = new FileLayout($layoutId); $renderer->setIncludePaths($this->getLayoutPaths()); return $renderer; } /** * Get the data that will be sent to the stats server. * * @return array * * @since 3.5 */ private function getStatsData() { $data = [ 'unique_id' => $this->getUniqueId(), 'php_version' => PHP_VERSION, 'db_type' => $this->getDatabase()->name, 'db_version' => $this->getDatabase()->getVersion(), 'cms_version' => JVERSION, 'server_os' => php_uname('s') . ' ' . php_uname('r'), ]; // Check if we have a MariaDB version string and extract the proper version from it if (preg_match('/^(?:5\.5\.5-)?(mariadb-)?(?P\d+)\.(?P\d+)\.(?P\d+)/i', $data['db_version'], $versionParts)) { $data['db_version'] = $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch']; } return $data; } /** * Get the unique id. Generates one if none is set. * * @return integer * * @since 3.5 */ private function getUniqueId() { if (null === $this->uniqueId) { $this->uniqueId = $this->params->get('unique_id', hash('sha1', UserHelper::genRandomPassword(28) . time())); } return $this->uniqueId; } /** * Check if current user is allowed to send the data * * @return boolean * * @since 3.5 */ private function isAllowedUser() { return $this->getApplication()->getIdentity() && $this->getApplication()->getIdentity()->authorise('core.admin'); } /** * Check if the debug is enabled * * @return boolean * * @since 3.5 */ private function isDebugEnabled() { return defined('PLG_SYSTEM_STATS_DEBUG'); } /** * Check if last_run + interval > now * * @return boolean * * @since 3.5 */ private function isUpdateRequired() { $last = (int) $this->params->get('lastrun', 0); $interval = (int) $this->params->get('interval', 12); $mode = (int) $this->params->get('mode', 0); if ($mode === static::MODE_ALLOW_NEVER) { return false; } // Never updated or debug enabled if (!$last || $this->isDebugEnabled()) { return true; } return abs(time() - $last) > $interval * 3600; } /** * Check valid AJAX request * * @return boolean * * @since 3.5 */ private function isAjaxRequest() { return strtolower($this->getApplication()->getInput()->server->get('HTTP_X_REQUESTED_WITH', '')) === 'xmlhttprequest'; } /** * Render a layout of this plugin * * @param string $layoutId Layout identifier * @param array $data Optional data for the layout * * @return string * * @since 3.5 */ public function render($layoutId, $data = []) { $data = array_merge($this->getLayoutData(), $data); return $this->getRenderer($layoutId)->render($data); } /** * Save the plugin parameters * * @return boolean * * @since 3.5 */ private function saveParams() { // Update params $this->params->set('lastrun', time()); $this->params->set('unique_id', $this->getUniqueId()); $interval = (int) $this->params->get('interval', 12); $this->params->set('interval', $interval ?: 12); $paramsJson = $this->params->toString('JSON'); $db = $this->getDatabase(); $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) ->set($db->quoteName('params') . ' = :params') ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) ->where($db->quoteName('element') . ' = ' . $db->quote('stats')) ->bind(':params', $paramsJson); try { // Lock the tables to prevent multiple plugin executions causing a race condition $db->lockTable('#__extensions'); } catch (\Exception $e) { // If we can't lock the tables it's too risky to continue execution return false; } try { // Update the plugin parameters $result = $db->setQuery($query)->execute(); $this->clearCacheGroups(['com_plugins']); } catch (\Exception $exc) { // If we failed to execute $db->unlockTables(); $result = false; } try { // Unlock the tables after writing $db->unlockTables(); } catch (\Exception $e) { // If we can't lock the tables assume we have somehow failed $result = false; } return $result; } /** * Send the stats to the stats server * * @return boolean * * @since 3.5 * * @throws \RuntimeException If there is an error sending the data and debug mode enabled. */ private function sendStats() { $error = false; try { // Don't let the request take longer than 2 seconds to avoid page timeout issues $response = HttpFactory::getHttp()->post($this->serverUrl, $this->getStatsData(), [], 2); if (!$response) { $error = 'Could not send site statistics to remote server: No response'; } elseif ($response->code !== 200) { $data = json_decode($response->body); $error = 'Could not send site statistics to remote server: ' . $data->message; } } catch (\UnexpectedValueException $e) { // There was an error sending stats. Should we do anything? $error = 'Could not send site statistics to remote server: ' . $e->getMessage(); } catch (\RuntimeException $e) { // There was an error connecting to the server or in the post request $error = 'Could not connect to statistics server: ' . $e->getMessage(); } catch (\Exception $e) { // An unexpected error in processing; don't let this failure kill the site $error = 'Unexpected error connecting to statistics server: ' . $e->getMessage(); } if ($error !== false) { // Log any errors if logging enabled. Log::add($error, Log::WARNING, 'jerror'); // If Stats debug mode enabled, or Global Debug mode enabled, show error to the user. if ($this->isDebugEnabled() || $this->getApplication()->get('debug')) { throw new \RuntimeException($error, 500); } return false; } return true; } /** * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. * * @param array $clearGroups The cache groups to clean * * @return void * * @since 3.5 */ private function clearCacheGroups(array $clearGroups) { foreach ($clearGroups as $group) { try { $options = [ 'defaultgroup' => $group, 'cachebase' => $this->getApplication()->get('cache_path', JPATH_CACHE), ]; $cache = Cache::getInstance('callback', $options); $cache->clean(); } catch (\Exception $e) { // Ignore it } } } /** * Disable this plugin, if user selects once or never, to stop Joomla loading the plugin on every page load and * therefore regaining a tiny bit of performance * * @since 4.0.0 * * @return boolean */ private function disablePlugin() { $db = $this->getDatabase(); $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) ->set($db->quoteName('enabled') . ' = 0') ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) ->where($db->quoteName('element') . ' = ' . $db->quote('stats')); try { // Lock the tables to prevent multiple plugin executions causing a race condition $db->lockTable('#__extensions'); } catch (\Exception $e) { // If we can't lock the tables it's too risky to continue execution return false; } try { // Update the plugin parameters $result = $db->setQuery($query)->execute(); $this->clearCacheGroups(['com_plugins']); } catch (\Exception $exc) { // If we failed to execute $db->unlockTables(); $result = false; } try { // Unlock the tables after writing $db->unlockTables(); } catch (\Exception $e) { // If we can't lock the tables assume we have somehow failed $result = false; } return $result; } /** * Are we in a Multi-factor Authentication page? * * @return bool * @since 4.2.1 */ private function isCaptiveMFA(): bool { return method_exists($this->getApplication(), 'isMultiFactorAuthenticationPage') && $this->getApplication()->isMultiFactorAuthenticationPage(true); } } PK!933$system/stats/src/Field/DataField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Stats\Field; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Unique ID Field class for the Stats Plugin. * * @since 3.5 */ class DataField extends AbstractStatsField { /** * The form field type. * * @var string * @since 3.5 */ protected $type = 'Data'; /** * Name of the layout being used to render the field * * @var string * @since 3.5 */ protected $layout = 'field.data'; /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 3.5 */ protected function getLayoutData() { $data = parent::getLayoutData(); PluginHelper::importPlugin('system', 'stats'); $result = Factory::getApplication()->triggerEvent('onGetStatsData', ['stats.field.data']); $data['statsData'] = $result ? reset($result) : []; return $data; } } PK!\Jy-system/stats/src/Field/AbstractStatsField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Stats\Field; use Joomla\CMS\Factory; use Joomla\CMS\Form\FormField; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Base field for the Stats Plugin. * * @since 3.5 */ abstract class AbstractStatsField extends FormField { /** * Get the layouts paths * * @return array * * @since 3.5 */ protected function getLayoutPaths() { $template = Factory::getApplication()->getTemplate(); return [ JPATH_ADMINISTRATOR . '/templates/' . $template . '/html/layouts/plugins/system/stats', JPATH_PLUGINS . '/system/stats/layouts', JPATH_SITE . '/layouts', ]; } } PK!t8c(system/stats/src/Field/UniqueidField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Stats\Field; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Unique ID Field class for the Stats Plugin. * * @since 3.5 */ class UniqueidField extends AbstractStatsField { /** * The form field type. * * @var string * @since 3.5 */ protected $type = 'Uniqueid'; /** * Name of the layout being used to render the field * * @var string * @since 3.5 */ protected $layout = 'field.uniqueid'; } PK!"system/log/log.xmlnu[ plg_system_log Joomla! Project 2007-04 (C) 2007 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_LOG_XML_DESCRIPTION Joomla\Plugin\System\Log services src language/en-GB/plg_system_log.ini language/en-GB/plg_system_log.sys.ini
PK! system/log/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\Log\Extension\Log; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Log( $dispatcher, (array) PluginHelper::getPlugin('system', 'log') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!j system/log/src/Extension/Log.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Log\Extension; use Joomla\CMS\Authentication\Authentication; use Joomla\CMS\Log\Log as Logger; use Joomla\CMS\Plugin\CMSPlugin; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! System Logging Plugin. * * @since 1.5 */ final class Log extends CMSPlugin { /** * Called if user fails to be logged in. * * @param array $response Array of response data. * * @return void * * @since 1.5 */ public function onUserLoginFailure($response) { $errorlog = []; switch ($response['status']) { case Authentication::STATUS_SUCCESS: $errorlog['status'] = $response['type'] . ' CANCELED: '; $errorlog['comment'] = $response['error_message']; break; case Authentication::STATUS_FAILURE: $errorlog['status'] = $response['type'] . ' FAILURE: '; if ($this->params->get('log_username', 0)) { $errorlog['comment'] = $response['error_message'] . ' ("' . $response['username'] . '")'; } else { $errorlog['comment'] = $response['error_message']; } break; default: $errorlog['status'] = $response['type'] . ' UNKNOWN ERROR: '; $errorlog['comment'] = $response['error_message']; break; } Logger::addLogger([], Logger::INFO); try { Logger::add($errorlog['comment'], Logger::INFO, $errorlog['status']); } catch (\Exception $e) { // If the log file is unwriteable during login then we should not go to the error page return; } } } PK!OW iiBsystem/nrframework/language/hu-HU/hu-HU.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Rendszer - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - Tassos.gr által fejlesztett bővítményekhez" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Mellőz" NR_INCLUDE="Befoglal" NR_EXCLUDE="Kizár" NR_SELECTION="Kiválasztás" NR_ASSIGN_MENU_NOITEM="Elemazonosító nélküli befoglalás" NR_ASSIGN_MENU_NOITEM_DESC="Hozzárendelés akkor is, ha nincs menüelem-azonosító beállítva az URL-ben?" ; NR_ASSIGN_MENU_CHILD="Also on child items" ; NR_ASSIGN_MENU_CHILD_DESC="Also assign to child items of the selected items?" NR_COPY_OF="%s másolata" ; NR_ASSIGN_DATETIME_DESC="Target visitors based on your server's datetime" NR_DATETIME="Dátum és idő" ; NR_TIME="Time" ; NR_DATE="Date" NR_DATETIME_DESC="Dátum és idő megadása az automatikus közzététel/lejárat beállításához" ; NR_START_PUBLISHING="Start Datetime" NR_START_PUBLISHING_DESC="Közzététel kezdetének megadása" ; NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="Közzététel végének megadása" NR_DATETIME_NOTE="A dátum hozzárendelése a szerveridőhöz történik, és nem a látogató gépének idejéhez." ; NR_ASSIGN_PHP="PHP" ; NR_PHPCODE="PHP Code" ; NR_ASSIGN_PHP_DESC="Enter a piece of PHP code to evaluate." ; NR_ASSIGN_PHP_DESC2="Target visitors evaluating custom PHP code. The code must return the value true or false.

For instance:
return ($user->name == 'Tassos Marinos');" ; NR_ASSIGN_TIMEONSITE="Time on Site" NR_SECONDS="Másodperc" ; NR_ASSIGN_TIMEONSITE_DESC="Enter a duration in seconds to compare with the user's total time (Visit duration) spent on your entire site .

Example:
If you want to display a box after the user has spent 3 minutes on your the entire site, enter 180." NR_ASSIGN_URLS="URL" ; NR_ASSIGN_URLS_DESC2="Target visitors who are browsing specific URLs" NR_ASSIGN_URLS_DESC="(Rész) URL-ek megadása a találatokhoz.
Használj új sort minden egyes megfeleltetésnek." NR_ASSIGN_URLS_LIST="URL egyezések" ; NR_ASSIGN_URLS_REGEX="Use Regular Expression" NR_ASSIGN_URLS_REGEX_DESC="A kezelni kívánt érték kiválasztása, úgy mint a reguláris kifejezések." ; NR_ASSIGN_LANGS="Language" ; NR_ASSIGN_LANGS_DESC="Target visitors who are browsing your website in specific language" NR_ASSIGN_LANGS_LIST_DESC="Nyelv kiválasztása a hozzárendeléshez" ; NR_ASSIGN_DEVICES="Device" ; NR_ASSIGN_DEVICES_DESC2="Target visitors using specific device such as Mobile, Tablet or Desktop." NR_ASSIGN_DEVICES_DESC="Eszközök kiválasztása a hozzárendeléshez" NR_ASSIGN_DEVICES_NOTE="Tartsd szem előtt, hogy az eszközfelimerés pontossága nem mindig 100%-os. A felhasználók be tudják állítani úgy a böngészőjüket, hogy az más eszközöket emuláljon." ; NR_MENU="Menu" ; NR_MENU_ITEMS="Menu Item" ; NR_MENU_ITEMS_DESC="Target visitors who are browsing specific menu items" ; NR_USERGROUP="User Group" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." ; NR_ACCESSLEVEL="User Group" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Szerzői jogok megjelenítése" NR_SHOW_COPYRIGHT_DESC="Ha kiválasztod, akkor extra szerzői jogi információ jelenik meg az adminisztrációs oldalon. A Tassos.gr bővítmények soha nem jelenítenek meg szerzői jogi információt vagy hivatkozásokat a felhasználói oldalon." NR_WIDTH="Szélesség" NR_WIDTH_DESC="Szélesség megadása, px-ben, em-ben, vagy %-ban

Például: 400px" NR_HEIGHT="Magasság" NR_HEIGHT_DESC="Mgasság megadása, px-ben, em-ben, vagy %-ban

Például: 400px" NR_PADDING="Kitöltés (padding)" NR_PADDING_DESC="Kitöltés (padding) megadása, px-ben, em-ben, vagy %-ban

Például: 20px" ; NR_MARGIN="Margin" ; NR_MARGIN_DESC="The CSS margin propertiy is used to generate space around the box and set the size of the white space outside the border in pixels or in %.

Example 1: 25px
Example 2: 5%

Specifying the margin for each side [top right bottom left]:

Top side only: 25px 0 0 0
Right side only: 0 25px 0 0
Bottom side only: 0 0 25px 0
Left side only: 0 0 0 25px" ; NR_COLOR_HOVER="Hover Color" NR_COLOR="Szín" ; NR_COLOR_DESC="Define a color in HEX or RGBA format." NR_TEXT_COLOR="Szövegszín" ; NR_BACKGROUND="Background" NR_BACKGROUND_COLOR="Háttérszín" ; NR_BACKGROUND_COLOR_DESC="Define a background color in HEX or RGBA format. To disable enter 'none'. For absolute transparency enter 'transparent'." NR_URL_SHORTENING_FAILED="%s (%s) rövidítése nem sikerült. %s." NR_EXPORT="Export" NR_IMPORT="Import" NR_PLEASE_CHOOSE_A_VALID_FILE="Kérjük, hogy válassz egy érvényes fájnevet" NR_IMPORT_ITEMS="Elemek importálása" NR_PUBLISH_ITEMS="Elemek közzététele" NR_AS_EXPORTED="Mint exportált" ; NR_TITLE="Title" NR_ACYMAILING="AcyMailing" ; NR_ACYMAILING_LIST="AcyMailing List" ; NR_ACYMAILING_LIST_DESC="Select AcyMailing lists to assign to." ; NR_ASSIGN_ACYMAILING_DESC="Target visitors who have subscribed to specific AcyMailing lists" NR_AKEEBASUBS="Akeeba feliratkozások" NR_AKEEBASUBS_LEVELS="Szintek" ; NR_AKEEBASUBS_LEVELS_DESC="Select Akeeba Subscription levels to assign to." ; NR_ASSIGN_AKEEBASUBS_DESC="Target visitors who have subscribed to specific Akeeba Subscriptions" ; NR_MATCH="Match" ; NR_MATCH_DESC="The used matching method to compare the value" NR_ASSIGN_MATCHING_METHOD="Találati módszer" ; NR_ASSIGN_MATCHING_METHOD_DESC="Should all or any assignments be matched?

All
Will be published if All of below assignments are matched.

Any
Will be published if Any (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." NR_ANY="Bármely" ; NR_ALL="All" ; NR_ASSIGN_REFERRER="Referrer URL" ; NR_ASSIGN_REFERRER_DESC2="Target visitors who land on your site from a specific traffic source" ; NR_ASSIGN_REFERRER_DESC="Enter one Referrer URL per line: Eg:

google.com
facebook.com/mypage" ; NR_ASSIGN_REFERRER_NOTE="Keep in mind that URL Referrer discovery is not always 100% accurate. Some servers may use proxies that strip this information out and it can be easily forged." ; NR_PROFEATURE_HEADER="%s is a PRO Feature" ; NR_PROFEATURE_DESC="We're sorry, %s is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features." ; NR_PROFEATURE_DISCOUNT="Bonus: %s free users get 20% off regular price, automatically applied at checkout." NR_ONLY_AVAILABLE_IN_PRO="Csak a BŐVÍTETT verzióban érhető el." NR_UPGRADE_TO_PRO="Frissítés a Bővített verzióra" ; NR_UPGRADE_TO_PRO_TO_UNLOCK="Upgrade to Pro version to unlock" ; NR_UPGRADE_TO_PRO_VERSION="Awesome! Only one step left. Click on the button below to complete the upgrade to the Pro version." ; NR_UNLOCK_PRO_FEATURE="Unlock Pro Feature" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="Balról jobbra" NR_RIGHT_TO_LEFT="Jobbról balra" NR_BGIMAGE="Háttérkép" NR_BGIMAGE_DESC="Háttérkép beállítása" NR_BGIMAGE_FILE="Kép" NR_BGIMAGE_FILE_DESC="Fájl kiválasztása vagy feltöltése háttérképnek." NR_BGIMAGE_REPEAT="Ismétlés" ; NR_BGIMAGE_REPEAT_DESC="The background-repeat property sets if/how a background image will be repeated. By default, a background-image is repeated both vertically and horizontally.

Repeat: The background image will be repeated both vertically and horizontally.

Repeat-x: The background image will be repeated only horizontally

Repeat-y: The background image will be repeated only vertically

No-repeat: The background-image will not be repeated" NR_BGIMAGE_SIZE="Méret" ; NR_BGIMAGE_SIZE_DESC="Specify the size of a background image.

Auto:The background-image contains its width and height

Cover: Scale the background image to be as large as possible so that the background area is completely covered by the background image. Some parts of the background image may not be in view within the background positioning area

Contain: Scale the image to the largest size such that both its width and its height can fit inside the content area

100% 100%: Stretch the background image to completely cover the content area." NR_BGIMAGE_POSITION="Pozíció" NR_BGIMAGE_POSITION_DESC="A háttérkép-pozíció tulajdonság határozza meg háttérkép a kiindulási pozícióját. Alapértelmezetten a háttérkép a bal felső sarokban van elhelyezbe. Az első érték a vizszintes pozíció, még a második érték a függőleges pozíció.

Használhatod az egyik előre meghatározott értéket, vagy adhatsz meg egyedi értéket is százalékban (x% y%) vagy pixelben (xPos yPos)." NR_RTL="RTL engedélyezése" NR_RTL_DESC="A jobbról balra haladó szövegirány elengedhetelen olyan nyelvek esetében, mint péládul az arab, a héber, a szír és a thaanai." NR_HORIZONTAL="Vizszintes" NR_VERTICAL="Függőleges" NR_FORM_ORIENTATION="Űrlap iránya" NR_FORM_ORIENTATION_DESC="Űrlap irányának kiválasztása" NR_ASSIGN_CATEGORY="Kategóriák" NR_ASSIGN_CATEGORY_DESC="Kategória kiválasztása a hozzárendeléshez" NR_ASSIGN_CATEGORY_CHILD="Szintén gyermek elemek" NR_ASSIGN_CATEGORY_CHILD_DESC="Hozzá kell rendelni a gyermek elemeket a kiválasztott elemekhez?" NR_NEW="Új" NR_LIST="Lista" NR_DOCUMENTATION="Dokumentáció" ; NR_KNOWLEDGEBASE="Knowledgebase" NR_FAQ="GYIK" NR_INFORMATION="Információ" NR_EXTENSION="Bővítmény" NR_VERSION="Verzió" NR_CHANGELOG="Változási napló" ; NR_DOWNLOAD="Download" ; NR_DOWNLOAD_KEY_MISSING="Download Key is missing" NR_DOWNLOAD_KEY="Letöltési kulcs" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="Ahhoz, hogy frissíteni tudd a(z) %s bővítményt a Joomla bővítményfrissítőn keresztül, meg kelle adnod a letöltési kulcsod a Novorain Framework beépülőmodul beállításaiban." NR_DOWNLOAD_KEY_FIND="Letöltési kulcs keresése" NR_DOWNLOAD_KEY_UPDATE="Letöltési kulcs frissítése" NR_OK="OKÉ" NR_MISSING="Hiányzó" NR_LICENSE="Licenc" NR_AUTHOR="Szerző" NR_FOLLOWME="Kövess engem" NR_FOLLOW="Kövess %s" NR_TRANSLATE_INTEREST="Lenne kedved segíteni a(z) %s fordításában a saját nyelvedre?" NR_TRANSIFEX_REQUEST="Küldj nekem egy kérést a Transifexen" NR_HELP_WITH_TRANSLATIONS="Fordítás segítése" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Haladó" NR_USEGLOBAL="Globális használata" ; NR_WEEKDAY="Day of Week" ; NR_MONTH="Month" ; NR_MONDAY="Monday" ; NR_TUESDAY="Tuesday" ; NR_WEDNESDAY="Wednesday" ; NR_THURSDAY="Thursday" ; NR_FRIDAY="Friday" ; NR_SATURDAY="Saturday" ; NR_WEEKEND="Weekend" ; NR_WEEKDAYS="Weekdays" ; NR_SUNDAY="Sunday" ; NR_JANUARY="January" ; NR_FEBRUARY="February" ; NR_MARCH="March" ; NR_APRIL="April" ; NR_MAY="May" ; NR_JUNE="June" ; NR_JULY="July" ; NR_AUGUST="August" ; NR_SEPTEMBER="September" ; NR_OCTOBER="October" ; NR_NOVEMBER="November" ; NR_DECEMBER="December" NR_NEVER="Soha" NR_SECONDS="Másodperc" NR_MINUTES="Percek" NR_HOURS="Órák" NR_DAYS="Napok" NR_SESSION="Munkamenet" NR_EVER="Mindig" NR_COOKIE="Süti" NR_BOTH="Mindkettő" NR_NONE="Egyik sem" ; NR_NONE_SELECTED="None Selected" ; NR_DESKTOPS="Desktop" ; NR_MOBILES="Mobile" ; NR_TABLETS="Tablet" ; NR_PER_SESSION="Per Session" ; NR_PER_DAY="Per Day" ; NR_PER_WEEK="Per Week" ; NR_PER_MONTH="Per Month" ; NR_FOREVER="Forever" ; NR_FEATURE_UNDER_DEV="This feature is under development" ; NR_LIKE_THIS_EXTENSION="Like this extension?" ; NR_LEAVE_A_REVIEW="Leave a review on JED" ; NR_SUPPORT="Support" ; NR_NEED_SUPPORT="Need support?" ; NR_DROP_EMAIL="Drop me an e-mail" ; NR_READ_DOCUMENTATION="Read the Documentation" ; NR_COPYRIGHT="%s - Tassos.gr All Rights Reserved" ; NR_DASHBOARD="Dashboard" ; NR_NAME="Name" ; NR_WRONG_COORDINATES="The coordinates you provided are not valid" ; NR_ENTER_COORDINATES="Latitude,Longitude" ; NR_NO_ITEMS_FOUND="No Items Found" ; NR_ITEM_IDS="No Item IDs" ; NR_TOGGLE="Toggle" ; NR_EXPAND="Expand" ; NR_COLLAPSE="Collapse" ; NR_SELECTED="Selected" ; NR_MAXIMIZE="Maximize" ; NR_MINIMIZE="Minimize" NR_SELECTION="Kiválasztás" ; NR_INSTALL="Install" ; NR_INSTALL_NOW="Install Now" ; NR_INSTALLED="Installed" ; NR_COMING_SOON="Coming soon" ; NR_ROADMAP="On the roadmap" ; NR_MEDIA_VERSIONING="Use Media Versioning" ; NR_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." ; NR_LOAD_JQUERY="Load jQuery" ; NR_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." ; NR_SELECT_CURRENCY="Select a Currency" ; NR_CONVERTFORMS="Convert Forms" ; NR_CONVERTFORMS_LIST="Campaign" ; NR_ASSIGN_CONVERTFORMS_DESC="Target visitors who have subscribed to specific ConvertForms campaigns" ; NR_CONVERTFORMS_LIST_DESC="Select ConvertForms campaigns to assign to." ; NR_LEFT="Left" ; NR_CENTER="Center" ; NR_RIGHT="Right" ; NR_BOTTOM="Bottom" ; NR_TOP="Top" ; NR_AUTO="Auto" ; NR_CUSTOM="Custom" ; NR_UPLOAD="Upload" ; NR_IMAGE="Image" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" ; NR_IMAGE_SELECT="Select Image" ; NR_IMAGE_SIZE_COVER="Cover" ; NR_IMAGE_SIZE_CONTAIN="Contain" ; NR_REPEAT="Repeat" ; NR_REPEAT_X="Repeat x" ; NR_REPEAT_Y="Repeat y" ; NR_REPEAT_NO="No repeat" ; NR_FIELD_STATE_DESC="Set item's state" ; NR_CREATED_DATE="Created Date" ; NR_CREATED_DATE_DESC="The date the item was created" ; NR_MODIFIFED_DATE="Modified Date" ; NR_MODIFIFED_DATE_DESC="The date that the item was last modified." ; NR_CATEGORIES="Category" ; NR_CATEGORIES_DESC="Select the categories to assign to." ; NR_ALSO_ON_CHILD_ITEMS="Also on child items" ; NR_ALSO_ON_CHILD_ITEMS_DESC="Also assign to child items of the selected items?" ; NR_PAGE_TYPE="Page type" ; NR_PAGE_TYPES="Page types" ; NR_PAGE_TYPES_DESC="Select on what page types the assignment should be active." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" ; NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" ; NR_CATEGORY_VIEW="Category View" ; NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." ; NR_ARTICLES="Articles" ; NR_ARTICLES_DESC="Select the articles to assign to." ; NR_ARTICLE="Article" ; NR_ARTICLE_AUTHORS="Authors" ; NR_ARTICLE_AUTHORS_DESC="Select the authors to assign to." ; NR_ONLY="Only" ; NR_OTHERS="Others" ; NR_SMARTTAGS="Smart Tags" ; NR_SMARTTAGS_SHOW="Show Smart Tags" ; NR_SMARTTAGS_NOTFOUND="No Smart Tags found" ; NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" ; NR_CONTACT_US="Contact us" ; NR_FONT_COLOR="Font Color" ; NR_FONT_SIZE="Font Size" ; NR_FONT_SIZE_DESC="Choose a font size in pixels" ; NR_TEXT="Text" ; NR_URL="URL" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE="Enable on Output Override" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Enables the extension rendering when the page layout (tmpl) is overriden. Examples: tmpl=component or tmpl=modal." ; NR_EXECUTE_ON_FORMAT_OVERRIDE="Enable on Format Override" ; NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Enables the extension rendering when the page format is not other than HTML. Examples: format=raw or format=json." ; NR_GEOLOCATING="Geolocating" ; NR_GEOLOCATION="Geolocation" ; NR_GEOLOCATING_DESC="Geolocating is not always 100% accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known." ; NR_CITY="City" ; NR_CITY_NAME="City Name" ; NR_CONDITION_CITY_DESC="Enter a city name in English. Enter multiple cities separated by comma." ; NR_CONTINENT="Continent" ; NR_REGION="Region" ; NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." ; NR_ASSIGN_COUNTRIES="Country" ; NR_ASSIGN_COUNTRIES_DESC2="Target visitors who are physically in a specific country" ; NR_ASSIGN_COUNTRIES_DESC="Select the countries to assign to" ; NR_ASSIGN_CONTINENTS="Continent" ; NR_ASSIGN_CONTINENTS_DESC="Select the continents to assign to" ; NR_ASSIGN_CONTINENTS_DESC2="Target visitors who are physically in a specific continent" ; NR_ICONTACT_ACCOUNTID_ERROR="The iContact AccountID could not be retrieved" ; NR_TAG_CLIENTDEVICE="Visitor Device Type" ; NR_TAG_CLIENTOS="Visitor Operating System" ; NR_TAG_CLIENTBROWSER="Visitor Browser" ; NR_TAG_CLIENTUSERAGENT="Visitor Agent String" ; NR_TAG_IP="Visitor IP Address" ; NR_TAG_URL="Page URL" ; NR_TAG_URLENCODED="Page URL Encoded" ; NR_TAG_URLPATH="Page Path" ; NR_TAG_REFERRER="Page Referrer" ; NR_TAG_SITENAME="Site Name" ; NR_TAG_SITEURL="Site URL" ; NR_TAG_PAGETITLE="Page Title" ; NR_TAG_PAGEDESC="Page Meta Description" ; NR_TAG_PAGELANG="Page Language Code" ; NR_TAG_USERID="User ID" ; NR_TAG_USERNAME="User Full Name" ; NR_TAG_USERLOGIN="User Login" ; NR_TAG_USEREMAIL="User Email" ; NR_TAG_USERFIRSTNAME="User First Name" ; NR_TAG_USERLASTNAME="User Last Name" ; NR_TAG_USERGROUPS="User Groups IDs" ; NR_TAG_DATE="Date" ; NR_TAG_TIME="Time" ; NR_TAG_RANDOMID="Random ID" ; NR_ICON="Icon" ; NR_SELECT_MODULE="Select a Module" ; NR_SELECT_CONTINENT="Select a Continent" ; NR_SELECT_COUNTRY="Select a Country" ; NR_PLUGIN="Plugin" ; NR_GMAP_KEY="Google Maps API Key" ; NR_GMAP_KEY_DESC="The Google Maps API Key is being used by Tassos.gr extensions. If you face any troubles with a Google Map not being loaded then you probably need to enter your own API Key." ; NR_GMAP_FIND_KEY="Get an API key" ; NR_ARE_YOU_SURE="Are you sure?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" ; NR_CUSTOMURL="Custom URL" ; NR_SAMPLE="Sample" ; NR_DEBUG="Debug" ; NR_CUSTOMURL="Custom URL" ; NR_READMORE="Read More" ; NR_IPADDRESS="IP Address" ; NR_ASSIGN_BROWSERS="Browser" ; NR_ASSIGN_BROWSERS_DESC="Select the browsers to assign to" ; NR_ASSIGN_BROWSERS_DESC2="Target visitors who are browsing your site with specific browsers such as Chrome, Firefox or Internet Explorer" ; NR_CHROME="Chrome" ; NR_FIREFOX="Firefox" ; NR_EDGE="Edge" ; NR_IE="Internet Explorer" ; NR_SAFARI="Safari" ; NR_OPERA="Opera" ; NR_ASSIGN_OS="Operating System" ; NR_ASSIGN_OS_DESC="Select the operating systems to assign to" ; NR_ASSIGN_OS_DESC2="Target visitors who are using specific operating systems such as Windows, Linux or Mac" ; NR_LINUX="Linux" ; NR_MAC="MacOS" ; NR_ANDROID="Android" ; NR_IOS="iOS" ; NR_WINDOWS="Windows" ; NR_BLACKBERRY="Blackberry" ; NR_CHROMEOS="Chrome OS" ; NR_ASSIGN_PAGEVIEWS="Number of Pageviews" ; NR_ASSIGN_PAGEVIEWS_DESC="Target visitors who have viewed certain number of pages" ; NR_ASSIGN_PAGEVIEWS_VIEWS="Pageviews" ; NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Enter the number of page views" ; NR_ASSIGN_COOKIENAME_NAME="Cookie Name" ; NR_ASSIGN_COOKIENAME_NAME_DESC="Enter the name of the cookie to assign to" ; NR_ASSIGN_COOKIENAME_NAME_DESC2="Target visitors who have specific cookies stored in their browser" ; NR_FEWER_THAN="Fewer than" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" ; NR_GREATER_THAN="Greater than" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" ; NR_EXACTLY="Exactly" ; NR_EXISTS="Exists" ; NR_NOT_EXISTS="Does not exists" ; NR_IS_EQUAL="Equals" ; NR_DOES_NOT_EQUAL="Does not equal" ; NR_CONTAINS="Contains" ; NR_DOES_NOT_CONTAIN="Does not contain" ; NR_STARTS_WITH="Starts with" ; NR_DOES_NOT_START_WITH="Does not start with" ; NR_ENDS_WITH="Ends with" ; NR_DOES_NOT_END_WITH="Does not end with" ; NR_ASSIGN_COOKIENAME_CONTENT="Cookie Content" ; NR_ASSIGN_COOKIENAME_CONTENT_DESC="The cookie's content" ; NR_ASSIGN_IP_ADDRESSES_DESC2="Target visitors who are behind a specific IP address (range)" ; NR_ASSIGN_IP_ADDRESSES_DESC="Enter a list of comma and/or 'enter' separated ip addresses and ranges

Example:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." ; NR_ASSIGN_USER_ID="User ID" ; NR_ASSIGN_USER_ID_DESC="Target specific Joomla Users by their IDs" ; NR_ASSIGN_USER_ID_SELECTION_DESC="Enter comma separated Joomla user IDs" ; NR_ASSIGN_COMPONENTS="Component" ; NR_ASSIGN_COMPONENTS_DESC="Select the components to assign to" ; NR_ASSIGN_COMPONENTS_DESC2="Target visitors who are browsing specific components" ; NR_ASSIGN_TIMERANGE="Time Range" ; NR_ASSIGN_TIMERANGE_DESC="Target visitors based on your server's time" ; NR_START_TIME="Start Time" ; NR_END_TIME="End Time" ; NR_START_PUBLISHING_TIMERANGE_DESC="Enter the time to start publishing" ; NR_FINISH_PUBLISHING_TIMERANGE_DESC="Enter the time to end publishing" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." ; NR_RECAPTCHA_SITE_KEY="Site Key" ; NR_RECAPTCHA_SITE_KEY_DESC="Used in the JavaScript code that is served to your users." ; NR_RECAPTCHA_SECRET_KEY="Secret Key" ; NR_RECAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret." ; NR_RECAPTCHA_SITE_KEY_ERROR="The reCaptcha Site Key is either missing or invalid" ; NR_PREVIOUS_MONTH="Previous Month" ; NR_NEXT_MONTH="Next Month" ; NR_ASSIGN_GROUP_PAGE_URL="Page / URL" ; NR_ASSIGN_GROUP_PAGE_URL_DESC="Target visitors who are browsing specific menu items or URLs" ; NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" ; NR_ASSIGN_GROUP_USER_VISITOR="Joomla User / Visitor" ; NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" ; NR_ASSIGN_GROUP_PLATFORM="Visitor Platform" ; NR_ASSIGN_GROUP_PLATFORM_DESC="Target visitors who are using Mobile, Google Chrome, or even Windows" ; NR_ASSIGN_GROUP_GEO_DESC="Target visitors who are physically in a specific region" ; NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" ; NR_ASSIGN_GROUP_JCONTENT_DESC="Target visitors who are viewing specific Joomla articles or categories" ; NR_ASSIGN_GROUP_SYSTEM="System / Integrations" ; NR_INTEGRATIONS="Integrations" ; NR_ASSIGN_GROUP_SYSTEM_DESC="Target visitors who have interacted with specific 3rd party Joomla Extensions" ; NR_ASSIGN_GROUP_ADVANCED="Advanced visitor targeting" ; NR_ASSIGN_USERGROUP_DESC="Target specific Joomla user groups" ; NR_ASSIGN_ARTICLE_DESC="Target visitors who are viewing specific Joomla articles" ; NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target visitors who are viewing specific Joomla categories" ; NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." ; NR_ASSIGN_K2="K2" ; NR_ASSIGN_K2_DESC="Target visitors who are browsing specific K2 Items, Categories or Tags" ; NR_ASSIGN_K2_ITEMS="Item" ; NR_ASSIGN_K2_ITEMS_DESC="Target visitors who are browsing specific K2 items." ; NR_ASSIGN_K2_ITEMS_LIST_DESC="Select the K2 Items to assign to" ; NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Match on specific keywords in the item's content. Seperate by a comma or a new line." ; NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Match on the item's meta keywords. Seperate by a comma or a new line." ; NR_ASSIGN_K2_PAGETYPES_DESC="Target visitors who are browsing specific K2 page types" ; NR_ASSIGN_K2_ITEM_OPTION="Item" ; NR_ASSIGN_K2_LATEST_OPTION="Latest items from users or categories" ; NR_ASSIGN_K2_TAG_OPTION="Tag Page" ; NR_ASSIGN_K2_CATEGORY_OPTION="Category Page" ; NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Edit Form" ; NR_ASSIGN_K2_USER_PAGE_OPTION="User Page (blog)" ; NR_ASSIGN_K2_TAGS_DESC="Target visitors who are browsing K2 items with specific tags" ; NR_ASSIGN_K2_CATEGORIES_DESC="Target visitors who are browsing specific K2 categories" ; NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" ; NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" ; NR_ASSIGN_PAGE_TYPES_DESC="Select the page types to assign to" ; NR_ASSIGN_TAGS_DESC="Select the tags to assign to" ; NR_CONTENT_KEYWORDS="Content keywords" ; NR_META_KEYWORDS="Meta keywords" ; NR_TAG="Tag" ; NR_NORMAL="Normal" ; NR_COMPACT="Compact" ; NR_LIGHT="Light" ; NR_DARK="Dark" ; NR_SIZE="Size" ; NR_THEME="Theme" ; NR_SINGLE="Single" ; NR_MULTIPLE="Multiple" ; NR_RANGE="Range" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_PLEASE_VALIDATE="Please validate" ; NR_RECAPTCHA_INVALID_SECRET_KEY="Invalid secret key" ; NR_PAGE="Page" ; NR_YOU_ARE_USING_EXTENSION="You are using %s %s" ; NR_UPDATE="Update" ; NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" ; NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." ; NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!uNBsystem/nrframework/language/ru-RU/ru-RU.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Фреймворк 'Novarain Framework' используется расширениями, выпускаемыми веб-сайтом Tassos.gr" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Игнорировать" NR_INCLUDE="Включить" NR_EXCLUDE="Исключить" NR_SELECTION="Выбор" NR_ASSIGN_MENU_NOITEM="Не включать ID номер" NR_ASSIGN_MENU_NOITEM_DESC="Назначить также когда в URL ссылке отсутствует ID номер меню?" NR_ASSIGN_MENU_CHILD="Также и дочерние объекты" NR_ASSIGN_MENU_CHILD_DESC="Назначить также и вложенным пунктам меню выбранных пунктов меню?" NR_COPY_OF="Копия %s" NR_ASSIGN_DATETIME_DESC="Нацеливаться на посетителей на основе времени на Вашем сервере" NR_DATETIME="Дата" NR_TIME="Время" NR_DATE="Дата" NR_DATETIME_DESC="Введите дату автоматической публикации/автоматического снятия с публикации" NR_START_PUBLISHING="Время начала" NR_START_PUBLISHING_DESC="Введите дату начала публикации" NR_FINISH_PUBLISHING="Время окончания" NR_FINISH_PUBLISHING_DESC="Введите дату снятия с публикации" NR_DATETIME_NOTE="Дата и время используют данные вашего сервера, а не ваших пользователей." NR_ASSIGN_PHP="PHP" NR_PHPCODE="Код PHP" NR_ASSIGN_PHP_DESC="Введите фрагмент кода PHP для его проверки" NR_ASSIGN_PHP_DESC2="Нацеливаться на посетителей, оценивающих определенный произвольный код PHP. Данный код должен возвращать значение true или false.

Например:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Время на сайте" NR_SECONDS="Секунды" NR_ASSIGN_TIMEONSITE_DESC="Введите время в секундах, чтобы сравнить общее время пользователя (Длительность посещения) потраченного на весь сайт.

Пример:
Если вы хотите отобразить окно после того, как пользователь потратил 3 минуты на вашем сайте, введите 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Нацеливаться на посетителей, которые просматривают конкретные страницы, с конкретными ссылками URL." NR_ASSIGN_URLS_DESC="Введите URL (или его часть) для сравнения.
Используйте новую строку для каждого отдельного элемента." NR_ASSIGN_URLS_LIST="URL совпадения" NR_ASSIGN_URLS_REGEX="Использовать регулярные выражения" NR_ASSIGN_URLS_REGEX_DESC="Выберите значение, как регулярное выражение." NR_ASSIGN_LANGS="Язык" NR_ASSIGN_LANGS_DESC="Нацелиться на посетителей, которые просматривают Ваш сайт на конкретном языке" NR_ASSIGN_LANGS_LIST_DESC="Выберите языки" NR_ASSIGN_DEVICES="Устройство" NR_ASSIGN_DEVICES_DESC2="Нацеливаться на посетителей, которые используют определенное устройство. Например, мобильное устройство, планшет или рабочий стол." NR_ASSIGN_DEVICES_DESC="Выберите устройства" NR_ASSIGN_DEVICES_NOTE="Имейте в виду, что обнаружение устройств не всегда на 100% точное. Пользователи могут настроить их браузер, чтобы имитировать другие устройства." NR_MENU="Меню" NR_MENU_ITEMS="Пункт меню" NR_MENU_ITEMS_DESC="Нацелиться на посетителей, которые просматривают конкретное меню" NR_USERGROUP="Группа пользователей" NR_ACCESSLEVEL="Группа пользователей" NR_ACCESSLEVEL_DESC="Назначьте группы пользователей.

Примечание: Если хотите сделать публичным установите параметр Игнорировать и не устанавливайте Public." NR_SHOW_COPYRIGHT="Показать копирайт" NR_SHOW_COPYRIGHT_DESC="Если вкл, дополнительная информация авторских прав будет отображаться в представлениях администратора. Расширения Tassos.gr никогда не отображают копирайты или обратные ссылки на сайте." NR_WIDTH="Ширина" NR_WIDTH_DESC="Укажите ширину в px, em или %

Пример: 400px" NR_HEIGHT="Высота" NR_HEIGHT_DESC="Укажите высоту в px, em или %

Пример: 400px" NR_PADDING="Отступ" NR_PADDING_DESC="Укажите отступ в px, em или %

Пример: 20px" NR_MARGIN="Отступ" NR_MARGIN_DESC="Стилевое CSS свойство 'margin' используется для создания свободного пространства вокруг блока. Оно настраивает размер такого белого пространства за пределами блока в пикселя или %.

Пример 1:-ый 25px
Пример 2-ой: 5%

Примеры назначения свойства 'margin' для каждой стороны [сверху справа снизу слева]:

только сверху: 25px 0 0 0
только справа: 0 25px 0 0
только снизу: 0 0 25px 0
только слева: 0 0 0 25px" NR_COLOR_HOVER="Цвет для ховера (hover)" NR_COLOR="Цвет" NR_COLOR_DESC="Введите цвет в форматах HEX или RGBA" NR_TEXT_COLOR="Цвет текста" NR_BACKGROUND="Фон" NR_BACKGROUND_COLOR="Цвет фона" NR_BACKGROUND_COLOR_DESC="Укажите цвет фона в форматах HEX или RGBA. Чтобы отключить укажите "_QQ_"Нет"_QQ_". Для абсолютной прозрачности введите "_QQ_"прозрачно"_QQ_"." NR_URL_SHORTENING_FAILED="Не удалось укоротить %s с %s. %s." NR_EXPORT="Экспорт" NR_IMPORT="Импорт" NR_PLEASE_CHOOSE_A_VALID_FILE="Пожалуйста, выберите корректное имя файла" NR_IMPORT_ITEMS="Импорт элементов" NR_PUBLISH_ITEMS="Публикация элементов" NR_AS_EXPORTED="Как экспортировано" NR_TITLE="Заголовок" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="Список AcyMailing" NR_ACYMAILING_LIST_DESC="Выбрать список рассылки компонента AcyMailing для назначения" NR_ASSIGN_ACYMAILING_DESC="Нацеливаться на посетителей, которые подписались на определенный список рассылки компонента AcyMailing" NR_AKEEBASUBS="Подписки Akeeba" NR_AKEEBASUBS_LEVELS="Уровни" NR_AKEEBASUBS_LEVELS_DESC="Выбрать уровень компонента Akeeba Subscription для назначения" NR_ASSIGN_AKEEBASUBS_DESC="Нацеливаться на посетителей, которые подписались на конкретный план, созданные расширением Akeeba Subscriptions" NR_MATCH="Сходится" NR_MATCH_DESC="Метод для сравнения значений" NR_ASSIGN_MATCHING_METHOD="Метод совпадения" NR_ASSIGN_MATCHING_METHOD_DESC="Должны ли все назначения совпадать??

Все
Будет опубликовано если все назначения ниже совпадают.

Любой
Будет опубликовано еслилюбое (одно или более) из назначений ниже совпадают.
Назначенные группы 'Ignore' будут проигнорированы." NR_ANY="Любой" NR_ASSIGN_REFERRER="Реферальная ссылка" NR_ASSIGN_REFERRER_DESC2="Нацеливаться на посетителей, которые прибыли на Ваш веб сайт с определенном источника трафика" NR_ASSIGN_REFERRER_DESC="Вводите по одной реферальной ссылке на строчку. Например:

google.com
facebook.com/moja-stranica" NR_ASSIGN_REFERRER_NOTE="Имейте в виду, что определение реферальной ссылки не всегда точны на 100%. Некоторые серверы могут использовать прокси, которые удаляют такую реферельную. информацию и ее можно легко подделать злоумышленнику." NR_PROFEATURE_HEADER="%s это PRO функция" NR_PROFEATURE_DESC="Извините, %s это недоступно в вашей подписке. Пожалуйста подпишитесь на PRO чтобы иметь доступ к данным функциям." NR_PROFEATURE_DISCOUNT="Бонус: %s пользователей получают 20% скидку автоматически при оплате." NR_ONLY_AVAILABLE_IN_PRO="Доступно только в версии PRO" NR_UPGRADE_TO_PRO="Обновить до PRO" NR_UPGRADE_TO_PRO_TO_UNLOCK="Обновиться до версии Pro" NR_UPGRADE_TO_PRO_VERSION="Awesome! Only one step left. Click on the button below to complete the upgrade to the Pro version." NR_UNLOCK_PRO_FEATURE="Разблокировать ПРО функции" NR_USING_THE_FREE_VERSION="Вы используете бесплатную версию Convert Forms. Купите PRO версию для полной функциональности." NR_LEFT_TO_RIGHT="Слева направо" NR_RIGHT_TO_LEFT="Справа налево" NR_BGIMAGE="Изображение фона" NR_BGIMAGE_DESC="Установить изображение фона" NR_BGIMAGE_FILE="Изображение" NR_BGIMAGE_FILE_DESC="Выберите или загрузите файл, в качестве фона." NR_BGIMAGE_REPEAT="Повтор" NR_BGIMAGE_REPEAT_DESC="Повтор фона устанавливает, режим, в котором фотове изображение будет повторяться. По умолчанию, фоновое изображение повторяется как по вертикали, так и по горизонтали.

Повтор: Фоновое изображение повторяется как по вертикали, так и по горизонтали.

Повтор-x: Фоновое изображение повторяется по горизонтали

Повтор-y: Фоновое изображение повторяется по вертикали

Нет-повтора: Повтор изображения отключен." NR_BGIMAGE_SIZE="Размер" NR_BGIMAGE_SIZE_DESC="Укажите размер фонового изображения.

Авто: Фоновое изображение содержит собственные ширину и высоту

Обложка: Масштабирует фоновое изображение на максимальный размер, чтобы покрыть фоновое пространство

Контейнер: Масштабирует изображение таким образом, что его ширина и высота его может поместиться внутри области содержимого

100% 100%: Растягивает фоновое изображение, чтобы полностью покрыть область контента." NR_BGIMAGE_POSITION="Позиция" NR_BGIMAGE_POSITION_DESC="Свойство background-position задает начальное положение изображения. По умолачнию размещается сверху-слева. Первое значение для горизонтального позиционирования, второе для вертикального

Вы можете использовать одно из предопределенных значений, или введите значение в процентах: x% y% или в пикселях xPos yPos." NR_RTL="Включить RTL" NR_RTL_DESC="Направление текста справа налево имеет важное значение для таких языков как арабский, иврит, сирийский и тд." NR_HORIZONTAL="Горизонтально" NR_VERTICAL="Вертикально" NR_FORM_ORIENTATION="Ориентация формы" NR_FORM_ORIENTATION_DESC="Выберите ориентацию формы" NR_ASSIGN_CATEGORY="Категории" NR_ASSIGN_CATEGORY_DESC="Выберите категории" NR_ASSIGN_CATEGORY_CHILD="Также для дочерних элементов" NR_ASSIGN_CATEGORY_CHILD_DESC="Также назначить выделенные элементы к дочерним?" NR_NEW="Новый" NR_LIST="Список" NR_DOCUMENTATION="Документация" NR_KNOWLEDGEBASE="База знаний" NR_FAQ="FAQ" NR_INFORMATION="Информация" NR_EXTENSION="Расширение" NR_VERSION="Версия" NR_CHANGELOG="Что нового" ; NR_DOWNLOAD="Download" NR_DOWNLOAD_KEY_MISSING="Ключ загрузки отсутствует" NR_DOWNLOAD_KEY="Ключ" NR_DOWNLOAD_KEY_DESC="Чтобы найти ключ загрузки, войдите в свою учетную запись на Tassos.gr и перейдите в раздел «Загрузки».

Примечание. Установка здесь ключа загрузки не приводит к обновлению бесплатных версий до версий Pro. Чтобы разблокировать функции Pro, вам также необходимо установить версию Pro поверх бесплатной." NR_DOWNLOAD_KEY_HOW="Для того, чтобы компонент обновлялся вместе с Joomla updater, нужно ввести Ключ в настройках Novarain Framework Plugin." NR_DOWNLOAD_KEY_FIND="Найти ключ" NR_DOWNLOAD_KEY_UPDATE="Обновить ключ" NR_OK="Ок" NR_MISSING="Не найдено" NR_LICENSE="Лицензия" NR_AUTHOR="Автор" NR_FOLLOWME="Подписаться" NR_FOLLOW="Подписаться на %s" NR_TRANSLATE_INTEREST="Заинтересованы в помощи с переводом %s на свой язык?" NR_TRANSIFEX_REQUEST="Пришлите мне запрос на Transifex" NR_HELP_WITH_TRANSLATIONS="Помощь с переводами" NR_PUBLISHING_ASSIGNMENTS="Привязка публикации" NR_ADVANCED="Расширенные" NR_USEGLOBAL="По умолчанию" NR_WEEKDAY="День недели" NR_MONTH="Месяц" NR_MONDAY="Понедельник" NR_TUESDAY="Вторник" NR_WEDNESDAY="Среда" NR_THURSDAY="Четверг" NR_FRIDAY="Пятница" NR_SATURDAY="Суббота" NR_WEEKEND="Выходные" NR_WEEKDAYS="Будни" NR_SUNDAY="Воскресенье" NR_JANUARY="Январь" NR_FEBRUARY="Февраль" NR_MARCH="Март" NR_APRIL="Апрель" NR_MAY="Май" NR_JUNE="Июнь" NR_JULY="Июль" NR_AUGUST="Август" NR_SEPTEMBER="Сентябрь" NR_OCTOBER="Октябрь" NR_NOVEMBER="ноябрь" NR_DECEMBER="Декабрь" NR_NEVER="Никогда" NR_SECONDS="Секунды" NR_MINUTES="Минут" NR_HOURS="Часов" NR_DAYS="Дней" NR_SESSION="Сессия" NR_EVER="Когда-либо" NR_COOKIE="Куки" NR_BOTH="Оба" NR_NONE="Нет" NR_DESKTOPS="Рабочий стол" NR_MOBILES="Мобильное устройство" NR_TABLETS="Планшет" NR_PER_SESSION="Раз в сессию" NR_PER_DAY="Каждый день" NR_PER_WEEK="Раз в неделю" NR_PER_MONTH="Раз в месяц" NR_FOREVER="Всегда" NR_FEATURE_UNDER_DEV="Эта опция в стадии разработки" NR_LIKE_THIS_EXTENSION="Нравится это расширение?" NR_LEAVE_A_REVIEW="Оставить отзыв на JED" NR_SUPPORT="Поддержка" NR_NEED_SUPPORT="Нужна поддержка?" NR_DROP_EMAIL="Напишите мне по электронной почте" NR_READ_DOCUMENTATION="Читать документацию" NR_COPYRIGHT="%s - Tassos.gr - Все права защищены" NR_DASHBOARD="Панель" NR_NAME="Имя" NR_WRONG_COORDINATES="Предоставленные координаты некорректные" NR_ENTER_COORDINATES="Широта, Долгота" NR_NO_ITEMS_FOUND="Элементы не найдены" NR_ITEM_IDS="Нет ID элементов" NR_TOGGLE="Переключиться" NR_EXPAND="Развернуть" NR_COLLAPSE="Свернуть" NR_SELECTED="Выбранные" NR_MAXIMIZE="Максимизировать" NR_MINIMIZE="Мнимизировать" NR_SELECTION="Выбор" NR_INSTALL="Установка" NR_INSTALL_NOW="Установить сейчас" NR_INSTALLED="Установлено" NR_COMING_SOON="Скоро..." NR_ROADMAP="Запланировано" NR_MEDIA_VERSIONING="Использовать версии медиа" NR_MEDIA_VERSIONING_DESC="Выберите, чтобы добавить дополнительный номер версии до конца носителя (JS / CSS) URL-адресов, чтобы заставить браузеры загружать правильный файл." NR_LOAD_JQUERY="Загрузка jQuery" NR_LOAD_JQUERY_DESC="Выберите загрузку ядра JQuery скрипт. Вы можете отключить эту функцию, если у вас есть конфликты, или если ваш шаблон или другие расширения загружают собственную версию JQuery." NR_SELECT_CURRENCY="Выберите валюту" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Кампания" NR_ASSIGN_CONVERTFORMS_DESC="Нацеливаться на посетителей, которые подписались на конкретную рекламную кампанию компонента ConvertForms" NR_CONVERTFORMS_LIST_DESC="Выберите компанию компонента ConvertForm для назначения:" NR_LEFT="Лево" NR_CENTER="Центр" NR_RIGHT="Право" NR_BOTTOM="Низ" NR_TOP="Верх" NR_AUTO="Авто" NR_CUSTOM="Пользовательский" NR_UPLOAD="Загрузка" NR_IMAGE="Изображение" NR_INTRO_IMAGE="Предварительное изображение" NR_FULL_IMAGE="Полное изображение" NR_IMAGE_SELECT="Выбрать изображение" NR_IMAGE_SIZE_COVER="Обложка" NR_IMAGE_SIZE_CONTAIN="Содержит" NR_REPEAT="Повторять" NR_REPEAT_X="Повторять по X" NR_REPEAT_Y="Повторять по Y" NR_REPEAT_NO="Не повторять" NR_FIELD_STATE_DESC="Установить состояние элемента" NR_CREATED_DATE="Дата создания" NR_CREATED_DATE_DESC="Дата создания элемента" NR_MODIFIFED_DATE="Дата изменения" NR_MODIFIFED_DATE_DESC="Дата изменения элемента" NR_CATEGORIES="Категория" NR_CATEGORIES_DESC="Выберите категорию для назначения." NR_ALSO_ON_CHILD_ITEMS="Также и для вложенных объектов" NR_ALSO_ON_CHILD_ITEMS_DESC="Назначить ли выбранные объекты также и вложенным объектам?" NR_PAGE_TYPE="Тип страницы" NR_PAGE_TYPES="Типы страниц" NR_PAGE_TYPES_DESC="Выбрать на страницах какого типа данное назначение будет активным." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" NR_CATEGORY_VIEW="Category View" NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" NR_ARTICLES="Материалы" NR_ARTICLES_DESC="Выберите материал для назначения." NR_ARTICLE="Материал" NR_ARTICLE_AUTHORS="Авторы" NR_ARTICLE_AUTHORS_DESC="Выберите автора для назначения." NR_ONLY="Только" NR_OTHERS="Другие" NR_SMARTTAGS="Умные теги" NR_SMARTTAGS_SHOW="Показать сообразительные метки" NR_SMARTTAGS_NOTFOUND="No Smart Tags found" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" NR_CONTACT_US="Свяжитесь с нами" NR_FONT_COLOR="Цвет шрифта" NR_FONT_SIZE="Размер шрифта" NR_FONT_SIZE_DESC="Выберите размер шрифта в пикселях" NR_TEXT="Текст" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Включить для переопределения выданных данных" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Включает выдачу данных расширения если макет страницы (tmpl) был переопределен. Пример: tmpl=component или tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Включить для переопределения формата" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Включает выдачу данных расширения если формат страницы был выполнен только в HTML. Пример: format=raw or format=json." NR_GEOLOCATING="Геопринадлежность" NR_GEOLOCATING_DESC="Геопринадлежность не всегда точна на 100%. Она основана на IP адресе посетителя. Не все IP адреса постоянны или известны." NR_CITY="City" NR_CITY_NAME="City Name" NR_CONDITION_CITY_DESC="Enter a city name in English. Enter multiple cities separated by comma." NR_CONTINENT="Continent" NR_REGION="Region" NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." NR_ASSIGN_COUNTRIES="Страна" NR_ASSIGN_COUNTRIES_DESC2="Нацеливаться на посетителей, которые физически находятся в определенной стране" NR_ASSIGN_COUNTRIES_DESC="Выберите страну для назначения" NR_ASSIGN_CONTINENTS="Континент" NR_ASSIGN_CONTINENTS_DESC="Выберите континенты для назначения" NR_ASSIGN_CONTINENTS_DESC2="Нацелиться на посетителей, которые физически находятся на определенном континенте" NR_ICONTACT_ACCOUNTID_ERROR="Не удалось извлечь ID номер iContact AccountID" NR_TAG_CLIENTDEVICE="Visitor Device Type" NR_TAG_CLIENTOS="Visitor Operating System" NR_TAG_CLIENTBROWSER="Visitor Browser" NR_TAG_CLIENTUSERAGENT="Visitor Agent String" NR_TAG_IP="Visitor IP Address" NR_TAG_URL="Page URL" NR_TAG_URLENCODED="Page URL Encoded" NR_TAG_URLPATH="Page Path" NR_TAG_REFERRER="Page Referrer" NR_TAG_SITENAME="Site Name" NR_TAG_SITEURL="Site URL" NR_TAG_PAGETITLE="Page Title" NR_TAG_PAGEDESC="Page Meta Description" NR_TAG_PAGELANG="Page Language Code" NR_TAG_USERID="ID номер пользователя" NR_TAG_USERNAME="Полное имя пользователя" NR_TAG_USERLOGIN="Логин пользователя" NR_TAG_USEREMAIL="Адрес эл.почты пользователя" NR_TAG_USERFIRSTNAME="Имя пользователя" NR_TAG_USERLASTNAME="Фамилия пользователя" NR_TAG_USERGROUPS="User Groups IDs" NR_TAG_DATE="Date" NR_TAG_TIME="Time" NR_TAG_RANDOMID="Random ID" NR_ICON="Иконка" NR_SELECT_MODULE="Выбрать модуль" NR_SELECT_CONTINENT="Выбрать континент" NR_SELECT_COUNTRY="Выбрать страну" NR_PLUGIN="Плагин" NR_GMAP_KEY="Ключ Google Maps API Key" NR_GMAP_KEY_DESC="Расширения от Tassos.gr используют ключ ' Google Maps API Key'. Если у Вас возникают какие-либо проблемы с загрузкой карт сервиса Google Map на Ваши страницы, то скорее всего Вам необходимо ввести свой собственный ключ API от Google Map." NR_GMAP_FIND_KEY="Получить ключ API" NR_ARE_YOU_SURE="Вы действительно желаете выполнить это действие?" NR_CUSTOMURL="Произвольный URL" NR_SAMPLE="Пример" NR_DEBUG="Отладка" NR_CUSTOMURL="Произвольный URL" NR_READMORE="Подробнее" NR_IPADDRESS="IP адрес" NR_ASSIGN_BROWSERS="Браузер" NR_ASSIGN_BROWSERS_DESC="Выберите браузер для назначения" NR_ASSIGN_BROWSERS_DESC2="Нацелиться на посетителей, которые просматривают Ваш сайт с конкретных браузеров, таких как Chrome, Firefox или Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Оперативная система" NR_ASSIGN_OS_DESC="Выберите операционную систему для назначения" NR_ASSIGN_OS_DESC2="Нацеливаться на посетителей, которые используют определенную операционную систему. Например, Windows, Linux или Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Число просмотров страницы" NR_ASSIGN_PAGEVIEWS_DESC="Target visitors who have viewed certain number of pages" NR_ASSIGN_PAGEVIEWS_VIEWS="Просмотров" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Введите число просмотров страницы" NR_ASSIGN_COOKIENAME_NAME="Название файла cookie" NR_ASSIGN_COOKIENAME_NAME_DESC="Введите название файла cookie к которому будет привязано это действие" NR_ASSIGN_COOKIENAME_NAME_DESC2="Нацеливаться на посетителей, в браузере которых хранится конкретный файл cookie" NR_FEWER_THAN="Меньше чем" NR_GREATER_THAN="Больше чем" NR_EXACTLY="В точности" NR_EXISTS="Существует" NR_IS_EQUAL="Равно" NR_CONTAINS="Содержит" NR_STARTS_WITH="Начать с" NR_ENDS_WITH="Заканчивается с" NR_ASSIGN_COOKIENAME_CONTENT="Контент файла Cookie" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Содержимое файла cookie" NR_ASSIGN_IP_ADDRESSES_DESC2="Нацеливаться на посетилей с определенным IP адресом (или диапазоном IP адресов)" NR_ASSIGN_IP_ADDRESSES_DESC="Enter a list of comma and/or 'enter' separated ip addresses and ranges

Example:
127.0.0.1,
192.10-120.2,
168" NR_ASSIGN_USER_ID="ID номер пользователя" NR_ASSIGN_USER_ID_DESC="Нацеливаться на конкретных пользователей Joomla на основе их ID номера" NR_ASSIGN_USER_ID_SELECTION_DESC="Enter comma separated Joomla user IDs" NR_ASSIGN_COMPONENTS="Компонент" NR_ASSIGN_COMPONENTS_DESC="Выберите компонент для назначения" NR_ASSIGN_COMPONENTS_DESC2="Нацеливаться на посетителей, которые просматривают содержимое, созданное определенным компонентом" NR_ASSIGN_TIMERANGE="Диапазон времени" NR_ASSIGN_TIMERANGE_DESC="Target visitors based on your server's time" NR_START_TIME="Время начала" NR_END_TIME="Время окончания" NR_START_PUBLISHING_TIMERANGE_DESC="Введите время начала публикации" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Введите время снятия с публикации" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_DESC="Для получения ключа сайта и секретного ключа своего домена, пройдите на https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Ключ сайта" NR_RECAPTCHA_SITE_KEY_DESC="Используется в коде JavaScript, который предоставляется Вашим пользователям." NR_RECAPTCHA_SECRET_KEY="Секретный ключ" NR_RECAPTCHA_SECRET_KEY_DESC="Используется для соединния между Вашим сервером и сервером на котором находится reCaptcha. Обязательно держите этот ключ в секрете." NR_RECAPTCHA_SITE_KEY_ERROR="Ключ 'Site Key' для Вашей reCaptcha либо отсутствует, либо недействителен" NR_PREVIOUS_MONTH="Предыдущий месяц" NR_NEXT_MONTH="Следующий месяц" NR_ASSIGN_GROUP_PAGE_URL="Страница/URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Нацеливаться на посетителей, которые просматривают страницу, принадлежащую какому-либо конкретному пункту меню или ссылкам URL." NR_ASSIGN_GROUP_DATETIME_DESC="Запустить коробку на основе даны и времени на Вашем сервере" NR_ASSIGN_GROUP_USER_VISITOR="Посетитель/пользователь Joomla" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Нацеливаться на посетителей или пользователей, которые просмотрели определенное число веб страниц" NR_ASSIGN_GROUP_PLATFORM="Платформа посетителя" NR_ASSIGN_GROUP_PLATFORM_DESC="Нацеливаться на посетителей, которые используют мобильные устройства, Goolge Chrome или даже Windows" NR_ASSIGN_GROUP_GEO_DESC="Нацеливаться на посетителей, которые физически находятся в определенном регионе" NR_ASSIGN_GROUP_JCONTENT="Содержимое Joomla" NR_ASSIGN_GROUP_JCONTENT_DESC="Нацеливаться на посетителей, просматривающих определенные материалы или категории материалов Joomla" NR_ASSIGN_GROUP_SYSTEM="Система/интеграции" NR_ASSIGN_GROUP_SYSTEM_DESC="Нацеливаться на посетителей, которые получили контент какого-либо конкретного стороннего расширения Joomla" NR_ASSIGN_GROUP_ADVANCED="Расширенное нацеливание на посетителей" NR_ASSIGN_USERGROUP_DESC="Нацеливаться на конкретную группу/группы пользователей Joomla" NR_ASSIGN_ARTICLE_DESC="Нацеливаться на посетителей которые просматривают конкретные материалы, созданные в Joomla" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Нацеливаться на посетителей, которые просматривают конкретные категории Joomla" NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Нацеливаться на посетителей, которые просматривают определенные объекты, категории или метки компонента К2" NR_ASSIGN_K2_ITEMS="Объект" NR_ASSIGN_K2_ITEMS_DESC="Нацеливаться на посетителей, которые просматривают какие-либо конкретные объекты, созданные компонентом К2." NR_ASSIGN_K2_ITEMS_LIST_DESC="Выберите объекты К2 для назначения" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Соответствовать определенным ключевым словам в содержимом объекта. Отделяйте значения запятой или вводите их по одному на строчку." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Соответствовать ключевым словам объекта. Отделяйте значения запятой или вводите их по одному на строчку." NR_ASSIGN_K2_PAGETYPES_DESC="Нацеливаться на посетителей, которые просматривают определенные типы страниц компонента К2" NR_ASSIGN_K2_ITEM_OPTION="Объект" NR_ASSIGN_K2_LATEST_OPTION="Недавно созданное пользователями или в категориях" NR_ASSIGN_K2_TAG_OPTION="Пометить страницу" NR_ASSIGN_K2_CATEGORY_OPTION="Страница категории" NR_ASSIGN_K2_ITEM_FORM_OPTION="Форма правки объекта" NR_ASSIGN_K2_USER_PAGE_OPTION="Страница пользователя (блог)" NR_ASSIGN_K2_TAGS_DESC="Нацеливаться на посетителей, которые просматривают объекты компонента К2 с определенными метками" NR_ASSIGN_K2_CATEGORIES_DESC="Нацеливаться на посетителей, которые просматривают определенную категорию компонента К2" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Категории" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Объекты" NR_ASSIGN_PAGE_TYPES_DESC="Выберите типы страниц для назначения" NR_ASSIGN_TAGS_DESC="Выберите метки для назначения" NR_CONTENT_KEYWORDS="Ключевые слова в контенте" NR_META_KEYWORDS="Ключевые слова" NR_TAG="Метка" NR_NORMAL="Нормальный" NR_COMPACT="Компактный" NR_LIGHT="Светлый" NR_DARK="Темный" NR_SIZE="Размер" NR_THEME="Тема" NR_SINGLE="Single" NR_MULTIPLE="Multiple" NR_RANGE="Диапазон" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Пожалуйста, подтвердите" NR_RECAPTCHA_INVALID_SECRET_KEY="Неверный секретный ключ" NR_PAGE="Страница" NR_YOU_ARE_USING_EXTENSION="Вы используете %s %s" NR_UPDATE="Обновить" NR_SHOW_UPDATE_NOTIFICATION="Показать уведомление об обновлении" NR_SHOW_UPDATE_NOTIFICATION_DESC="Если выбрано, уведомление об обновлении будет отображаться в представлении основного компонента, когда есть новая версия для этого расширения." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s доступен" NR_ERROR_EMAIL_IS_DISABLED="Отправка почты отключена. Письма не могут быть отправлены." NR_ASSIGN_ITEMS="Элемент" NR_COUNTRY_AF="Афганистан" NR_COUNTRY_AX="Аландские острова" NR_COUNTRY_AL="Албания" NR_COUNTRY_DZ="Алжир" NR_COUNTRY_AS="Американское Самоа" NR_COUNTRY_AD="Андорра" NR_COUNTRY_AO="Ангола" NR_COUNTRY_AI="Ангилья" NR_COUNTRY_AQ="Антарктика" NR_COUNTRY_AG="Антигуа и Барбуда" NR_COUNTRY_AR="Аргентина" NR_COUNTRY_AM="Армения" NR_COUNTRY_AW="Аруба" NR_COUNTRY_AU="Австралия" NR_COUNTRY_AT="Австрия" NR_COUNTRY_AZ="Азербайджан" NR_COUNTRY_BS="Багамы" NR_COUNTRY_BH="Бахрейн" NR_COUNTRY_BD="Бангладеш" NR_COUNTRY_BB="Барбадос" NR_COUNTRY_BY="Беларусь" NR_COUNTRY_BE="Бельгия" NR_COUNTRY_BZ="Белиз" NR_COUNTRY_BJ="Бенин" NR_COUNTRY_BM="Bermuda" NR_COUNTRY_BT="Бутан" NR_COUNTRY_BO="Боливия" NR_COUNTRY_BA="Босния и Герцеговина" NR_COUNTRY_BW="Ботсвана" NR_COUNTRY_BV="Остров Буве" NR_COUNTRY_BR="Бразилия" NR_COUNTRY_IO="Британская территория в Индийском океане" NR_COUNTRY_BN="Бруней-Даруссалам" NR_COUNTRY_BG="Болгария" NR_COUNTRY_BF="Буркина-Фасо" NR_COUNTRY_BI="Бурунди" NR_COUNTRY_KH="Камбоджа" NR_COUNTRY_CM="Камерун" NR_COUNTRY_CA="Канада" NR_COUNTRY_CV="Кабо-Верде" NR_COUNTRY_KY="Каймановы острова" NR_COUNTRY_CF="Центральноафриканская Республика" NR_COUNTRY_TD="Чад" NR_COUNTRY_CL="Чили" NR_COUNTRY_CN="Китай" NR_COUNTRY_CX="Остров Рождества" NR_COUNTRY_CC="Кокосовые (Килинг) острова" NR_COUNTRY_CO="Колумбия" NR_COUNTRY_KM="Коморские острова" NR_COUNTRY_CG="Конго" NR_COUNTRY_CD="Конго, Демократическая Республика" NR_COUNTRY_CK="Острова Кука" NR_COUNTRY_CR="Коста-Рика" NR_COUNTRY_CI="Кот-д'Ивуар" NR_COUNTRY_HR="Хорватия" NR_COUNTRY_CU="Куба" ; NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Кипр" NR_COUNTRY_CZ="Чешская республика" NR_COUNTRY_DK="Дания" NR_COUNTRY_DJ="Джибути" NR_COUNTRY_DM="Dominica" NR_COUNTRY_DO="Доминиканская Республика" NR_COUNTRY_EC="Эквадор" NR_COUNTRY_EG="Египет" NR_COUNTRY_SV="Сальвадор" NR_COUNTRY_GQ="Экваториальная Гвинея" NR_COUNTRY_ER="Эритрея" NR_COUNTRY_EE="Эстония" NR_COUNTRY_ET="Эфиопия" NR_COUNTRY_FK="Фолклендские (Мальвинские) острова" NR_COUNTRY_FO="Фарерские острова" NR_COUNTRY_FJ="Фиджи" NR_COUNTRY_FI="Финляндия" NR_COUNTRY_FR="Франция" NR_COUNTRY_GF="Французская Гвиана" NR_COUNTRY_PF="Французская Полинезия" NR_COUNTRY_TF="Французские Южные Территории" NR_COUNTRY_GA="Габон" NR_COUNTRY_GM="Гамбия" NR_COUNTRY_GE="Грузия" NR_COUNTRY_DE="Германия" NR_COUNTRY_GH="Гана" NR_COUNTRY_GI="Гибралтар" NR_COUNTRY_GR="Греция" NR_COUNTRY_GL="Гренландия" NR_COUNTRY_GD="Гренада" NR_COUNTRY_GP="Гваделупа" NR_COUNTRY_GU="Гуам" NR_COUNTRY_GT="Гватемала" NR_COUNTRY_GG="Гернси" NR_COUNTRY_GN="Guinea" NR_COUNTRY_GW="Гвинея-Бисау" NR_COUNTRY_GY="Гайана" NR_COUNTRY_HT="Гаити" NR_COUNTRY_HM="Остров Херд и острова Макдональд" NR_COUNTRY_VA="Святой Престол (город-государство Ватикан)" NR_COUNTRY_HN="Гондурас" NR_COUNTRY_HK="Гонконг" NR_COUNTRY_HU="Венгрия" NR_COUNTRY_IS="Исландия" NR_COUNTRY_IN="Индия" NR_COUNTRY_ID="Индонезия" NR_COUNTRY_IR="Иран, Исламская Республика" NR_COUNTRY_IQ="Ирак" NR_COUNTRY_IE="Ирландия" NR_COUNTRY_IM="Остров Мэн" NR_COUNTRY_IL="Израиль" NR_COUNTRY_IT="Италия" NR_COUNTRY_JM="Ямайка" NR_COUNTRY_JP="Япония" NR_COUNTRY_JE="Джерси" NR_COUNTRY_JO="Джордан" NR_COUNTRY_KZ="Казахстан" NR_COUNTRY_KE="Кения" NR_COUNTRY_KI="Кирибати" NR_COUNTRY_KP="Корея, Народно-Демократическая Республика" NR_COUNTRY_KR="Республика Корея" NR_COUNTRY_KW="Кувейт" NR_COUNTRY_KG="Кыргызстан" NR_COUNTRY_LA="Лаосская Народно-Демократическая Республика" NR_COUNTRY_LV="Латвия" NR_COUNTRY_LB="Ливан" NR_COUNTRY_LS="Лесото" NR_COUNTRY_LR="Либерия" NR_COUNTRY_LY="Ливийская Арабская Джамахирия" NR_COUNTRY_LI="Лихтенштейн" NR_COUNTRY_LT="Литва" NR_COUNTRY_LU="Люксембург" NR_COUNTRY_MO="Macao" NR_COUNTRY_MK="Македония" NR_COUNTRY_MG="Мадагаскар" NR_COUNTRY_MW="Малави" NR_COUNTRY_MY="Малайзия" NR_COUNTRY_MV="Мальдивы" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Мальта" NR_COUNTRY_MH="Маршалловы острова" NR_COUNTRY_MQ="Мартиника" NR_COUNTRY_MR="Мавритания" NR_COUNTRY_MU="Маврикий" NR_COUNTRY_YT="Майотта" NR_COUNTRY_MX="Мексика" NR_COUNTRY_FM="Микронезия, Федеративные Штаты" NR_COUNTRY_MD="Республика Молдова" NR_COUNTRY_MC="Монако" NR_COUNTRY_MN="Монголия" NR_COUNTRY_ME="Черногория" NR_COUNTRY_MS="Монсеррат" NR_COUNTRY_MA="Марокко" NR_COUNTRY_MZ="Мозамбик" NR_COUNTRY_MM="Мьянма" NR_COUNTRY_NA="Намибия" NR_COUNTRY_NR="Науру" NR_COUNTRY_NM="Северная македония" NR_COUNTRY_NP="Непал" NR_COUNTRY_NL="Нидерланды" NR_COUNTRY_AN="Нидерландские Антильские острова" NR_COUNTRY_NC="Новая Каледония" NR_COUNTRY_NZ="Новая Зеландия" NR_COUNTRY_NI="Никарагуа" NR_COUNTRY_NE="Нигер" NR_COUNTRY_NG="Нигерия" NR_COUNTRY_NU="Ниуэ" NR_COUNTRY_NF="Остров Норфолк" NR_COUNTRY_MP="Северные Марианские острова" NR_COUNTRY_NO="Норвегия" NR_COUNTRY_OM="Оман" NR_COUNTRY_PK="Пакистан" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Палестинская территория" NR_COUNTRY_PA="Панама" NR_COUNTRY_PG="Папуа-Новая Гвинея" NR_COUNTRY_PY="Парагвай" NR_COUNTRY_PE="Перу" NR_COUNTRY_PH="Филиппины" NR_COUNTRY_PN="Pitcairn" NR_COUNTRY_PL="Польша" NR_COUNTRY_PT="Португалия" NR_COUNTRY_PR="Пуэрто-Рико" NR_COUNTRY_QA="Катар" NR_COUNTRY_RE="Reunion" NR_COUNTRY_RO="Румыния" NR_COUNTRY_RU="Российская Федерация" NR_COUNTRY_RW="Руанда" NR_COUNTRY_SH="Святая Елена" NR_COUNTRY_KN="Сент-Китс и Невис" NR_COUNTRY_LC="Сент-Люсия" NR_COUNTRY_PM="Сен-Пьер и Микелон" NR_COUNTRY_VC="Сент-Винсент и Гренадины" NR_COUNTRY_WS="Самоа" NR_COUNTRY_SM="Сан-Марино" NR_COUNTRY_ST="Сан-Томе и Принсипи" NR_COUNTRY_SA="Саудовская Аравия" NR_COUNTRY_SN="Сенегал" NR_COUNTRY_RS="Сербия" NR_COUNTRY_SC="Сейшельские острова" NR_COUNTRY_SL="Сьерра-Леоне" NR_COUNTRY_SG="Сингапур" NR_COUNTRY_SK="Словакия" NR_COUNTRY_SI="Словения" NR_COUNTRY_SB="Соломоновы Острова" NR_COUNTRY_SO="Сомали" NR_COUNTRY_ZA="Южная Африка" NR_COUNTRY_GS="Южная Георгия и Южные Сандвичевы острова" NR_COUNTRY_ES="Испания" NR_COUNTRY_LK="Шри-Ланка" NR_COUNTRY_SD="Судан" NR_COUNTRY_SS="Южный Судан" NR_COUNTRY_SR="Суринам" NR_COUNTRY_SJ="Шпицберген и Ян Майен" NR_COUNTRY_SZ="Свазиленд" NR_COUNTRY_SE="Швеция" NR_COUNTRY_CH="Швейцария" NR_COUNTRY_SY="Сирийская Арабская Республика" NR_COUNTRY_TW="Тайвань" NR_COUNTRY_TJ="Таджикистан" NR_COUNTRY_TZ="Танзания, Объединенная Республика" NR_COUNTRY_TH="Таиланд" NR_COUNTRY_TL="Восточный Тимор" NR_COUNTRY_TG="Того" NR_COUNTRY_TK="Токелау" NR_COUNTRY_TO="Тонга" NR_COUNTRY_TT="Тринидад и Тобаго" NR_COUNTRY_TN="Тунис" NR_COUNTRY_TR="Турция" NR_COUNTRY_TM="Туркменистан" NR_COUNTRY_TC="Острова Теркс и Кайкос" NR_COUNTRY_TV="Тувалу" NR_COUNTRY_UG="Уганда" NR_COUNTRY_UA="Украина" NR_COUNTRY_AE="Объединенные Арабские Эмираты" NR_COUNTRY_GB="Великобритания" NR_COUNTRY_US="Соединенные Штаты" NR_COUNTRY_UM="Малые отдаленные острова США" NR_COUNTRY_UY="Уругвай" NR_COUNTRY_UZ="Узбекистан" NR_COUNTRY_VU="Вануату" NR_COUNTRY_VE="Венесуэла" NR_COUNTRY_VN="Вьетнам" NR_COUNTRY_VG="Британские Виргинские острова" NR_COUNTRY_VI="Виргинские острова, США" NR_COUNTRY_WF="Уоллис и Футуна" NR_COUNTRY_EH="Западная Сахара" NR_COUNTRY_YE="Йемен" NR_COUNTRY_ZM="Замбия" NR_COUNTRY_ZW="Зимбабве" NR_CONTINENT_AF="Африка" NR_CONTINENT_AS="Азия" NR_CONTINENT_EU="Европа" NR_CONTINENT_NA="Северная Америка" NR_CONTINENT_SA="Южная Америка" NR_CONTINENT_OC="Океания" NR_CONTINENT_AN="Антарктика" NR_FRONTEND="Пользовательский интерфейс" NR_BACKEND="Администрация" NR_EMBED="Присоединен" NR_RATE="Ставка %s" NR_REPORT_ISSUE="Сообщить о проблеме" NR_CANNOT_CREATE_FOLDER="Невозможно создать папку для перемещения файла. %s" NR_CANNOT_MOVE_FILE="Невозможно переместить файл: %s" NR_UPLOAD_INVALID_FILE_TYPE="Неподдерживаемый файл: %s. Допустимые типы файлов:%s" NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Невозможно загрузить файл: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" PK!#ZZBsystem/nrframework/language/ca-ES/ca-ES.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - utilitzat per les extensions Tassos.gr" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignorar" NR_INCLUDE="Incloure" NR_EXCLUDE="Excloure" NR_SELECTION="Selecció" NR_ASSIGN_MENU_NOITEM="Incloure sense Itemid" NR_ASSIGN_MENU_NOITEM_DESC="Assignar també quan no hi ha cap Itemid de menú establert a la URL?" NR_ASSIGN_MENU_CHILD="També als hereus" NR_ASSIGN_MENU_CHILD_DESC="Asignar també als ítems que hereden d'aquest ítem?" NR_COPY_OF="Copia de %s" NR_ASSIGN_DATETIME_DESC="Fixa els visitants segons la data i hora (datetime) del teu servidor" NR_DATETIME="Datetime" NR_TIME="Hora" NR_DATE="Data" NR_DATETIME_DESC="Escriu la data i hora (datetime) per auto publicar/deixar de publicar" NR_START_PUBLISHING="Data i hora d'inici" NR_START_PUBLISHING_DESC="Escriu la data per començar a publicar" NR_FINISH_PUBLISHING="Data i hora final" NR_FINISH_PUBLISHING_DESC="Escriu la data per deixar de publicar" NR_DATETIME_NOTE="L'assignació de data i hora utilitza la data/hora dels teus servidors, no del sistema del visitant" NR_ASSIGN_PHP="PHP" NR_PHPCODE="Codi PHP" NR_ASSIGN_PHP_DESC="Escriu un tros de codi PHP per avaluar." NR_ASSIGN_PHP_DESC2="Apunta als visitants avaluant codi PHP personalitzat. El codi ha de retornar el valor cert o fals.

Per exemple:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Hora al lloc" NR_SECONDS="Segons" NR_ASSIGN_TIMEONSITE_DESC="Escriu la duració en segons per comparar amb el temps total que l'usuari (duració de la visita) ha passat a tot el teu lloc.

Exemple:
Si vols mostrar una caixa un cop l'usuari ha passat 3 minuts al lloc, escriu 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Apunta als visitants que naveguen des d'URLs específiques" NR_ASSIGN_URLS_DESC="Escriu (part de) les URLs a coincidir
Utilitza una línia per cada coincidència." NR_ASSIGN_URLS_LIST="Coincidències URL" NR_ASSIGN_URLS_REGEX="Utilitzar Expressió Regular" NR_ASSIGN_URLS_REGEX_DESC="Escull per tractar el valor com una Expressió Regular." NR_ASSIGN_LANGS="Idioma" NR_ASSIGN_LANGS_DESC="Apunta als visitants que naveguen en un idioma específic" NR_ASSIGN_LANGS_LIST_DESC="Escull els idiomes als que assignar" NR_ASSIGN_DEVICES="Dispositiu" NR_ASSIGN_DEVICES_DESC2="Apunta als visitants que utilitzen un dispositiu específic com Mòbil, Tauleta o Escriptori" NR_ASSIGN_DEVICES_DESC="Escull els dispositius als que assignar" NR_ASSIGN_DEVICES_NOTE="Tingues en compte que la detecció de dispositius no és 100% acurada. Els usuaris poden configurar els seus navegadors per imitar altres dispositius" NR_MENU="Menú" NR_MENU_ITEMS="Ítem de menú" NR_MENU_ITEMS_DESC="Apunta als usuaris que naveguen per ítems de menú concrets" NR_USERGROUP="Grup d'usuari" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Grup d'usuari" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Mostrar Copyright" NR_SHOW_COPYRIGHT_DESC="Si està seleccionat, es mostrarà informació extra de copyright a la vista d'administració. Les extensions de Tassos.gr mai mostraran informació de copyright o backlinks a la part pública." NR_WIDTH="Amplada" NR_WIDTH_DESC="Escriu l'amplada en px, em o %

Exemple: 400px" NR_HEIGHT="Alçada" NR_HEIGHT_DESC="Escriu l'alçada en px, em o %

Exemple: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Escriu l'encoixinat (padding) en px, em o %

Exemple: 400px" NR_MARGIN="Marge" NR_MARGIN_DESC="La propietat CSS margin s'utilitza per generar espai al voltant de la caixa i establir la mida de l'espai en blanc al voltant de la vora en píxels o en %.

Exemple 1: 25px
Exemple 2: 5%

Especificant el marge per cada costat [top right bottom left]:

Només costat superior: 25px 0 0 0
Només costat dret: 0 25px 0 0
Només costat inferior: 0 0 25px 0
Només costat esquerra: 0 0 0 25px" NR_COLOR_HOVER="Hover color" NR_COLOR="Color" NR_COLOR_DESC="Defineix el color en format HEX o RGBA." NR_TEXT_COLOR="Color del text" NR_BACKGROUND="Fons" NR_BACKGROUND_COLOR="Color del fons" NR_BACKGROUND_COLOR_DESC="Defeineix un color de fons en format HEX o RGBA. Per desactivar-ho escriu 'cap'. Per una transparència absoluta escriu 'transparent'." NR_URL_SHORTENING_FAILED="Ha fallat l'escurçament de %s amb %s. %s." NR_EXPORT="Exportar" NR_IMPORT="Importar" NR_PLEASE_CHOOSE_A_VALID_FILE="Escull un nom d'arxiu vàlid" NR_IMPORT_ITEMS="Importar ítems" NR_PUBLISH_ITEMS="Publicar ítems" NR_AS_EXPORTED="Com exportat" NR_TITLE="Títol" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="Llistat AcyMailing" NR_ACYMAILING_LIST_DESC="Escull els llistats AcyMailing als que assignar" NR_ASSIGN_ACYMAILING_DESC="Apunta als visitants que s'hagin subscrit a llistats específics d'AcyMailing" NR_AKEEBASUBS="Akeeba Subscriptions" NR_AKEEBASUBS_LEVELS="Nivells" NR_AKEEBASUBS_LEVELS_DESC="Escull els nivells d'Akeeba Subscription als que assignar" NR_ASSIGN_AKEEBASUBS_DESC="Apunta als visitants que hagin fet una subscripció específica Akeeba" NR_MATCH="Coincidència" NR_MATCH_DESC="El mètode de coincidència utilitzat per comparar els valors" NR_ASSIGN_MATCHING_METHOD="Mètode de coincidència" NR_ASSIGN_MATCHING_METHOD_DESC="Haurien de coincidir totes o només algunes de les assignacions

Totes
Es publicarà si coincideixen totes les assignacions a continuació coincideixen.

Qualsevol
Es publicarà si qualsevol (una o més) de les assignacions a continuació coincideixen.
S'ignoraran els grups d'assignació on se seleccioni 'Ignore'." NR_ANY="Qualsevol" ; NR_ALL="All" NR_ASSIGN_REFERRER="URL del referenciador" NR_ASSIGN_REFERRER_DESC2="Apunta als visitants que arribin al teu lloc des 'duna font de trànsit específica" NR_ASSIGN_REFERRER_DESC="Escriu la URL d'un referenciador a cada línia. Exemple:

google.com
facebook.com/lamevapagina" NR_ASSIGN_REFERRER_NOTE="Tingues en compte que la detecció de la URL de referència no és 100% acurada. Alguns servidors poden utilitzar servidors intermediaris que modifiquen aquesta informació i podria ser alterada fàcilment." NR_PROFEATURE_HEADER="%s és una funcionalitat PRO" NR_PROFEATURE_DESC="%s no està disponible al teu pla. Millora'l al PRO per desbloquejar totes aquestes funcionalitat increïbles." NR_PROFEATURE_DISCOUNT="Bonificació: %s els usuaris gratuïts tenen un 20% de descompte sobre el preu normal aplicat automàticament a caixa." NR_ONLY_AVAILABLE_IN_PRO="Només disponible a la versió PRO" NR_UPGRADE_TO_PRO="Millorar a PRO" NR_UPGRADE_TO_PRO_TO_UNLOCK="Millora a la versió PRO per desbloquejar" NR_UPGRADE_TO_PRO_VERSION="Fantàstic! Només falta un pas. Clica al botó a continuació per completar la millora a la versió PRO." NR_UNLOCK_PRO_FEATURE="Desbloquejar característica PRO" NR_USING_THE_FREE_VERSION="Estàs utilitzant la versió GRATUÏTA de Convert Forms. Compra la versió PRO per tenir totes les funcionalitats." NR_LEFT_TO_RIGHT="D'esquerra a dreta" NR_RIGHT_TO_LEFT="De dreta a esquerra" NR_BGIMAGE="Imatge de fons" NR_BGIMAGE_DESC="Estableix una imatge de fons" NR_BGIMAGE_FILE="Imatge" NR_BGIMAGE_FILE_DESC="Escull o puja una imatge per ser la background-image." NR_BGIMAGE_REPEAT="Repetir" NR_BGIMAGE_REPEAT_DESC="La propietat background-repeat estableix si/com una imatge de fons es repetirà. Per defecte, una background-image es repeteix tant vertical com horitzontalment.

Repetir: La imatge de fons es repetirà tan vertical com horitzontalment.

Repeat-x: La imatge de fons només es repetirà horitzontalment.

Repeat-y: La imatge de fons només es repetirà verticalment.

No-repeat: La imatge de fons no es repetirà" NR_BGIMAGE_SIZE="Mida" NR_BGIMAGE_SIZE_DESC="Especifica la mida de la imatge de fons.

Auto: La imatge de fons conté la seva alçada i amplada

Cover: Escala la imatge de fons per ser tan gran com calgui perquè l'àrea del fons quedi completament coberta per la imatge. Pot ser que algunes parts de la imatge de fons no estiguin a la vista dins de l'àrea de posicionament del fons.

Contain: Escala la imatge a la mida més gran que capigui tan vertical com horitzontalment dins l'àrea de contingut

100%: Estira la imatge de fons per cobrir completament l'àrea de contingut." NR_BGIMAGE_POSITION="Posició" NR_BGIMAGE_POSITION_DESC="La propietat background-position estableix la posició d'inici d'una imatge de fons. Per defecte, la imatge de fons es col·loca a la cantonada superior-esquerra. El primer valor és la posició horitzontal i el segon la vertical.

Pots utilitzar un dels valors predefinits o escriure un valor personalitzat en percentatge (x% y%) o en píxels (xPos yPos)" NR_RTL="Activar RTL" NR_RTL_DESC="La direcció de text dreta a esquerra és essencial per textos de dreta a esquerra com l'Àrab, Hebreu, Siri o tāna." NR_HORIZONTAL="Horitzontal" NR_VERTICAL="Vertical" NR_FORM_ORIENTATION="Orientació del formulari" NR_FORM_ORIENTATION_DESC="Escull la orientació del formulari" NR_ASSIGN_CATEGORY="Categories" NR_ASSIGN_CATEGORY_DESC="Escull les categories a les que assignar" NR_ASSIGN_CATEGORY_CHILD="També als hereus" NR_ASSIGN_CATEGORY_CHILD_DESC="Asignar també als ítems que hereden d'aquest ítem?" NR_NEW="Nou" NR_LIST="Llistar" NR_DOCUMENTATION="Documentació" NR_KNOWLEDGEBASE="Base de coneixements" NR_FAQ="PMF" NR_INFORMATION="Informació" NR_EXTENSION="Extensió" NR_VERSION="Versió" NR_CHANGELOG="Registre de canvis" ; NR_DOWNLOAD="Download" NR_DOWNLOAD_KEY_MISSING="Falta la clau de descàrrega" NR_DOWNLOAD_KEY="Clau de descàrrega" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="Per poder actualitzar %s a través de l'actualitzador de Joomla!, necessites escriure una clau de descàrrega a la configuració del Connector Novarain Framework" NR_DOWNLOAD_KEY_FIND="Trobar la clau de descàrrega" NR_DOWNLOAD_KEY_UPDATE="Actualitzar clau de descàrrega" NR_OK="OK" NR_MISSING="Perdut" NR_LICENSE="Llicència" NR_AUTHOR="Autor" NR_FOLLOWME="Segueix-me" NR_FOLLOW="Segueix %s" NR_TRANSLATE_INTEREST="T'agradaria ajudar traduint %s al teu idioma" NR_TRANSIFEX_REQUEST="Envia'm una petició a Transifex" NR_HELP_WITH_TRANSLATIONS="Ajuda amb les traduccions" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Avançat" NR_USEGLOBAL="Ús global" NR_WEEKDAY="Dia de la setmana" NR_MONTH="Mes" NR_MONDAY="Dilluns" NR_TUESDAY="Dimarts" NR_WEDNESDAY="Dimecres" NR_THURSDAY="Dijous" NR_FRIDAY="Divendres" NR_SATURDAY="Dissabte" NR_WEEKEND="Cap de setmana" NR_WEEKDAYS="Entre setmana" NR_SUNDAY="Dilluns" NR_JANUARY="Gener" NR_FEBRUARY="Febrer" NR_MARCH="Març" NR_APRIL="Abril" NR_MAY="Maig" NR_JUNE="Juny" NR_JULY="Juliol" NR_AUGUST="Agost" NR_SEPTEMBER="Setembre" NR_OCTOBER="Octubre" NR_NOVEMBER="Novembre" NR_DECEMBER="Desembre" NR_NEVER="Mai" NR_SECONDS="Segons" NR_MINUTES="Minuts" NR_HOURS="Hores" NR_DAYS="Dies" NR_SESSION="Sessió" NR_EVER="Mai" NR_COOKIE="Galeta" NR_BOTH="Ambdos" NR_NONE="Cap" ; NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Escriptori" NR_MOBILES="Mòbil" NR_TABLETS="Tauleta" NR_PER_SESSION="Per sessió" NR_PER_DAY="Per dia" NR_PER_WEEK="Per setmana" NR_PER_MONTH="Per més" NR_FOREVER="Sempre" NR_FEATURE_UNDER_DEV="Aquesta funcionalitat encara està en desenvolupament" NR_LIKE_THIS_EXTENSION="T'agrada aquesta extensió?" NR_LEAVE_A_REVIEW="Deixa una opinió al JED" NR_SUPPORT="Suport" NR_NEED_SUPPORT="Necessites ajuda?" NR_DROP_EMAIL="Envia'm un correu electrònic" NR_READ_DOCUMENTATION="Llegir la documentació" NR_COPYRIGHT="%s - Tassos.gr Tots els drets reservats" NR_DASHBOARD="Taulell de control" NR_NAME="Nom" NR_WRONG_COORDINATES="Les coordinades subministrades no són vàlides" NR_ENTER_COORDINATES="Latitud, Longitud" NR_NO_ITEMS_FOUND="No s'han trobat ítems" NR_ITEM_IDS="No hi ha Ids d'ítem" NR_TOGGLE="Canviar" NR_EXPAND="Expandir" NR_COLLAPSE="Colapsar" NR_SELECTED="Escollit" NR_MAXIMIZE="Maximitzar" NR_MINIMIZE="Minimitzar" NR_SELECTION="Selecció" NR_INSTALL="Instal·lar" NR_INSTALL_NOW="Instal·lar ara" NR_INSTALLED="Instal·lat" NR_COMING_SOON="Aviat disponible" NR_ROADMAP="Al pla de ruta" NR_MEDIA_VERSIONING="Utilitzar versionat multimèdia" NR_MEDIA_VERSIONING_DESC="Escull per afegir el número de versió de l'extensió al final de la url multimèdia (js/css) , per assegurar que els navegadors carreguen l'arxiu correcte" NR_LOAD_JQUERY="Carregar jQuery" NR_LOAD_JQUERY_DESC="Escull carregar l'script base de jQuery. Pots deshabilitar això si et trobes conflictes amb la plantilla o qualsevol altra extensió que carregui la seva versió pròpia de jQuery." NR_SELECT_CURRENCY="Escull una divisa" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Campanya" NR_ASSIGN_CONVERTFORMS_DESC="Apunta als visitants que s'haguin subscrit a una campanya específica de ConvertForms" NR_CONVERTFORMS_LIST_DESC="Escull la campanya ConvertForms a la que assignar." NR_LEFT="Esquerra" NR_CENTER="Centre" NR_RIGHT="Dreta" NR_BOTTOM="Inferior" NR_TOP="Superior" NR_AUTO="Auto" NR_CUSTOM="Personalitzat" NR_UPLOAD="Pujar" NR_IMAGE="Imatge" NR_INTRO_IMAGE="Imatge d'introducció" NR_FULL_IMAGE="Imatge completa" NR_IMAGE_SELECT="Escull imatge" NR_IMAGE_SIZE_COVER="Coberta" NR_IMAGE_SIZE_CONTAIN="Conté" NR_REPEAT="Repetir" NR_REPEAT_X="Repetir x" NR_REPEAT_Y="Repetir y" NR_REPEAT_NO="Sense repetició" NR_FIELD_STATE_DESC="Estableix l'estat de l'ítem" NR_CREATED_DATE="Data de creació" NR_CREATED_DATE_DESC="La data de creació de l'ítem" NR_MODIFIFED_DATE="Data de modificació" NR_MODIFIFED_DATE_DESC="La data en què es va modificar per darrera vegada l'ítem." NR_CATEGORIES="Categoria" NR_CATEGORIES_DESC="Escull la categoria a la que assignar." NR_ALSO_ON_CHILD_ITEMS="També als hereus" NR_ALSO_ON_CHILD_ITEMS_DESC="Asignar també als ítems que hereden d'aquest ítem?" NR_PAGE_TYPE="Tipus de pàgina" NR_PAGE_TYPES="Tipus de pàgines" NR_PAGE_TYPES_DESC="Escull a quins tipus de pàgines hauria d'estar activa l'assignació." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" NR_ARTICLE_VIEW_DESC="Activa per tenir en compte la vista d'article" NR_CATEGORY_VIEW="Vista de categoria" NR_CATEGORY_VIEW_DESC="Activa per tenir en compte la vista de categoria" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Articles" NR_ARTICLES_DESC="Escull els articles als que assignar." NR_ARTICLE="Article" NR_ARTICLE_AUTHORS="Autors" NR_ARTICLE_AUTHORS_DESC="Escull els autors als que assignar." NR_ONLY="Només" NR_OTHERS="Altres" NR_SMARTTAGS="Etiquetes intel·ligents" NR_SMARTTAGS_SHOW="Mostrar etiquetes intel·ligents" NR_SMARTTAGS_NOTFOUND="No s'han trobat etiquetes intel·ligents" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Buscar etiquetes intel·ligents" NR_CONTACT_US="Contacta'ns" NR_FONT_COLOR="Color de font" NR_FONT_SIZE="Mida de la font" NR_FONT_SIZE_DESC="Escull una mida en píxels per la font" NR_TEXT="Text" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Activa a la substitució de sortida" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Activa el renderitzat de l'extensió quan el disseny de la pàgina (tmpl) està substituït. Exemples: tmpl=component o tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Activa a la substitució de format" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Activa el renderitzat de l'extensió quan el format de la pàgina és HTML. Exemples: format=raw o format=json." NR_GEOLOCATING="Geolocalització" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="La geolocalització no sempre és 100% acurada. La geolocalització es basa en l'adreça IP del visitant. No totes les adreces IP són fixes o conegudes." NR_CITY="Ciutat" NR_CITY_NAME="Nom de la ciutat" NR_CONDITION_CITY_DESC="Escriu el nom d'una població en anglès. Escriu-ne diverses separant-les amb comes." NR_CONTINENT="Continent" NR_REGION="Regió" NR_CONDITION_REGION_DESC="El valor està format per dues parts, les dues lletres del codi de país ISO 3166-1 i el codi de regió. Per tant, el valor hauria de seguir el format següent: COUNTRY_CODE-REGION_CODE. Pots consultar una llista completa de codis de regió clicant a l'enllaç 'Trobar un codi de regió'" NR_ASSIGN_COUNTRIES="País" NR_ASSIGN_COUNTRIES_DESC2="Aputa als visitants que estan físicament a un país concret" NR_ASSIGN_COUNTRIES_DESC="Escull els països als que assignar" NR_ASSIGN_CONTINENTS="Continent" NR_ASSIGN_CONTINENTS_DESC="Escull els continents als que assignar" NR_ASSIGN_CONTINENTS_DESC2="Aputa als visitants que estan físicament a un continent concret" NR_ICONTACT_ACCOUNTID_ERROR="No s'ha pogut recuperar l'AccountID d'iContact" NR_TAG_CLIENTDEVICE="Tipus de dispositiu del visitant" NR_TAG_CLIENTOS="Sistema operatiu del visitant" NR_TAG_CLIENTBROWSER="Navegador del visitant" NR_TAG_CLIENTUSERAGENT="Cadena d'agent del visitant" NR_TAG_IP="Adreça IP del visitant" NR_TAG_URL="URL de pàgina" NR_TAG_URLENCODED="URL de la pàgina codificada" NR_TAG_URLPATH="Ruta de la pàgina" NR_TAG_REFERRER="Referenciador de la pàgina" NR_TAG_SITENAME="Nom del lloc" NR_TAG_SITEURL="URL del lloc" NR_TAG_PAGETITLE="Títol de la pàgina" NR_TAG_PAGEDESC="Meta descripció de la pàgina" NR_TAG_PAGELANG="Codi d'idioma de la pàgina" NR_TAG_USERID="ID d'usuari" NR_TAG_USERNAME="Nom complet de l'usuari" NR_TAG_USERLOGIN="Inici de sessió de l'usuari" NR_TAG_USEREMAIL="Correu electrònic de l'usuari" NR_TAG_USERFIRSTNAME="Nom de l'usuari" NR_TAG_USERLASTNAME="Cognom de l'usuari" NR_TAG_USERGROUPS="ID's dels grups d'usuari" NR_TAG_DATE="Data" NR_TAG_TIME="Hora" NR_TAG_RANDOMID="ID aleatori" NR_ICON="Icona" NR_SELECT_MODULE="Escull un mòdul" NR_SELECT_CONTINENT="Escull un continent" NR_SELECT_COUNTRY="Escull un país" NR_PLUGIN="Connector" NR_GMAP_KEY="Clau API Google Maps" NR_GMAP_KEY_DESC="Les extensions Tassos.gr utilitzen la clau API de Google Maps. Si et trobes amb dificultats perquè no es carrega un mapa de Google Maps probablement és perquè no has introduït la teva clau API" NR_GMAP_FIND_KEY="Aconseguir una clau API" NR_ARE_YOU_SURE="Estàs segur?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="URL personalitzada" NR_SAMPLE="Mostra" NR_DEBUG="Depuració" NR_CUSTOMURL="URL personalitzada" NR_READMORE="Llegir més" NR_IPADDRESS="Adreça IP" NR_ASSIGN_BROWSERS="Navegador" NR_ASSIGN_BROWSERS_DESC="Escull el navegador al que assignar" NR_ASSIGN_BROWSERS_DESC2="Apunta als visitants que naveguen pel teu lloc amb navegadors específics com Chrome, Firefox o Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Sistema Operatiu" NR_ASSIGN_OS_DESC="Escull el sistema operatiu al que assignar" NR_ASSIGN_OS_DESC2="Apunta als visitants que utilitzen sistemes operatius concrets com Windows Linux o Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Quantitat d'impressions de la pàgina" NR_ASSIGN_PAGEVIEWS_DESC="Apunta als visitants que han visitat un cert nombre de pàgines" NR_ASSIGN_PAGEVIEWS_VIEWS="Impressions de pàgina" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Escriu la quantitat d'impressions de pàgina" NR_ASSIGN_COOKIENAME_NAME="Nom de galeta" NR_ASSIGN_COOKIENAME_NAME_DESC="Escriu el nom de la galeta a la que assignar" NR_ASSIGN_COOKIENAME_NAME_DESC2="Apunta als visitants que tenen galetes específiques guardades al seu navegador" NR_FEWER_THAN="Menor que" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="Major que" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Exactament" NR_EXISTS="Existeix" ; NR_NOT_EXISTS="Does not exists" NR_IS_EQUAL="Iguals" ; NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Conté" ; NR_DOES_NOT_CONTAIN="Does not contain" NR_STARTS_WITH="Comença amb" ; NR_DOES_NOT_START_WITH="Does not start with" NR_ENDS_WITH="Acaba amb" ; NR_DOES_NOT_END_WITH="Does not end with" NR_ASSIGN_COOKIENAME_CONTENT="Contingut de la galeta" NR_ASSIGN_COOKIENAME_CONTENT_DESC="El contingut de la galeta" NR_ASSIGN_IP_ADDRESSES_DESC2="Apunta als visitants que estan darrere una adreça IP concreta (rang)" NR_ASSIGN_IP_ADDRESSES_DESC="Escriu una llista d'adreces i rangs IP separats per comes i/o 'intro'

Exemple:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="ID d'usuari" NR_ASSIGN_USER_ID_DESC="Apunta a usuaris Joomla! específics pel seu ID" NR_ASSIGN_USER_ID_SELECTION_DESC="Escriu una llista separades per comes d'IDs d'usuaris Joomla!" NR_ASSIGN_COMPONENTS="Component" NR_ASSIGN_COMPONENTS_DESC="Escull el component al que assignar" NR_ASSIGN_COMPONENTS_DESC2="Apunta als visitants que estan navegant components concrets" NR_ASSIGN_TIMERANGE="Interval de temps" NR_ASSIGN_TIMERANGE_DESC="Fixa els visitants segons l'hora del teu servidor" NR_START_TIME="Hora d'inici" NR_END_TIME="Hora final" NR_START_PUBLISHING_TIMERANGE_DESC="Escriu l'hora per començar a publicar" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Escriu l'hora per deixar de publicar" NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Clau de lloc" NR_RECAPTCHA_SITE_KEY_DESC="Utilitzada al codi JavaScript que es serveix als teus usuaris" NR_RECAPTCHA_SECRET_KEY="Clau Secreta" NR_RECAPTCHA_SECRET_KEY_DESC="Utilitzada a la comunicació entre el teu servidor i el servidor reCAPTCHA. Assegura't de mantenir-la secreta." NR_RECAPTCHA_SITE_KEY_ERROR="Falta la clau de lloc reCAPTCHA, o és invàlida" NR_PREVIOUS_MONTH="Mes anterior" NR_NEXT_MONTH="Proper mes" NR_ASSIGN_GROUP_PAGE_URL="Pàgina / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Apunta als usuaris que naveguen per ítems de menú concrets o URLs" NR_ASSIGN_GROUP_DATETIME_DESC="Activa una caixa segons la data i hora del teu servidor" NR_ASSIGN_GROUP_USER_VISITOR="Usuari Joomla / Visitant" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Apunta a usuaris registrats o visitants que hagin vist un cert nombre de pàgines" NR_ASSIGN_GROUP_PLATFORM="Plataforma del visitant" NR_ASSIGN_GROUP_PLATFORM_DESC="Apunta als visitants que fan servir mòbil, Google Chrome o inclús Windows" NR_ASSIGN_GROUP_GEO_DESC="Apunta als visitants que estan físicament a una regió concreta" NR_ASSIGN_GROUP_JCONTENT="Contingut Joomla!" NR_ASSIGN_GROUP_JCONTENT_DESC="Apunta als visitants que estan veient articles o categories Joomla! concretes" NR_ASSIGN_GROUP_SYSTEM="Sistema / Integracions" ; NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Apunta als servidors que han interactuat amb extensions Joomla! de tercers específiques" NR_ASSIGN_GROUP_ADVANCED="Apuntat a visitants avançat" NR_ASSIGN_USERGROUP_DESC="Apunta a grups d'usuaris Joomla! específics" NR_ASSIGN_ARTICLE_DESC="Apunta als visitants que estan veient articles Joomla! concrets" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Apunta als visitants que estan veient categories Joomla! concretes" NR_EXTENSION_REQUIRED="El component %s requereix que el connector %s estigui activat per funcionar correctament." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Apunta als visitants que naveguen per ítems K2, categories o etiquetes específiques" NR_ASSIGN_K2_ITEMS="Ítem" NR_ASSIGN_K2_ITEMS_DESC="Apunta als usuaris que naveguen per ítems K2 concrets." NR_ASSIGN_K2_ITEMS_LIST_DESC="Escull els ítems K2 als que assignar" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Coincidència de paraules clau al contingut de l'ítem. Separa-les amb comes o nova línia." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Coincidència de les meta paraules clau de l'ítem. Separa-les amb comes o nova línia." NR_ASSIGN_K2_PAGETYPES_DESC="Apunta als usuaris que naveguen per tipus de pàgines K2 concrets." NR_ASSIGN_K2_ITEM_OPTION="Ítem" NR_ASSIGN_K2_LATEST_OPTION="Darrers ítems dels usuaris o les categories" NR_ASSIGN_K2_TAG_OPTION="Etiquetar pàgina" NR_ASSIGN_K2_CATEGORY_OPTION="Pàgina de categories" NR_ASSIGN_K2_ITEM_FORM_OPTION="Ítem editar formulari" NR_ASSIGN_K2_USER_PAGE_OPTION="Pàgina d'usuari (blog)" NR_ASSIGN_K2_TAGS_DESC="Apunta als visitants que naveguen per ítems K2 amb etiquetes específiques" NR_ASSIGN_K2_CATEGORIES_DESC="Apunta als visitans que naveguen per categories K2 específiques" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Ítems" NR_ASSIGN_PAGE_TYPES_DESC="Escull els tipus de pàgines als que assignar" NR_ASSIGN_TAGS_DESC="Escull les etiquetes a les que assignar" NR_CONTENT_KEYWORDS="Paraules clau del contingut" NR_META_KEYWORDS="Meta paraules clau" NR_TAG="Etiqueta" NR_NORMAL="Normal" NR_COMPACT="Compacte" NR_LIGHT="Clar" NR_DARK="Fosc" NR_SIZE="Mida" NR_THEME="Tema" NR_SINGLE="Individual" NR_MULTIPLE="Múltiple" NR_RANGE="Interval" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Valida" NR_RECAPTCHA_INVALID_SECRET_KEY="Clau secreta invàlida" NR_PAGE="Pàgina" NR_YOU_ARE_USING_EXTENSION="Estàs utilitzant %s %s" NR_UPDATE="Actualitza" NR_SHOW_UPDATE_NOTIFICATION="Mostrar notificació d'actualització" NR_SHOW_UPDATE_NOTIFICATION_DESC="Si s'activa, es mostrarà una notificació d'actualització a la vista principal del component quan hi hagi una nova versió d'aquesta extensió." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s està disponible " NR_ERROR_EMAIL_IS_DISABLED="L'enviament de correu està desactivat. No s'han pogut enviar els correus electrònics." NR_ASSIGN_ITEMS="Ítem" NR_COUNTRY_AF="Afganistan" NR_COUNTRY_AX="Illes Aland" NR_COUNTRY_AL="Albània" NR_COUNTRY_DZ="Algèria" NR_COUNTRY_AS="Samoa Americana" NR_COUNTRY_AD="Andorra" NR_COUNTRY_AO="Angola" NR_COUNTRY_AI="Anguilla" NR_COUNTRY_AQ="Antàrtida" NR_COUNTRY_AG="Antigua i Barbuda" NR_COUNTRY_AR="Argentina" NR_COUNTRY_AM="Armènia" NR_COUNTRY_AW="Aruba" NR_COUNTRY_AU="Austràlia" NR_COUNTRY_AT="Àustria" NR_COUNTRY_AZ="Azerbaitjan" NR_COUNTRY_BS="Bahames" NR_COUNTRY_BH="Bahrain" NR_COUNTRY_BD="Bangla Desh" NR_COUNTRY_BB="Barbados" NR_COUNTRY_BY="Bielorússia" NR_COUNTRY_BE="Bèlgica" NR_COUNTRY_BZ="Belize" NR_COUNTRY_BJ="Benín" NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" NR_COUNTRY_BT="Bhutan" NR_COUNTRY_BO="Bolívia" NR_COUNTRY_BA="Bòsnia i Hercegovina" NR_COUNTRY_BW="Botswana" NR_COUNTRY_BV="Illa Bouvet" NR_COUNTRY_BR="Brasil" NR_COUNTRY_IO="Territori Britànic de l'Oceà Índic" NR_COUNTRY_BN="Brunei (Negara Brunei Darussalam)" NR_COUNTRY_BG="Bulgària" NR_COUNTRY_BF="Burkina Faso" NR_COUNTRY_BI="Burundi" NR_COUNTRY_KH="Cambodja" NR_COUNTRY_CM="Camerun" NR_COUNTRY_CA="Canadà" NR_COUNTRY_CV="Cap Verd" NR_COUNTRY_KY="Illes Caiman" NR_COUNTRY_CF="República Centreafricana" NR_COUNTRY_TD="Txad" NR_COUNTRY_CL="Xile" NR_COUNTRY_CN="Xina" NR_COUNTRY_CX="Illa Christmas" NR_COUNTRY_CC="Illes Cocos (Keeling)" NR_COUNTRY_CO="Colòmbia" NR_COUNTRY_KM="Comores" NR_COUNTRY_CG="Congo" NR_COUNTRY_CD="Congo, La República Democràtica del" NR_COUNTRY_CK="Illes Cook" NR_COUNTRY_CR="Costa Rica" NR_COUNTRY_CI="Costa de Vori" NR_COUNTRY_HR="Croàcia" NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Xipre" NR_COUNTRY_CZ="República Txeca" NR_COUNTRY_DK="Dinamarca" NR_COUNTRY_DJ="Djibouti" NR_COUNTRY_DM="Dominica" NR_COUNTRY_DO="República Dominicana" NR_COUNTRY_EC="Ecuador" NR_COUNTRY_EG="Egipte" NR_COUNTRY_SV="El Salvador" NR_COUNTRY_GQ="Guinea Equatorial" NR_COUNTRY_ER="Eritrea" NR_COUNTRY_EE="Estònia" NR_COUNTRY_ET="Etiòpia" NR_COUNTRY_FK="Illes Malvines (Falkland)" NR_COUNTRY_FO="Illes Fèroe" NR_COUNTRY_FJ="Fiji" NR_COUNTRY_FI="Finlàndia" NR_COUNTRY_FR="França" NR_COUNTRY_GF="Guaiana Francesa" NR_COUNTRY_PF="Polinèsia francesa" NR_COUNTRY_TF="erritoris Francesos del Sud" NR_COUNTRY_GA="Gabon" NR_COUNTRY_GM="Gàmbia" NR_COUNTRY_GE="Geòrgia" NR_COUNTRY_DE="Alemanya" NR_COUNTRY_GH="Ghana" NR_COUNTRY_GI="Gibraltar" NR_COUNTRY_GR="Grècia" NR_COUNTRY_GL="Groenlàndia" NR_COUNTRY_GD="Grenada" NR_COUNTRY_GP="Guadalupe" NR_COUNTRY_GU="Guam" NR_COUNTRY_GT="Guatemala" NR_COUNTRY_GG="Guernsey" NR_COUNTRY_GN="Guinea" NR_COUNTRY_GW="Guinea-Bissau" NR_COUNTRY_GY="Guyana" NR_COUNTRY_HT="Haití" NR_COUNTRY_HM="Illa Heard i Illes McDonald" NR_COUNTRY_VA="Santa Seu (Estat del Vaticà)" NR_COUNTRY_HN="Honduras" NR_COUNTRY_HK="Hong Kong" NR_COUNTRY_HU="Hongria" NR_COUNTRY_IS="Islàndia" NR_COUNTRY_IN="India" NR_COUNTRY_ID="Indonèsia" NR_COUNTRY_IR="República Islàmica de l'Iran" NR_COUNTRY_IQ="Iraq" NR_COUNTRY_IE="Irlanda" NR_COUNTRY_IM="Illa de Man" NR_COUNTRY_IL="Israel" NR_COUNTRY_IT="Itàlia" NR_COUNTRY_JM="Jamaica" NR_COUNTRY_JP="Japó" NR_COUNTRY_JE="Jersey" NR_COUNTRY_JO="Jordània" NR_COUNTRY_KZ="Kazakhstan" NR_COUNTRY_KE="Kenya" NR_COUNTRY_KI="Kiribati" NR_COUNTRY_KP="República Democràtica Popular de Corea" NR_COUNTRY_KR="Corea del Sud" NR_COUNTRY_KW="Kuwait" NR_COUNTRY_KG="Kirguizistan" NR_COUNTRY_LA="República Democràtica Popular de Laos" NR_COUNTRY_LV="Letònia" NR_COUNTRY_LB="Líban" NR_COUNTRY_LS="Lesotho" NR_COUNTRY_LR="Liberia" NR_COUNTRY_LY="Líbia" NR_COUNTRY_LI="Liechtenstein" NR_COUNTRY_LT="Lituània" NR_COUNTRY_LU="Luxemburg" NR_COUNTRY_MO="Macau" NR_COUNTRY_MK="Macedònia" NR_COUNTRY_MG="Madagascar" NR_COUNTRY_MW="Malawi" NR_COUNTRY_MY="Malàisia" NR_COUNTRY_MV="Maldives" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Malta" NR_COUNTRY_MH="Illes Marshall" NR_COUNTRY_MQ="Martinica" NR_COUNTRY_MR="Mauritania" NR_COUNTRY_MU="Maurici" NR_COUNTRY_YT="Mayotte" NR_COUNTRY_MX="Mexico" NR_COUNTRY_FM="Micronèsia, Estats Federats de" NR_COUNTRY_MD="Moldàvia, República de" NR_COUNTRY_MC="Mònaco" NR_COUNTRY_MN="Mongòlia" NR_COUNTRY_ME="Montenegro" NR_COUNTRY_MS="Montserrat" NR_COUNTRY_MA="Marroc" NR_COUNTRY_MZ="Moçambic" NR_COUNTRY_MM="Myanmar" NR_COUNTRY_NA="Namibia" NR_COUNTRY_NR="Nauru" NR_COUNTRY_NM="Macedònia nord" NR_COUNTRY_NP="Nepal" NR_COUNTRY_NL="Països Baixos" NR_COUNTRY_AN="Antilles Neerlandeses" NR_COUNTRY_NC="Nova Caledònia" NR_COUNTRY_NZ="Nova Zelanda" NR_COUNTRY_NI="Nicaragua" NR_COUNTRY_NE="Níger" NR_COUNTRY_NG="Nigèria" NR_COUNTRY_NU="Niue" NR_COUNTRY_NF="Illa Norfolk" NR_COUNTRY_MP="Illes Marianes del Nord" NR_COUNTRY_NO="Noruega" NR_COUNTRY_OM="Oman" NR_COUNTRY_PK="Pakistan" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Territori Palestí" NR_COUNTRY_PA="Panamà" NR_COUNTRY_PG="Papua Nova Guinea" NR_COUNTRY_PY="Paraguai" NR_COUNTRY_PE="Perú" NR_COUNTRY_PH="Filipines" NR_COUNTRY_PN="Pitcairn" NR_COUNTRY_PL="Polònia" NR_COUNTRY_PT="Portugal" NR_COUNTRY_PR="Puerto Rico" NR_COUNTRY_QA="Qatar" NR_COUNTRY_RE="Reunió" NR_COUNTRY_RO="Romania" NR_COUNTRY_RU="Federació Russa" NR_COUNTRY_RW="Rwanda" NR_COUNTRY_SH="Saint Helena" NR_COUNTRY_KN="Saint Christopher i Nevis" NR_COUNTRY_LC="Saint Lucia" NR_COUNTRY_PM="Saint Pierre and Miquelon" NR_COUNTRY_VC="Saint Vincent i les Grenadines" NR_COUNTRY_WS="Samoa" NR_COUNTRY_SM="San Marino" NR_COUNTRY_ST="Sao Tome i Príncipe" NR_COUNTRY_SA="Aràbia Saudita" NR_COUNTRY_SN="Senegal" NR_COUNTRY_RS="Sèrbia" NR_COUNTRY_SC="Seychelles" NR_COUNTRY_SL="Sierra Leone" NR_COUNTRY_SG="Singapur" NR_COUNTRY_SK="Eslovàquia" NR_COUNTRY_SI="Eslovènia" NR_COUNTRY_SB="Illes Salomó" NR_COUNTRY_SO="Somàlia" NR_COUNTRY_ZA="Sudàfrica" NR_COUNTRY_GS="Illes Geòrgia del Sud i Sandwich del Sud" NR_COUNTRY_ES="Espanya" NR_COUNTRY_LK="Sri Lanka" NR_COUNTRY_SD="Sudan" NR_COUNTRY_SS="Sudan del Sud" NR_COUNTRY_SR="Surinam" NR_COUNTRY_SJ="Svalbard i Jan Mayen" NR_COUNTRY_SZ="Swazilàndia" NR_COUNTRY_SE="Suècia" NR_COUNTRY_CH="Suïssa" NR_COUNTRY_SY="República Àrab Síria" NR_COUNTRY_TW="Taiwan" NR_COUNTRY_TJ="Tadjikistan" NR_COUNTRY_TZ="Tanzània, República Unida de" NR_COUNTRY_TH="Tailàndia" NR_COUNTRY_TL="Timor Oriental" NR_COUNTRY_TG="Togo" NR_COUNTRY_TK="Tokelau" NR_COUNTRY_TO="Tonga" NR_COUNTRY_TT="Trinitat i Tobago" NR_COUNTRY_TN="Tunísia" NR_COUNTRY_TR="Turquia" NR_COUNTRY_TM="Turkmenistan" NR_COUNTRY_TC="Illes Turks i Caicos" NR_COUNTRY_TV="Tuvalu" NR_COUNTRY_UG="Uganda" NR_COUNTRY_UA="Ucraïna" NR_COUNTRY_AE="Unió dels Emirats Àrabs" NR_COUNTRY_GB="Regne Unit" NR_COUNTRY_US="Estats Units" NR_COUNTRY_UM="lles Perifèriques Menors dels EUA" NR_COUNTRY_UY="Uruguai" NR_COUNTRY_UZ="Uzbekistan" NR_COUNTRY_VU="Vanuatu" NR_COUNTRY_VE="Veneçuela" NR_COUNTRY_VN="Vietnam" NR_COUNTRY_VG="lles Verges, Britàniques" NR_COUNTRY_VI="Illes Verges, EUA" NR_COUNTRY_WF="Wallis i Futuna" NR_COUNTRY_EH="Sàhara Occidental" NR_COUNTRY_YE="Iemen" NR_COUNTRY_ZM="Zàmbia" NR_COUNTRY_ZW="Zimbabwe" NR_CONTINENT_AF="Africa" NR_CONTINENT_AS="Asia" NR_CONTINENT_EU="Europa" NR_CONTINENT_NA="America del nord" NR_CONTINENT_SA="America del sud" NR_CONTINENT_OC="Oceania" NR_CONTINENT_AN="Antarctica" NR_FRONTEND="Part pública" NR_BACKEND="Administració" NR_EMBED="Incorporar" NR_RATE="Tasa %s" NR_REPORT_ISSUE="Informar d'un problema" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!vSSBsystem/nrframework/language/sl-SI/sl-SI.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Sistem - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - uporablja se z Tassos.gr razširitvami" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Prezri" NR_INCLUDE="Vključi" NR_EXCLUDE="Izključi" NR_SELECTION="Izbira" NR_ASSIGN_MENU_NOITEM="Vključi id postavke" NR_ASSIGN_MENU_NOITEM_DESC="Določite, kateri ne-menu se nastavi v URL-ju??" ; NR_ASSIGN_MENU_CHILD="Also on child items" ; NR_ASSIGN_MENU_CHILD_DESC="Also assign to child items of the selected items?" NR_COPY_OF="Kopija %s" ; NR_ASSIGN_DATETIME_DESC="Target visitors based on your server's datetime" NR_DATETIME="Datum, čas" ; NR_TIME="Time" ; NR_DATE="Date" NR_DATETIME_DESC="Vnesite datum in čas za samodejno objavljanje/prekinitev objave" ; NR_START_PUBLISHING="Start Datetime" NR_START_PUBLISHING_DESC="Vnesite začetni datum objave" ; NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="Vnesite končni datum objave" NR_DATETIME_NOTE="Datum in čas uporablja časovne nastavitve vašega strežnika in nastavitve obiskovalca." ; NR_ASSIGN_PHP="PHP" ; NR_PHPCODE="PHP Code" ; NR_ASSIGN_PHP_DESC="Enter a piece of PHP code to evaluate." ; NR_ASSIGN_PHP_DESC2="Target visitors evaluating custom PHP code. The code must return the value true or false.

For instance:
return ($user->name == 'Tassos Marinos');" ; NR_ASSIGN_TIMEONSITE="Time on Site" NR_SECONDS="Sekund" NR_ASSIGN_TIMEONSITE_DESC="Vnesite trajanje v sekundah za primerjavo z uporabnikovim skupnim časom (trajanje obiska), porabljen za celotno spletno stran.

Na primer:
Če želite po 3 minutnem obisku prikazati okno, potem vnesite 180." NR_ASSIGN_URLS="URL" ; NR_ASSIGN_URLS_DESC2="Target visitors who are browsing specific URLs" NR_ASSIGN_URLS_DESC="Vnesite (del) URL-jev za ujemanje.
Vsak URL v svojo vrstico" NR_ASSIGN_URLS_LIST="URL ujemanje" ; NR_ASSIGN_URLS_REGEX="Use Regular Expression" NR_ASSIGN_URLS_REGEX_DESC="Za obravnavo določite regularni izraz" ; NR_ASSIGN_LANGS="Language" ; NR_ASSIGN_LANGS_DESC="Target visitors who are browsing your website in specific language" NR_ASSIGN_LANGS_LIST_DESC="Določite jezik dodeljen za" ; NR_ASSIGN_DEVICES="Device" ; NR_ASSIGN_DEVICES_DESC2="Target visitors using specific device such as Mobile, Tablet or Desktop." NR_ASSIGN_DEVICES_DESC="Določite naprave." NR_ASSIGN_DEVICES_NOTE="Imejte v mislih, da odkrivanje naprav ni vedno 100% natančno. Uporabniki namreč lahko nastavijo brskalnik tako, da le ti posnemajo druge naprave." ; NR_MENU="Menu" ; NR_MENU_ITEMS="Menu Item" ; NR_MENU_ITEMS_DESC="Target visitors who are browsing specific menu items" ; NR_USERGROUP="User Group" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." ; NR_ACCESSLEVEL="User Group" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Prikaži avtorske pravice" NR_SHOW_COPYRIGHT_DESC="Če je izbrano, bodo avtorske pravice prikazane v administraciji. Razširitve Tassos.gr v ospredju nikoli ne prikazujejo avtorskih pravic in ne vsebujejo skritih reklamnih povezav." NR_WIDTH="Širina" NR_WIDTH_DESC="Vnesite širino v px, em ali %

Primer: 400px" NR_HEIGHT="Višina" NR_HEIGHT_DESC="Vnesite višino v px, em ali %

Primer 400px" NR_PADDING="Odmik" NR_PADDING_DESC="Vnesite odmik v px, em ali %

Primer: 20px" NR_MARGIN="Rob" ; NR_MARGIN_DESC="The CSS margin propertiy is used to generate space around the box and set the size of the white space outside the border in pixels or in %.

Example 1: 25px
Example 2: 5%

Specifying the margin for each side [top right bottom left]:

Top side only: 25px 0 0 0
Right side only: 0 25px 0 0
Bottom side only: 0 0 25px 0
Left side only: 0 0 0 25px" ; NR_COLOR_HOVER="Hover Color" NR_COLOR="Barva" NR_COLOR_DESC="Določite barvo v HEX ali RGBA formatu." NR_TEXT_COLOR="Barva besedila" ; NR_BACKGROUND="Background" NR_BACKGROUND_COLOR="Barva ozadja" NR_BACKGROUND_COLOR_DESC="Določite barvo ozadja v HEX ali RGBA formatu. Za onemogočanje vnesite 'none'. Za popolno prosojnost vnesite 'transparency'." NR_URL_SHORTENING_FAILED="Krajšanje %s z %s ni možno. %s." NR_EXPORT="Izvoz" NR_IMPORT="Uvoz" NR_PLEASE_CHOOSE_A_VALID_FILE="Določite pravilno ime datoteke" NR_IMPORT_ITEMS="Uvoz postavk" NR_PUBLISH_ITEMS="Objava postavk" NR_AS_EXPORTED="Kot izvozi" ; NR_TITLE="Title" NR_ACYMAILING="AcyMailing" ; NR_ACYMAILING_LIST="AcyMailing List" ; NR_ACYMAILING_LIST_DESC="Select AcyMailing lists to assign to." ; NR_ASSIGN_ACYMAILING_DESC="Target visitors who have subscribed to specific AcyMailing lists" NR_AKEEBASUBS="Akeeba naročnine" NR_AKEEBASUBS_LEVELS="Nivoji" ; NR_AKEEBASUBS_LEVELS_DESC="Select Akeeba Subscription levels to assign to." ; NR_ASSIGN_AKEEBASUBS_DESC="Target visitors who have subscribed to specific Akeeba Subscriptions" ; NR_MATCH="Match" ; NR_MATCH_DESC="The used matching method to compare the value" NR_ASSIGN_MATCHING_METHOD="Metoda primerjanja" NR_ASSIGN_MATCHING_METHOD_DESC="Ali se ujema?

Vse
Bo objavljeno če se VSEl od spodnjega ujema.

Karkoli
Bo objavljeno če se Karkoli (eno ali več) od spodnjega ujema.
Dodelitev skupinam, kjer je izbrano 'Prezri', bodo prezrte." NR_ANY="Karkoli" ; NR_ALL="All" ; NR_ASSIGN_REFERRER="Referrer URL" ; NR_ASSIGN_REFERRER_DESC2="Target visitors who land on your site from a specific traffic source" ; NR_ASSIGN_REFERRER_DESC="Enter one Referrer URL per line: Eg:

google.com
facebook.com/mypage" ; NR_ASSIGN_REFERRER_NOTE="Keep in mind that URL Referrer discovery is not always 100% accurate. Some servers may use proxies that strip this information out and it can be easily forged." ; NR_PROFEATURE_HEADER="%s is a PRO Feature" ; NR_PROFEATURE_DESC="We're sorry, %s is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features." ; NR_PROFEATURE_DISCOUNT="Bonus: %s free users get 20% off regular price, automatically applied at checkout." NR_ONLY_AVAILABLE_IN_PRO="Samo v PRO različici" NR_UPGRADE_TO_PRO="Nadgradi na PRO" ; NR_UPGRADE_TO_PRO_TO_UNLOCK="Upgrade to Pro version to unlock" ; NR_UPGRADE_TO_PRO_VERSION="Awesome! Only one step left. Click on the button below to complete the upgrade to the Pro version." ; NR_UNLOCK_PRO_FEATURE="Unlock Pro Feature" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="Z leve na desno" NR_RIGHT_TO_LEFT="Z desne na levo" NR_BGIMAGE="Slika ozadja" NR_BGIMAGE_DESC="Določite sliko ozadja" NR_BGIMAGE_FILE="Slika" NR_BGIMAGE_FILE_DESC="Izberite ali naložite sliko za ozadje" NR_BGIMAGE_REPEAT="Ponovi" NR_BGIMAGE_REPEAT_DESC="Določi, kako se bo slika ozadja ponavljala. Privzeto je, da se slika ponavlja v vodoravni in navpišni smeri.

Ponovi: Slika se bo ponavljala v navpični in vodoravni smeri.

Ponovi X: Slika se bo ponavljala samo v vodoravni smeri

Ponovi Y: Slika se bo ponavljala samo v navpični smeri

Brez ponavljanja: Slika ozadja se ne bo ponavljala." NR_BGIMAGE_SIZE="Velikost" NR_BGIMAGE_SIZE_DESC="Velikost slike za ozadje.

Samodejno: Slika uporablja svojo širino in višino

Prekrij: Slika bo popolnoma prekrila prostor za sliko ozadja. Nekateri deli ozadja ne bodo vidni

Okvir: Slika se bo prilagodila okvirju

100% 100%: Slika bo popolnoma prekrila prostor za prispevke" NR_BGIMAGE_POSITION="Pozicija" NR_BGIMAGE_POSITION_DESC="Pozicija slike za ozadje. Privzeto je, da se slika postavi v zgornji levi kot. Prva vrednost je vodoravna pozicija, druga pa navpična pozicija.

Lahko uporabite eno izmed naprej določenih vrednosti, ali pa vnesete svoje vrednosti v procentih: x% y% ali pa v pikslih xPoz yPoz." NR_RTL="Omogoči RTL" NR_RTL_DESC="Smer besedila z desne proti levi se uporablja le pri arabščini, hebrejščini, sirskih in Tana jezikih" NR_HORIZONTAL="Vodoravno" NR_VERTICAL="Navpično" NR_FORM_ORIENTATION="Smer obrazca" NR_FORM_ORIENTATION_DESC="Določite smer obrazca" NR_ASSIGN_CATEGORY="Kategorije" NR_ASSIGN_CATEGORY_DESC="Določite kategorije" NR_ASSIGN_CATEGORY_CHILD="Podrejene postavke" NR_ASSIGN_CATEGORY_CHILD_DESC="Dodeli podrejene postavke" NR_NEW="Nov" NR_LIST="Seznam" NR_DOCUMENTATION="Dokumentacija" ; NR_KNOWLEDGEBASE="Knowledgebase" NR_FAQ="Pogosta vprašanja" NR_INFORMATION="Informacija" NR_EXTENSION="Razširitev" NR_VERSION="Različica" NR_CHANGELOG="Dnevnik sprememb" ; NR_DOWNLOAD="Download" ; NR_DOWNLOAD_KEY_MISSING="Download Key is missing" NR_DOWNLOAD_KEY="Prenos ključa" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="Da omogočite posodobitve %s preko Joomla posodobitev, potem potrebujete svoj ključ za prenos, katerega vnesete v Novarain Framework vtičnik" NR_DOWNLOAD_KEY_FIND="Najdi ključ za prenos" NR_DOWNLOAD_KEY_UPDATE="Posodobi ključ za prenos" NR_OK="Vredu" NR_MISSING="Manjkajoče" NR_LICENSE="Licenca" NR_AUTHOR="Avtor" NR_FOLLOWME="Sledi mi" NR_FOLLOW="Sledi %s" NR_TRANSLATE_INTEREST="Nam želite pomagati pri prevodu %s v vaš jezik?" NR_TRANSIFEX_REQUEST="Pošljite zahtevek na Transifex" NR_HELP_WITH_TRANSLATIONS="Pomoč pri prevodih" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Napredno" NR_USEGLOBAL="Uporabi globalno" ; NR_WEEKDAY="Day of Week" ; NR_MONTH="Month" ; NR_MONDAY="Monday" ; NR_TUESDAY="Tuesday" ; NR_WEDNESDAY="Wednesday" ; NR_THURSDAY="Thursday" ; NR_FRIDAY="Friday" ; NR_SATURDAY="Saturday" ; NR_WEEKEND="Weekend" ; NR_WEEKDAYS="Weekdays" ; NR_SUNDAY="Sunday" ; NR_JANUARY="January" ; NR_FEBRUARY="February" ; NR_MARCH="March" ; NR_APRIL="April" ; NR_MAY="May" ; NR_JUNE="June" ; NR_JULY="July" ; NR_AUGUST="August" ; NR_SEPTEMBER="September" ; NR_OCTOBER="October" ; NR_NOVEMBER="November" ; NR_DECEMBER="December" NR_NEVER="Nikoli" NR_SECONDS="Sekund" NR_MINUTES="Minute" NR_HOURS="Ure" NR_DAYS="Dnevi" NR_SESSION="Seja" NR_EVER="Vedno" NR_COOKIE="Piškotek" NR_BOTH="Oboje" NR_NONE="Nič" ; NR_NONE_SELECTED="None Selected" ; NR_DESKTOPS="Desktop" ; NR_MOBILES="Mobile" ; NR_TABLETS="Tablet" NR_PER_SESSION="Na sejo" NR_PER_DAY="Na dan" NR_PER_WEEK="Na vikend" NR_PER_MONTH="Na mesec" NR_FOREVER="Vedno" NR_FEATURE_UNDER_DEV="Ta funkcija je v fazi razvoja" ; NR_LIKE_THIS_EXTENSION="Like this extension?" ; NR_LEAVE_A_REVIEW="Leave a review on JED" ; NR_SUPPORT="Support" ; NR_NEED_SUPPORT="Need support?" ; NR_DROP_EMAIL="Drop me an e-mail" ; NR_READ_DOCUMENTATION="Read the Documentation" ; NR_COPYRIGHT="%s - Tassos.gr All Rights Reserved" ; NR_DASHBOARD="Dashboard" ; NR_NAME="Name" ; NR_WRONG_COORDINATES="The coordinates you provided are not valid" ; NR_ENTER_COORDINATES="Latitude,Longitude" ; NR_NO_ITEMS_FOUND="No Items Found" ; NR_ITEM_IDS="No Item IDs" ; NR_TOGGLE="Toggle" ; NR_EXPAND="Expand" ; NR_COLLAPSE="Collapse" ; NR_SELECTED="Selected" ; NR_MAXIMIZE="Maximize" ; NR_MINIMIZE="Minimize" NR_SELECTION="Izbira" ; NR_INSTALL="Install" ; NR_INSTALL_NOW="Install Now" ; NR_INSTALLED="Installed" ; NR_COMING_SOON="Coming soon" ; NR_ROADMAP="On the roadmap" ; NR_MEDIA_VERSIONING="Use Media Versioning" ; NR_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." ; NR_LOAD_JQUERY="Load jQuery" ; NR_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." ; NR_SELECT_CURRENCY="Select a Currency" ; NR_CONVERTFORMS="Convert Forms" ; NR_CONVERTFORMS_LIST="Campaign" ; NR_ASSIGN_CONVERTFORMS_DESC="Target visitors who have subscribed to specific ConvertForms campaigns" ; NR_CONVERTFORMS_LIST_DESC="Select ConvertForms campaigns to assign to." ; NR_LEFT="Left" ; NR_CENTER="Center" ; NR_RIGHT="Right" ; NR_BOTTOM="Bottom" ; NR_TOP="Top" ; NR_AUTO="Auto" ; NR_CUSTOM="Custom" ; NR_UPLOAD="Upload" ; NR_IMAGE="Image" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" ; NR_IMAGE_SELECT="Select Image" ; NR_IMAGE_SIZE_COVER="Cover" ; NR_IMAGE_SIZE_CONTAIN="Contain" ; NR_REPEAT="Repeat" ; NR_REPEAT_X="Repeat x" ; NR_REPEAT_Y="Repeat y" ; NR_REPEAT_NO="No repeat" ; NR_FIELD_STATE_DESC="Set item's state" ; NR_CREATED_DATE="Created Date" ; NR_CREATED_DATE_DESC="The date the item was created" ; NR_MODIFIFED_DATE="Modified Date" ; NR_MODIFIFED_DATE_DESC="The date that the item was last modified." ; NR_CATEGORIES="Category" ; NR_CATEGORIES_DESC="Select the categories to assign to." ; NR_ALSO_ON_CHILD_ITEMS="Also on child items" ; NR_ALSO_ON_CHILD_ITEMS_DESC="Also assign to child items of the selected items?" ; NR_PAGE_TYPE="Page type" ; NR_PAGE_TYPES="Page types" ; NR_PAGE_TYPES_DESC="Select on what page types the assignment should be active." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" ; NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" ; NR_CATEGORY_VIEW="Category View" ; NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." ; NR_ARTICLES="Articles" ; NR_ARTICLES_DESC="Select the articles to assign to." ; NR_ARTICLE="Article" ; NR_ARTICLE_AUTHORS="Authors" ; NR_ARTICLE_AUTHORS_DESC="Select the authors to assign to." ; NR_ONLY="Only" ; NR_OTHERS="Others" ; NR_SMARTTAGS="Smart Tags" ; NR_SMARTTAGS_SHOW="Show Smart Tags" ; NR_SMARTTAGS_NOTFOUND="No Smart Tags found" ; NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" ; NR_CONTACT_US="Contact us" ; NR_FONT_COLOR="Font Color" ; NR_FONT_SIZE="Font Size" ; NR_FONT_SIZE_DESC="Choose a font size in pixels" ; NR_TEXT="Text" ; NR_URL="URL" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE="Enable on Output Override" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Enables the extension rendering when the page layout (tmpl) is overriden. Examples: tmpl=component or tmpl=modal." ; NR_EXECUTE_ON_FORMAT_OVERRIDE="Enable on Format Override" ; NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Enables the extension rendering when the page format is not other than HTML. Examples: format=raw or format=json." ; NR_GEOLOCATING="Geolocating" ; NR_GEOLOCATION="Geolocation" ; NR_GEOLOCATING_DESC="Geolocating is not always 100% accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known." ; NR_CITY="City" ; NR_CITY_NAME="City Name" ; NR_CONDITION_CITY_DESC="Enter a city name in English. Enter multiple cities separated by comma." ; NR_CONTINENT="Continent" ; NR_REGION="Region" ; NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." ; NR_ASSIGN_COUNTRIES="Country" ; NR_ASSIGN_COUNTRIES_DESC2="Target visitors who are physically in a specific country" ; NR_ASSIGN_COUNTRIES_DESC="Select the countries to assign to" ; NR_ASSIGN_CONTINENTS="Continent" ; NR_ASSIGN_CONTINENTS_DESC="Select the continents to assign to" ; NR_ASSIGN_CONTINENTS_DESC2="Target visitors who are physically in a specific continent" ; NR_ICONTACT_ACCOUNTID_ERROR="The iContact AccountID could not be retrieved" ; NR_TAG_CLIENTDEVICE="Visitor Device Type" ; NR_TAG_CLIENTOS="Visitor Operating System" ; NR_TAG_CLIENTBROWSER="Visitor Browser" ; NR_TAG_CLIENTUSERAGENT="Visitor Agent String" ; NR_TAG_IP="Visitor IP Address" ; NR_TAG_URL="Page URL" ; NR_TAG_URLENCODED="Page URL Encoded" ; NR_TAG_URLPATH="Page Path" ; NR_TAG_REFERRER="Page Referrer" ; NR_TAG_SITENAME="Site Name" ; NR_TAG_SITEURL="Site URL" ; NR_TAG_PAGETITLE="Page Title" ; NR_TAG_PAGEDESC="Page Meta Description" ; NR_TAG_PAGELANG="Page Language Code" ; NR_TAG_USERID="User ID" ; NR_TAG_USERNAME="User Full Name" ; NR_TAG_USERLOGIN="User Login" ; NR_TAG_USEREMAIL="User Email" ; NR_TAG_USERFIRSTNAME="User First Name" ; NR_TAG_USERLASTNAME="User Last Name" ; NR_TAG_USERGROUPS="User Groups IDs" ; NR_TAG_DATE="Date" ; NR_TAG_TIME="Time" ; NR_TAG_RANDOMID="Random ID" ; NR_ICON="Icon" ; NR_SELECT_MODULE="Select a Module" ; NR_SELECT_CONTINENT="Select a Continent" ; NR_SELECT_COUNTRY="Select a Country" ; NR_PLUGIN="Plugin" ; NR_GMAP_KEY="Google Maps API Key" ; NR_GMAP_KEY_DESC="The Google Maps API Key is being used by Tassos.gr extensions. If you face any troubles with a Google Map not being loaded then you probably need to enter your own API Key." ; NR_GMAP_FIND_KEY="Get an API key" ; NR_ARE_YOU_SURE="Are you sure?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" ; NR_CUSTOMURL="Custom URL" ; NR_SAMPLE="Sample" ; NR_DEBUG="Debug" ; NR_CUSTOMURL="Custom URL" ; NR_READMORE="Read More" ; NR_IPADDRESS="IP Address" ; NR_ASSIGN_BROWSERS="Browser" ; NR_ASSIGN_BROWSERS_DESC="Select the browsers to assign to" ; NR_ASSIGN_BROWSERS_DESC2="Target visitors who are browsing your site with specific browsers such as Chrome, Firefox or Internet Explorer" ; NR_CHROME="Chrome" ; NR_FIREFOX="Firefox" ; NR_EDGE="Edge" ; NR_IE="Internet Explorer" ; NR_SAFARI="Safari" ; NR_OPERA="Opera" ; NR_ASSIGN_OS="Operating System" ; NR_ASSIGN_OS_DESC="Select the operating systems to assign to" ; NR_ASSIGN_OS_DESC2="Target visitors who are using specific operating systems such as Windows, Linux or Mac" ; NR_LINUX="Linux" ; NR_MAC="MacOS" ; NR_ANDROID="Android" ; NR_IOS="iOS" ; NR_WINDOWS="Windows" ; NR_BLACKBERRY="Blackberry" ; NR_CHROMEOS="Chrome OS" ; NR_ASSIGN_PAGEVIEWS="Number of Pageviews" ; NR_ASSIGN_PAGEVIEWS_DESC="Target visitors who have viewed certain number of pages" ; NR_ASSIGN_PAGEVIEWS_VIEWS="Pageviews" ; NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Enter the number of page views" ; NR_ASSIGN_COOKIENAME_NAME="Cookie Name" ; NR_ASSIGN_COOKIENAME_NAME_DESC="Enter the name of the cookie to assign to" ; NR_ASSIGN_COOKIENAME_NAME_DESC2="Target visitors who have specific cookies stored in their browser" ; NR_FEWER_THAN="Fewer than" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" ; NR_GREATER_THAN="Greater than" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" ; NR_EXACTLY="Exactly" ; NR_EXISTS="Exists" ; NR_NOT_EXISTS="Does not exists" ; NR_IS_EQUAL="Equals" ; NR_DOES_NOT_EQUAL="Does not equal" ; NR_CONTAINS="Contains" ; NR_DOES_NOT_CONTAIN="Does not contain" ; NR_STARTS_WITH="Starts with" ; NR_DOES_NOT_START_WITH="Does not start with" ; NR_ENDS_WITH="Ends with" ; NR_DOES_NOT_END_WITH="Does not end with" ; NR_ASSIGN_COOKIENAME_CONTENT="Cookie Content" ; NR_ASSIGN_COOKIENAME_CONTENT_DESC="The cookie's content" ; NR_ASSIGN_IP_ADDRESSES_DESC2="Target visitors who are behind a specific IP address (range)" ; NR_ASSIGN_IP_ADDRESSES_DESC="Enter a list of comma and/or 'enter' separated ip addresses and ranges

Example:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." ; NR_ASSIGN_USER_ID="User ID" ; NR_ASSIGN_USER_ID_DESC="Target specific Joomla Users by their IDs" ; NR_ASSIGN_USER_ID_SELECTION_DESC="Enter comma separated Joomla user IDs" ; NR_ASSIGN_COMPONENTS="Component" ; NR_ASSIGN_COMPONENTS_DESC="Select the components to assign to" ; NR_ASSIGN_COMPONENTS_DESC2="Target visitors who are browsing specific components" ; NR_ASSIGN_TIMERANGE="Time Range" ; NR_ASSIGN_TIMERANGE_DESC="Target visitors based on your server's time" ; NR_START_TIME="Start Time" ; NR_END_TIME="End Time" ; NR_START_PUBLISHING_TIMERANGE_DESC="Enter the time to start publishing" ; NR_FINISH_PUBLISHING_TIMERANGE_DESC="Enter the time to end publishing" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." ; NR_RECAPTCHA_SITE_KEY="Site Key" ; NR_RECAPTCHA_SITE_KEY_DESC="Used in the JavaScript code that is served to your users." ; NR_RECAPTCHA_SECRET_KEY="Secret Key" ; NR_RECAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret." ; NR_RECAPTCHA_SITE_KEY_ERROR="The reCaptcha Site Key is either missing or invalid" ; NR_PREVIOUS_MONTH="Previous Month" ; NR_NEXT_MONTH="Next Month" ; NR_ASSIGN_GROUP_PAGE_URL="Page / URL" ; NR_ASSIGN_GROUP_PAGE_URL_DESC="Target visitors who are browsing specific menu items or URLs" ; NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" ; NR_ASSIGN_GROUP_USER_VISITOR="Joomla User / Visitor" ; NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" ; NR_ASSIGN_GROUP_PLATFORM="Visitor Platform" ; NR_ASSIGN_GROUP_PLATFORM_DESC="Target visitors who are using Mobile, Google Chrome, or even Windows" ; NR_ASSIGN_GROUP_GEO_DESC="Target visitors who are physically in a specific region" ; NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" ; NR_ASSIGN_GROUP_JCONTENT_DESC="Target visitors who are viewing specific Joomla articles or categories" ; NR_ASSIGN_GROUP_SYSTEM="System / Integrations" ; NR_INTEGRATIONS="Integrations" ; NR_ASSIGN_GROUP_SYSTEM_DESC="Target visitors who have interacted with specific 3rd party Joomla Extensions" ; NR_ASSIGN_GROUP_ADVANCED="Advanced visitor targeting" ; NR_ASSIGN_USERGROUP_DESC="Target specific Joomla user groups" ; NR_ASSIGN_ARTICLE_DESC="Target visitors who are viewing specific Joomla articles" ; NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target visitors who are viewing specific Joomla categories" ; NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." ; NR_ASSIGN_K2="K2" ; NR_ASSIGN_K2_DESC="Target visitors who are browsing specific K2 Items, Categories or Tags" ; NR_ASSIGN_K2_ITEMS="Item" ; NR_ASSIGN_K2_ITEMS_DESC="Target visitors who are browsing specific K2 items." ; NR_ASSIGN_K2_ITEMS_LIST_DESC="Select the K2 Items to assign to" ; NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Match on specific keywords in the item's content. Seperate by a comma or a new line." ; NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Match on the item's meta keywords. Seperate by a comma or a new line." ; NR_ASSIGN_K2_PAGETYPES_DESC="Target visitors who are browsing specific K2 page types" ; NR_ASSIGN_K2_ITEM_OPTION="Item" ; NR_ASSIGN_K2_LATEST_OPTION="Latest items from users or categories" ; NR_ASSIGN_K2_TAG_OPTION="Tag Page" ; NR_ASSIGN_K2_CATEGORY_OPTION="Category Page" ; NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Edit Form" ; NR_ASSIGN_K2_USER_PAGE_OPTION="User Page (blog)" ; NR_ASSIGN_K2_TAGS_DESC="Target visitors who are browsing K2 items with specific tags" ; NR_ASSIGN_K2_CATEGORIES_DESC="Target visitors who are browsing specific K2 categories" ; NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" ; NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" ; NR_ASSIGN_PAGE_TYPES_DESC="Select the page types to assign to" ; NR_ASSIGN_TAGS_DESC="Select the tags to assign to" ; NR_CONTENT_KEYWORDS="Content keywords" ; NR_META_KEYWORDS="Meta keywords" ; NR_TAG="Tag" ; NR_NORMAL="Normal" ; NR_COMPACT="Compact" ; NR_LIGHT="Light" ; NR_DARK="Dark" ; NR_SIZE="Size" ; NR_THEME="Theme" ; NR_SINGLE="Single" ; NR_MULTIPLE="Multiple" ; NR_RANGE="Range" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_PLEASE_VALIDATE="Please validate" ; NR_RECAPTCHA_INVALID_SECRET_KEY="Invalid secret key" ; NR_PAGE="Page" ; NR_YOU_ARE_USING_EXTENSION="You are using %s %s" ; NR_UPDATE="Update" ; NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" ; NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." ; NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!gBsystem/nrframework/language/pt-BR/pt-BR.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Sistema - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - usado pelas extensões Tassos.gr" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignorar" NR_INCLUDE="Incluir" NR_EXCLUDE="Excluir" NR_SELECTION="Seleção" NR_ASSIGN_MENU_NOITEM="Incluir Sem Itemid" NR_ASSIGN_MENU_NOITEM_DESC="Também atribuir quando nenhum Itemid do menu for definido na URL?" NR_ASSIGN_MENU_CHILD="Também em itens filhos" NR_ASSIGN_MENU_CHILD_DESC="Atribuir também aos itens filhos dos itens selecionados?" NR_COPY_OF="Copiar de %s" NR_ASSIGN_DATETIME_DESC="Segmentar visitantes com base na data e hora do seu servidor" NR_DATETIME="Data/Hora" NR_TIME="Hora" NR_DATE="Data" NR_DATETIME_DESC="Digite a data e hora para publicar/despublicar." NR_START_PUBLISHING="Data/Hora Inicial" NR_START_PUBLISHING_DESC="Digite a data para iniciar a publicação." ; NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="Digite a data para finalizar a publicação." NR_DATETIME_NOTE="As atribuições de data e hora usa a data/hora de seus servidores, não do sistema dos visitantes." NR_ASSIGN_PHP="PHP Personalizado" NR_PHPCODE="Código PHP" NR_ASSIGN_PHP_DESC="Digite um pedaço de código PHP para avaliar." NR_ASSIGN_PHP_DESC2="Segmentar visitantes avaliando o código PHP personalizado. O código deve retornar o valor verdadeiro ou false.

Por exemplo:
retorna ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Hora no site" NR_SECONDS="Segundos" NR_ASSIGN_TIMEONSITE_DESC="Digite uma duração em segundos para comparar com a hora total do usuário (duração da visita) gasto em todo o seu site.

Exemplo:
Se você deseja exibir uma caixa após o usuário tiver gasto 3 minutos no seu site inteiro, digite 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Segmentar visitantes que estão navegando por URLs específicos." NR_ASSIGN_URLS_DESC="Digite (parte da) a URLs para corresponder.
Use uma nova linha para cada correspondência diferente." NR_ASSIGN_URLS_LIST="Correspondência de URL" NR_ASSIGN_URLS_REGEX="Usar Expressão Regular" NR_ASSIGN_URLS_REGEX_DESC="Selecione para tratar o valor como expressões regulares." NR_ASSIGN_LANGS="Idioma" NR_ASSIGN_LANGS_DESC="Segmentar visitantes que estão navegando em seu website em um idioma específico." NR_ASSIGN_LANGS_LIST_DESC="Selecione o Idioma para atribuir." NR_ASSIGN_DEVICES="Dispositivo" NR_ASSIGN_DEVICES_DESC2="Segmentar visitantes usando um dispositivo específico, como celular, tablet ou computador." NR_ASSIGN_DEVICES_DESC="Selecione os dispositivos para atribuir." NR_ASSIGN_DEVICES_NOTE="Tenha em mente que a detecção de dispositivos nem sempre é 100% precisa. Os usuários podem configurar seu navegador para imitar outros dispositivos." NR_MENU="Menu" NR_MENU_ITEMS="Item de Menu" NR_MENU_ITEMS_DESC="Segmentar visitantes que estão navegando em itens de menu específicos" NR_USERGROUP="Grupo de Usuário" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Grupo de Usuários" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Exibir Copyright" NR_SHOW_COPYRIGHT_DESC="Se selecionado, informações extras sobre direitos autorais serão exibidas nas visualizações do admin. As extensões Tassos.gr nunca exibe as informações de copyright ou links de retorno no frontend." NR_WIDTH="Largura" NR_WIDTH_DESC="Digite a largura em px, em ou %

Exemplo: 400px" NR_HEIGHT="Altura" NR_HEIGHT_DESC="Digite a altura em px, em or %

Exemplo: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Digite o padding em px, em ou %

Exemplo: 20px" NR_MARGIN="Margem" NR_MARGIN_DESC="A propriedade de margem CSS é usada para gerar espaço ao redor da caixa e definir o tamanho do espaço em branco fora da borda em pixels ou em %.

Exemplo 1: 25px
Exemplo 2: 5%

Especificando a margem para cada lado [superior direita inferior esquerda]:

Apenas lado superior: 25px 0 0 0
Apenas lado direito: 0 25px 0 0
Apenas lado inferior: 0 0 25px 0
Apenas lado esquerdo: 0 0 0 25px" NR_COLOR_HOVER="Cor ao Passar o Mouse" NR_COLOR="Cor" NR_COLOR_DESC="Defina uma cor no formato HEX ou RGBA." NR_TEXT_COLOR="Cor do Texto" NR_BACKGROUND="Fundo" NR_BACKGROUND_COLOR="Cor de Fundo" NR_BACKGROUND_COLOR_DESC="Defina uma cor de fundo em formato HEX ou RGBA. Para desativar digite 'none'. Para transper~encia absoluta digite 'transparent'." NR_URL_SHORTENING_FAILED="Shortening %s com %s falhou. %s." NR_EXPORT="Exportar" NR_IMPORT="Importar" NR_PLEASE_CHOOSE_A_VALID_FILE="Por favor, escolha um nome de arquivo válido." NR_IMPORT_ITEMS="Importar Itens" NR_PUBLISH_ITEMS="Publicar Itens" NR_AS_EXPORTED="Como exportado" NR_TITLE="Título" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="Listas" NR_ACYMAILING_LIST_DESC="Selecione listas AcyMailing para atribuir." NR_ASSIGN_ACYMAILING_DESC="Segmentar visitantes inscritos em listas específicas do AcyMailing." NR_AKEEBASUBS="Akeeba Subscriptions" NR_AKEEBASUBS_LEVELS="Níveis" NR_AKEEBASUBS_LEVELS_DESC="Selecione os níveis de Assinatura Akeeba para atribuir." NR_ASSIGN_AKEEBASUBS_DESC="Segmentar visitantes inscritos em Assinaturas Akeeba específicas." NR_MATCH="Corresponder" NR_MATCH_DESC="O método de correspondência usado para comparar o valor." NR_ASSIGN_MATCHING_METHOD="Método de Correspondência" NR_ASSIGN_MATCHING_METHOD_DESC="Todas as atribuições devem ser correspondidas?

Todas
será publicada se Todas as atribuições abaixo são correspondentes.

Qualquer
será publicada se Qualquer (uma ou mais) das atribuições abaixo são correspondentes.
Grupos de atribuição onde 'Ignorar' está selecionado será ignorado." NR_ANY="Qualquer" ; NR_ALL="All" NR_ASSIGN_REFERRER="URL do Referenciador" NR_ASSIGN_REFERRER_DESC2="Segmentar visitantes que chegam ao seu site de uma fonte de tráfego específica." NR_ASSIGN_REFERRER_DESC="Digite um URL de referenciador por linha: Ex:

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Lembre-se de que a descoberta do referenciador de URL nem sempre é 100% precisa. Alguns servidores podem usar proxies que retiram essa informação e podem ser facilmente forjados." NR_PROFEATURE_HEADER="%s é um Recurso PRO" NR_PROFEATURE_DESC="Nós lamentamos, %s não está disponível no seu plano. Por favor, atualize para o plano PRO para desbloquear todos esses recursos impressionantes." NR_PROFEATURE_DISCOUNT="Bônus: %s usuários gratuitos recebem 20% preço normal, aplicado automaticamente no checkout." NR_ONLY_AVAILABLE_IN_PRO="Apenas disponível na versão PRO" NR_UPGRADE_TO_PRO="Atualizar para Pro" NR_UPGRADE_TO_PRO_TO_UNLOCK="Atualizar para versão Pro para desbloquear" NR_UPGRADE_TO_PRO_VERSION="Fantástico! Só falta um passo. Clique no botão abaixo para completar a atualização para a versão Pro." NR_UNLOCK_PRO_FEATURE="Desbloquear Recurso Pro" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="Esquerda para Direita" NR_RIGHT_TO_LEFT="Direita para Esquerda" NR_BGIMAGE="Imagem de Fundo" NR_BGIMAGE_DESC="Defina a imagem de fundo." NR_BGIMAGE_FILE="Imagem" NR_BGIMAGE_FILE_DESC="Selecione ou carregue um arquivo para o background-image." NR_BGIMAGE_REPEAT="Repetir" NR_BGIMAGE_REPEAT_DESC="A propriedade background-repeat define se/como uma imagem de fundo será repetida. Por padrão, uma background-image é repetida vertical e horizontalmente.

Repeat: A imagem de fundo será repetida tanto na vertical como na horizontal.

Repeat-x: A imagem de fundo será repetida apenas horizontalmente

Repeat-y: A imagem de fundo será repetida apenas verticalmente

No-repeat: A imagem de fundo não será repetida." NR_BGIMAGE_SIZE="Tamanho" NR_BGIMAGE_SIZE_DESC="Especifique o tamanho de uma imagem de fundo.

Auto: A background-image contém a sua largura e altura

Cover: Dimensiona a imagem de fundo para ser o maior possível para que a área de fundo seja completamente coberta pela imagem de fundo. Algumas partes da imagem de fundo podem não estar visíveis dentro da área de posicionamento de fundo

Contain: Dimensiona a imagem para o tamanho maior, de forma que a largura e a altura possam se ajustar dentro da área de conteúdo

100% 100%: Estique a imagem de plano de fundo para cobrir completamente a área de conteúdo." NR_BGIMAGE_POSITION="Posição" NR_BGIMAGE_POSITION_DESC="A propriedade background-position define a posição inicial de uma imagem de fundo. Por padrão, uma background-image é colocada no canto superior esquerdo. O primeiro valor é a posição horizontal e o segundo valor é a posição vertical.

Você pode usar um dos valores predefinidos ou inserir um valor personalizado em porcentagem: x% y% ou em pixel xPos yPos." NR_RTL="Ativar RTL" NR_RTL_DESC="A direção do texto da direita para a esquerda é essencial para scripts da direita para a esquerda, como Árabe, Hebraico, Siríaco e Thaana." NR_HORIZONTAL="Horizontal" NR_VERTICAL="Vertical" NR_FORM_ORIENTATION="Orientação do Formulário" NR_FORM_ORIENTATION_DESC="Selecione a orientação do formulário." NR_ASSIGN_CATEGORY="Categorias" NR_ASSIGN_CATEGORY_DESC="Selecione as categorias para atribuir." NR_ASSIGN_CATEGORY_CHILD="Também em Itens Filhos" NR_ASSIGN_CATEGORY_CHILD_DESC="Também atribuir para itens filhos dos itens selecionados?" NR_NEW="Novo" NR_LIST="Lista" NR_DOCUMENTATION="Documentação" NR_KNOWLEDGEBASE="Base de Conhecimento" NR_FAQ="FAQ" NR_INFORMATION="Informação" NR_EXTENSION="Extensão" NR_VERSION="Versão" NR_CHANGELOG="Changelog" ; NR_DOWNLOAD="Download" ; NR_DOWNLOAD_KEY_MISSING="Download Key is missing" NR_DOWNLOAD_KEY="Chave de Download" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="Para ser capaz de atualizar %s via o atualizador do Joomla, você precisará digitar sua Chave de Download nas configurações do Plugin Novarain Framework." NR_DOWNLOAD_KEY_FIND="Encontrar a Chave de Download" NR_DOWNLOAD_KEY_UPDATE="Atualizar Chave de Download" NR_OK="OK" NR_MISSING="Faltando" NR_LICENSE="Licença" NR_AUTHOR="Autor" NR_FOLLOWME="Siga-me" NR_FOLLOW="Siga %s" NR_TRANSLATE_INTEREST="Você estaria interessado em ajudar com a tradução do %s para o seu Idioma?" NR_TRANSIFEX_REQUEST="Envie-me um pedido no Transifex" NR_HELP_WITH_TRANSLATIONS="Ajuda com Traduções" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Avançado" NR_USEGLOBAL="Usar Global" NR_WEEKDAY="Dia da Semana" NR_MONTH="Mês" NR_MONDAY="Segunda" NR_TUESDAY="Terça" NR_WEDNESDAY="Quarta" NR_THURSDAY="Quinta" NR_FRIDAY="Sexta" NR_SATURDAY="Sábado" NR_WEEKEND="Final de Semana" NR_WEEKDAYS="Finais de Semanas" NR_SUNDAY="Domingo" NR_JANUARY="Janeiro" NR_FEBRUARY="Fevereiro" NR_MARCH="Março" NR_APRIL="Abril" NR_MAY="Maio" NR_JUNE="Junho" NR_JULY="Julho" NR_AUGUST="Agosto" NR_SEPTEMBER="Setembro" NR_OCTOBER="Outubro" NR_NOVEMBER="Novembro" NR_DECEMBER="Dezembro" NR_NEVER="Nunca" NR_SECONDS="Segundos" NR_MINUTES="Minutos" NR_HOURS="Horas" NR_DAYS="Dias" NR_SESSION="Sessão" NR_EVER="Sempre" NR_COOKIE="Cookie" NR_BOTH="Ambos" NR_NONE="Nenhum" ; NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Computador" NR_MOBILES="Celular" NR_TABLETS="Tablet" NR_PER_SESSION="Por Sessão" NR_PER_DAY="Por Dia" NR_PER_WEEK="Por Semana" NR_PER_MONTH="Por Mês" NR_FOREVER="Para Sempre" NR_FEATURE_UNDER_DEV="Este recurso está em desenvolvimento" NR_LIKE_THIS_EXTENSION="Curtir esta extensão?" NR_LEAVE_A_REVIEW="Deixe um comentário no JED" NR_SUPPORT="Suporte" NR_NEED_SUPPORT="Precisa de suporte?" NR_DROP_EMAIL="Me envie um e-mail" NR_READ_DOCUMENTATION="Ler a Documentação" NR_COPYRIGHT="%s - Tassos.gr Todos os Direitos Reservados" NR_DASHBOARD="Painel" NR_NAME="Nome" NR_WRONG_COORDINATES="As coordenadas que você forneceu não são válidas!" NR_ENTER_COORDINATES="Latitude, Longitude" NR_NO_ITEMS_FOUND="Nenhum Item Foi Encontrado!" NR_ITEM_IDS="Nenhum IDs de Item" NR_TOGGLE="Alternar" NR_EXPAND="Expandir" NR_COLLAPSE="Recolher" NR_SELECTED="Selecionado" NR_MAXIMIZE="Maximizar" NR_MINIMIZE="Minimizar" NR_SELECTION="Seleção" NR_INSTALL="Instalar" NR_INSTALL_NOW="Instalar Agora" NR_INSTALLED="Instalado" NR_COMING_SOON="Em breve" NR_ROADMAP="No roteiro" NR_MEDIA_VERSIONING="Usar Versão de Mídia" NR_MEDIA_VERSIONING_DESC="Selecione para adicionar o número da versão da extensão ao final da urls de mídia (js/css), para fazer os navegadores forçar o carregamento do arquivo correto." NR_LOAD_JQUERY="Carregar jQuery" NR_LOAD_JQUERY_DESC="Selecione para carregar o script do core do jQuery. Você pode desativar isso se você tiver conflitos se seu template ou outras extensões carregarem sua própria versão do jQuery." NR_SELECT_CURRENCY="Selecionar a Moeda" NR_CONVERTFORMS="Formulários de Conversão" NR_CONVERTFORMS_LIST="Campanhas" NR_ASSIGN_CONVERTFORMS_DESC="Segmente os visitantes que se inscreveram em campanhas específicas do Formulários de Conversão." NR_CONVERTFORMS_LIST_DESC="Selecione campanhas do Formulários de Conversão para atribuir." NR_LEFT="Esquerda" NR_CENTER="Centro" NR_RIGHT="Direita" NR_BOTTOM="Rodapé" NR_TOP="Topo" NR_AUTO="Auto" NR_CUSTOM="Personalizar" NR_UPLOAD="Carregar" NR_IMAGE="Imagem" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" NR_IMAGE_SELECT="Selecionar Imagem" NR_IMAGE_SIZE_COVER="Capa" NR_IMAGE_SIZE_CONTAIN="Contém" NR_REPEAT="Repetir" NR_REPEAT_X="Repetir x" NR_REPEAT_Y="Repetir y" NR_REPEAT_NO="Não repetir" NR_FIELD_STATE_DESC="Defina o estado do item." NR_CREATED_DATE="Data de Criação" NR_CREATED_DATE_DESC="A data em que o item foi criado." NR_MODIFIFED_DATE="Data de Modificação" NR_MODIFIFED_DATE_DESC="A data que o item foi modificado pela última vez." NR_CATEGORIES="Categoria" NR_CATEGORIES_DESC="Selecione as categorias para o trabalho." NR_ALSO_ON_CHILD_ITEMS="Também nos itens do tema pendente" NR_ALSO_ON_CHILD_ITEMS_DESC="Também atribuir os itens selecionados aos itens pendentes?" NR_PAGE_TYPE="Tipo de página" NR_PAGE_TYPES="Tipos de páginas" NR_PAGE_TYPES_DESC="Selecione quais os tipos de páginas que serão ativados no trabalho." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" NR_ARTICLE_VIEW_DESC="Ativar para levar em conta a visualização do artigo." NR_CATEGORY_VIEW="Visualização da Categoria" NR_CATEGORY_VIEW_DESC="Ativar para levar em conta a visualização de categoria." ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Artigos" NR_ARTICLES_DESC="Selecione os artigos designados" NR_ARTICLE="Artigo" NR_ARTICLE_AUTHORS="Autor" NR_ARTICLE_AUTHORS_DESC="Escolha o autor designado" NR_ONLY="Somente" NR_OTHERS="outros" NR_SMARTTAGS="Tags Inteligente" NR_SMARTTAGS_SHOW="Mostrar Smart Tags" NR_SMARTTAGS_NOTFOUND="Nenhuma Tags Inteligente foi encontrada!" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Pesquisar por Tags Inteligente" NR_CONTACT_US="Entre em contato conosco." NR_FONT_COLOR="Seleção de cor" NR_FONT_SIZE="Seleção do tamanho da fonte" NR_FONT_SIZE_DESC="Escolha o tamanho da fonte em Pixel" NR_TEXT="Texto" NR_URL="Endereço da Web" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Ativar na Substituição de Saída" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Ativa a renderização da extensão quando o layout da página (tmpl) é substituído. Exemplos: tmpl=component ou tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Ativar na Substituição de Formato" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Ativa a renderização da extensão quando o formato da página não é diferente de HTML. Exemplos: format=raw ou format=json." NR_GEOLOCATING="Geolocalização" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="A geolocalização nem sempre é 100% precisa. A geolocalização é baseada no endereço IP do visitante. Nem todos os endereços IP são fixos ou conhecidos." NR_CITY="Cidade" NR_CITY_NAME="Nome da Cidade" NR_CONDITION_CITY_DESC="Digite o nome da cidade em inglês. Insira várias cidades separadas por vírgula." NR_CONTINENT="Continente" NR_REGION="Região" NR_CONDITION_REGION_DESC="O valor consiste em duas partes, o código de país de duas letras ISO 3166-1 e o código de região. Portanto, o valor deve estar no seguinte formato: COUNTRY_CODE-REGION_CODE. Para obter uma lista completa de códigos de região, clique no link Localizar um código de região." NR_ASSIGN_COUNTRIES="País" NR_ASSIGN_COUNTRIES_DESC2="Segmentar visitantes que estão fisicamente em um país específico." NR_ASSIGN_COUNTRIES_DESC="Selecione os países para atribuir." NR_ASSIGN_CONTINENTS="Continente" NR_ASSIGN_CONTINENTS_DESC="Selecione os continentes para atribuir." NR_ASSIGN_CONTINENTS_DESC2="Segmentar visitantes que estão fisicamente em um continente específico." NR_ICONTACT_ACCOUNTID_ERROR="O ID da conta do iContact não pôde ser recuperado!" NR_TAG_CLIENTDEVICE="Tipo de Dispositivo do Visitante" NR_TAG_CLIENTOS="Sistema Operacional Visitante" NR_TAG_CLIENTBROWSER="Navegador do Visitante" NR_TAG_CLIENTUSERAGENT="String do Agente do Visitante" NR_TAG_IP="Endereço IP do Visitante" NR_TAG_URL="URL da Página" NR_TAG_URLENCODED="URL da Página Codificada" NR_TAG_URLPATH="Caminho da Página" NR_TAG_REFERRER="Referenciador de Página" NR_TAG_SITENAME="Nome do Site" NR_TAG_SITEURL="URL do Site" NR_TAG_PAGETITLE="Título da Página" NR_TAG_PAGEDESC="Descrição Meta da Página" NR_TAG_PAGELANG="Código do Idioma da Página" NR_TAG_USERID="ID do Usuário" NR_TAG_USERNAME="Nome Completo do Usuário" NR_TAG_USERLOGIN="Login do Usuário" NR_TAG_USEREMAIL="E-mail do Usuário" NR_TAG_USERFIRSTNAME="Primeiro Nome do Usuário" NR_TAG_USERLASTNAME="Sobrenome do Usuário" NR_TAG_USERGROUPS="IDs dos Grupos de Usuário" NR_TAG_DATE="Data" NR_TAG_TIME="Hora" NR_TAG_RANDOMID="ID Aleatório" NR_ICON="Ícone" NR_SELECT_MODULE="Selecione um Módulo" NR_SELECT_CONTINENT="Selecione um Continente" NR_SELECT_COUNTRY="Selecione um País" NR_PLUGIN="Plugin" NR_GMAP_KEY="Chave API do Google Maps" NR_GMAP_KEY_DESC="A chave API do Google Maps API está sendo usado por extensões Tassos.gr. Se você enfrentar algum problema com o Google Map não sendo carregado, provavelmente precisará inserir sua própria chave de API." NR_GMAP_FIND_KEY="Obter uma chave API" NR_ARE_YOU_SURE="Você tem certeza?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="URL Personalizada" NR_SAMPLE="Exemplo" NR_DEBUG="Depurar" NR_CUSTOMURL="URL Personalizada" NR_READMORE="Leia Mais" NR_IPADDRESS="Endereço de IP" NR_ASSIGN_BROWSERS="Navegador" NR_ASSIGN_BROWSERS_DESC="Selecione os navegadores para atribuir." NR_ASSIGN_BROWSERS_DESC2="Segmentar visitantes que estão navegando em seu site com navegadores específicos, como Chrome, Firefox ou Internet Explorer." NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Sistema Operacional" NR_ASSIGN_OS_DESC="Selecione os sistemas operacionais para atribuir." NR_ASSIGN_OS_DESC2="Segmente os visitantes que estão usando sistemas operacionais específicos, como Windows, Linux ou Mac." NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Número de Exibições de Página" NR_ASSIGN_PAGEVIEWS_DESC="Segmentar visitantes que visualizaram determinado número de páginas" NR_ASSIGN_PAGEVIEWS_VIEWS="Exibições de Página" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Digite o número de visualizações de página." NR_ASSIGN_COOKIENAME_NAME="Nome do Cookie" NR_ASSIGN_COOKIENAME_NAME_DESC="Digite o nome do cookie para atribuir." NR_ASSIGN_COOKIENAME_NAME_DESC2="Segmentar visitantes que possuem cookies específicos armazenados em seus navegadores." NR_FEWER_THAN="Menor que" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="Maior que" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Exatamente" NR_EXISTS="Existe" ; NR_NOT_EXISTS="Does not exists" NR_IS_EQUAL="É Igual" ; NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Contém" ; NR_DOES_NOT_CONTAIN="Does not contain" NR_STARTS_WITH="Inicia com" ; NR_DOES_NOT_START_WITH="Does not start with" NR_ENDS_WITH="Termina com" ; NR_DOES_NOT_END_WITH="Does not end with" NR_ASSIGN_COOKIENAME_CONTENT="Conteúdo do Cookie" NR_ASSIGN_COOKIENAME_CONTENT_DESC="O conteúdo do cookie." NR_ASSIGN_IP_ADDRESSES_DESC2="Segmentar visitantes que estão por trás de um endereço IP específico (intervalo)." NR_ASSIGN_IP_ADDRESSES_DESC="Digite uma lista de endereços de IP e intervalos separados por vírgula e/ou 'enter'

Exemplo:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="ID do Usuário" NR_ASSIGN_USER_ID_DESC="Segmentar usuários específicos do Joomla por seus IDs." NR_ASSIGN_USER_ID_SELECTION_DESC="Digite IDs de usuário do Joomla separados por vírgula." NR_ASSIGN_COMPONENTS="Componente" NR_ASSIGN_COMPONENTS_DESC="Selecione os componentes para atribuir." NR_ASSIGN_COMPONENTS_DESC2="Segmentar visitantes que estão navegando em componentes específicos." NR_ASSIGN_TIMERANGE="Intervalo de Tempo" NR_ASSIGN_TIMERANGE_DESC="Segmentar visitantes com base no horário do seu servidor." NR_START_TIME="Hora Inicial" NR_END_TIME="Hora Final" NR_START_PUBLISHING_TIMERANGE_DESC="Digite o horário para iniciar a publicação." NR_FINISH_PUBLISHING_TIMERANGE_DESC="Digite o horário para finalizar a publicação" NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Chave do Site" NR_RECAPTCHA_SITE_KEY_DESC="Usado no código JavaScript que é servido para seus usuários." NR_RECAPTCHA_SECRET_KEY="Chave Secreta" NR_RECAPTCHA_SECRET_KEY_DESC="Usado na comunicação entre seu servidor e o servidor reCAPTCHA. Certifique-se de manter isso em segredo." NR_RECAPTCHA_SITE_KEY_ERROR="A chave do site reCaptcha está ausente ou é inválida" NR_PREVIOUS_MONTH="Mês Anterior" NR_NEXT_MONTH="Próximo Mês" NR_ASSIGN_GROUP_PAGE_URL="Página / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Segmentar visitantes que estão navegando por itens de menu ou URLs específicos." NR_ASSIGN_GROUP_DATETIME_DESC="Aciona uma caixa com base na data e hora do seu servidor" NR_ASSIGN_GROUP_USER_VISITOR="Usuário do Joomla / Visitante" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Segmente usuários registrados ou visitantes que visualizaram um determinado número de páginas." NR_ASSIGN_GROUP_PLATFORM="Plataforma do Visitante" NR_ASSIGN_GROUP_PLATFORM_DESC="Segmente os visitantes que estão usando o celular, o Google Chrome ou até o Windows." NR_ASSIGN_GROUP_GEO_DESC="Segmentar visitantes que estão fisicamente em uma região específica" NR_ASSIGN_GROUP_JCONTENT="Conteúdo do Joomla!" NR_ASSIGN_GROUP_JCONTENT_DESC="Segmentar visitantes que estão visualizando artigos ou categorias específicas do Joomla" NR_ASSIGN_GROUP_SYSTEM="Sistema / Integrações" ; NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Segmentar visitantes que interagiram com extensões do Joomla de terceiros específicas." NR_ASSIGN_GROUP_ADVANCED="Segmentação avançada por visitante" NR_ASSIGN_USERGROUP_DESC="Segmentar grupos de usuários específicos do Joomla." NR_ASSIGN_ARTICLE_DESC="Segmentar visitantes que estão visualizando artigos específicos do Joomla." NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Segmentar visitantes que estão visualizando categorias específicas do Joomla." NR_EXTENSION_REQUIRED="%s requer %s para ser ativado, a fim de funcionar corretamente." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Segmentar visitantes que estão navegando por itens, categorias ou tags específicos do K2." NR_ASSIGN_K2_ITEMS="Item" NR_ASSIGN_K2_ITEMS_DESC="Segmentar visitantes que estão navegando em itens específicos do K2." NR_ASSIGN_K2_ITEMS_LIST_DESC="Selecione os itens do K2 para atribuir." NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Corresponder palavras-chave específicas no conteúdo do item. Separado por uma vírgula ou uma nova linha." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Corresponder às meta palavras-chave do item. Separado por uma vírgula ou por uma nova linha." NR_ASSIGN_K2_PAGETYPES_DESC="Segmentar visitantes que estão navegando por tipos de página específicos do K2" NR_ASSIGN_K2_ITEM_OPTION="Item" NR_ASSIGN_K2_LATEST_OPTION="Últimos itens de usuários ou categorias" NR_ASSIGN_K2_TAG_OPTION="Página de Tag" NR_ASSIGN_K2_CATEGORY_OPTION="Página de Categoria" NR_ASSIGN_K2_ITEM_FORM_OPTION="Formulário de Edição de Item" NR_ASSIGN_K2_USER_PAGE_OPTION="Página do Usuário (blog)" NR_ASSIGN_K2_TAGS_DESC="Segmentar visitantes que estão navegando em itens do K2 com tags específicas." NR_ASSIGN_K2_CATEGORIES_DESC="Segmentar visitantes que estão navegando em categorias específicas do K2" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categorias" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Itens" NR_ASSIGN_PAGE_TYPES_DESC="Selecione os tipos de página para atribuir." NR_ASSIGN_TAGS_DESC="Selecione as tags para atribuir." NR_CONTENT_KEYWORDS="Palavras-chave do Conteúdo" NR_META_KEYWORDS="Palavras-chave Meta" NR_TAG="Tag" NR_NORMAL="Normal" NR_COMPACT="Compacto" NR_LIGHT="Claro" NR_DARK="Escuro" NR_SIZE="Tamanho" NR_THEME="Tema" NR_SINGLE="Único" NR_MULTIPLE="Vários" NR_RANGE="Intervalo" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Por favor, valide" NR_RECAPTCHA_INVALID_SECRET_KEY="Chave secreta inválida" NR_PAGE="Página" NR_YOU_ARE_USING_EXTENSION="Você está usando %s %s" NR_UPDATE="Atualizar" NR_SHOW_UPDATE_NOTIFICATION="Exibir Notificação de Atualização Update Notification" NR_SHOW_UPDATE_NOTIFICATION_DESC="Se selecionado, uma notificação de atualização será mostrada na visualização do componente principal quando houver uma nova versão para essa extensão." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s está disponível" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!6Bsystem/nrframework/language/bg-BG/bg-BG.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Системни - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework – използва се от Tassos.gr разширенията" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Игнориране" NR_INCLUDE="Включване" NR_EXCLUDE="Изключване" NR_SELECTION="Избор" NR_ASSIGN_MENU_NOITEM="Не включва ID" NR_ASSIGN_MENU_NOITEM_DESC="Присвоява също и когато в URL адреса няма ID меню?" NR_ASSIGN_MENU_CHILD="Също и върху дъщерни елементи " NR_ASSIGN_MENU_CHILD_DESC="Също да присвои ли и на вложените елементи избраното меню?" NR_COPY_OF="Копие на %s" NR_ASSIGN_DATETIME_DESC="Целево насочване на посетителите въз основа на дата и час на вашия сървър" NR_DATETIME="Дата и час" NR_TIME="Час" NR_DATE="Дата" NR_DATETIME_DESC="Въведете датата за автоматично публикуване / отмяна на публикуването" NR_START_PUBLISHING="Време начало" NR_START_PUBLISHING_DESC="Въведете датата и/или час, за начало на публикуването" ; NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="Въведете дата и/или час за край на публикуването" NR_DATETIME_NOTE="За дата и час използват стойностите от вашия сървър, а не тази на системете на посетителите." NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP код" NR_ASSIGN_PHP_DESC="Въведете фрагмнт от PHP кода за проверка." NR_ASSIGN_PHP_DESC2="Целево насочено към потребители, оценяващ произволен PHP код. Кодът трябва да връща стойност true или false.

Например:
return ($ user-> name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Време на сайта" NR_SECONDS="Секунди" NR_ASSIGN_TIMEONSITE_DESC="Въведете продължителност в секунди, за да сравните с общото време на потребителя (продължителност на посещението), прекарано на целия ви сайт.

Пример:
Ако искате да покажете поле, след като потребителят е прекарал 3 минути на целия ви сайт, въведете 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Проследяване посетители, които разглеждат конкретни URL адреси" NR_ASSIGN_URLS_DESC="Въведете (част от) URL адреси, за сравнение.
Използвайте нов ред за всяко съвпадение." NR_ASSIGN_URLS_LIST="URL съвпадения" NR_ASSIGN_URLS_REGEX="Използване Regular Expression" NR_ASSIGN_URLS_REGEX_DESC="Изберете, за да третирате стойността като регулярен израз, regular expressions." NR_ASSIGN_LANGS="Език" NR_ASSIGN_LANGS_DESC="Таргетирайте посетителите, които разглеждат уебсайта Ви на конкретен език" NR_ASSIGN_LANGS_LIST_DESC="Изберете езици" NR_ASSIGN_DEVICES="Устройство" NR_ASSIGN_DEVICES_DESC2="Целево селектиране на потребители, които използват определени устройства, като мобилни, таблети или настолни." NR_ASSIGN_DEVICES_DESC="Изберете устройства" NR_ASSIGN_DEVICES_NOTE="Имайте предвид, че откриването по устройството не винаги е 100% точно. Потребителите могат да настроят браузъра си, за да имитират други устройства" NR_MENU="Меню" NR_MENU_ITEMS="Меню елемент" NR_MENU_ITEMS_DESC="Целево селектиране на посетители, които разглеждат конкретни меню елементи" NR_USERGROUP="Група потребители" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Група потребители" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Показва авторски права" NR_SHOW_COPYRIGHT_DESC="Ако е избрана, информация за авторските права ще се показва в изгледите на администраторския панел. Разширенията на Tassos.gr никога не показват информация за авторското право или обратни връзки в сайта." NR_WIDTH="Ширина" NR_WIDTH_DESC="Въведете ширина в px, em или %

Пример: 400px" NR_HEIGHT="Височина" NR_HEIGHT_DESC="Въведете височина в px, em или %

Пример: 400px" NR_PADDING="Отстъп" NR_PADDING_DESC="Въведете отстъп в px, em или %

Пример: 20px" NR_MARGIN="Поле" NR_MARGIN_DESC="CSS стил за поле 'margin' за генериране на пространство около блока. Задаване на размера на бялото пространство на полето в пиксели или в %.

Пример 1: 25px
Пример 2: 5%

Посочване на полето за всяка страна [горе вдясно долу вляво]:

Само горна страна: 25px 0 0 0
Само дясна страна: 0 25px 0 0
Само от долната страна: 0 0 25px 0
Само от лявата страна: 0 0 0 25px" NR_COLOR_HOVER="Цвят при 'hover'" NR_COLOR="Цвят" NR_COLOR_DESC="Определете цвят за 'hover' в HEX или RGBA формат. Появява се при задръжан курсор на мишката." NR_TEXT_COLOR="Цвят на текста" NR_BACKGROUND="Фон" NR_BACKGROUND_COLOR="Цвят на фона" NR_BACKGROUND_COLOR_DESC="Определете цвят на фона във формат HEX или RGBA. За да деактивирате въведете 'none'. За пълна прозрачност въведете 'transparent'." NR_URL_SHORTENING_FAILED="Съкращаването на %s с %s е неуспешно. %s," NR_EXPORT="Експорт" NR_IMPORT="Импорт" NR_PLEASE_CHOOSE_A_VALID_FILE="Моля, изберете валидно файлово име" NR_IMPORT_ITEMS="Импорт на елементи" NR_PUBLISH_ITEMS="Публикуване на елементи" NR_AS_EXPORTED="Както е експортирано" NR_TITLE="Заглавие" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="AcyMailing списък" NR_ACYMAILING_LIST_DESC="Изберете AcyMailing списъци, в които да присвоите." NR_ASSIGN_ACYMAILING_DESC="Таргетирайте посетители, които са се абонирали за орледелени списъци на AcyMailing" NR_AKEEBASUBS="Абонаменти за Akeeba" NR_AKEEBASUBS_LEVELS="Нива" NR_AKEEBASUBS_LEVELS_DESC="Изберете ниво на Akeeba абонаменти, към което да абонирате." NR_ASSIGN_AKEEBASUBS_DESC="Таргетира посетителите, които са се абонирали за конкретни Akeeba абонаменти" NR_MATCH="Съвпадение" NR_MATCH_DESC="Използваният метод на съвпадение за сравняване" NR_ASSIGN_MATCHING_METHOD="Метод на съвпадение" NR_ASSIGN_MATCHING_METHOD_DESC="Трябва ли всички или каквито и да било задания да бъдат съпоставени?

Всички
ще бъдат публикувани, ако всички по-долу задания са съвпадащи.

Всички
ще бъдат публикувани, ако се съвпадат всякакви (една или повече) по-долу зададените.
Групите за задаване, където е избрано „Игнориране“, ще бъдат игнорирани." NR_ANY="Който и да е" ; NR_ALL="All" NR_ASSIGN_REFERRER="Референтен URL адрес" NR_ASSIGN_REFERRER_DESC2="Таргетирайте посетителите, които идват на Вашия сайт от конкретен източник на трафик" NR_ASSIGN_REFERRER_DESC="Въведете по един референтен URL адрес на ред: Например:

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Имайте предвид, че откриването на референтен URL не винаги е 100% точно. Някои сървъри могат да използват прокси, които премахват тази информация или тя може лесно да бъде подправена." NR_PROFEATURE_HEADER="%s е PRO функция" NR_PROFEATURE_DESC="За съжаление, %s не е във вашия план. Моля, надстройте до PRO плана, за да отключите тези функции." NR_PROFEATURE_DISCOUNT="Бонус: %s ползвателите на безплатен план получават 20% отспъпка от редовната цена, която автоматично се прилага при плащане." NR_ONLY_AVAILABLE_IN_PRO="Предлага се само в PRO версия" NR_UPGRADE_TO_PRO="Надстройка до Pro" NR_UPGRADE_TO_PRO_TO_UNLOCK="Надстройте до Pro версия за отключване" NR_UPGRADE_TO_PRO_VERSION="Страхотно! Остава само една стъпка. Щракнете върху бутона по-долу, за да завършите надстройката до Pro версията." NR_UNLOCK_PRO_FEATURE="Отключи Pro функция" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="Отляво надясно" NR_RIGHT_TO_LEFT="От дясно на ляво" NR_BGIMAGE="Фоново изображение" NR_BGIMAGE_DESC="Задава фоново изображение" NR_BGIMAGE_FILE="Изображение" NR_BGIMAGE_FILE_DESC="Изберете или качете файл за фоновото изображение." NR_BGIMAGE_REPEAT="Повторение" NR_BGIMAGE_REPEAT_DESC="Свойството background-repeat задава, ако / или как ще се повтори фоновото изображение. По подразбиране фоновото изображение се повтаря както вертикално, така и хоризонтално.

Повторение: фоновото изображение ще се повтори вертикално и хоризонтално.

Повторение-x: Фоновото изображение ще се повтори само хоризонтално.

Повторение-у: Фоновото изображение ще се повтори само вертикално.

Без-Повторение: фоновото изображение няма да се повтаря." NR_BGIMAGE_SIZE="Размер" NR_BGIMAGE_SIZE_DESC="Задайте размера на фоновото изображение.

Авто: Фоновото изображение с неговата ширина и височина.

Покритие: Мащабиране на фоновото изображение, така че фоновата област да бъде изцяло покрита от него. Някои части от фоновото изображение може да не се виждат.
Контейнер: Мащабирайте изображението по такъв начин, че неговите ширина и височина да се вместят във видимата област.

100% 100%: Разтегляне на фоновото изображение до пълно покриете областта на съдържанието." NR_BGIMAGE_POSITION="Позиция" NR_BGIMAGE_POSITION_DESC="Свойството background-position, задава началната позиция на фоново изображение. По подразбиране фоновото изображение се поставя в горния ляв ъгъл. Първата стойност е хоризонталното положение, а втората - вертикалното.

Можете да използвате някоя от предварително зададените стойности или да въведете собствени в проценти: x% y% или в пиксели xPos yPos." NR_RTL="Активиране на RTL" NR_RTL_DESC="Посоката на четене на текста отдясно наляво е от съществено значение за езици като арабски, иврит, сирийски и таана." NR_HORIZONTAL="Хоризонтално" NR_VERTICAL="Вертиикално" NR_FORM_ORIENTATION="Ориентация на формуляра" NR_FORM_ORIENTATION_DESC="Изберете ориентация на формуляра" NR_ASSIGN_CATEGORY="Категории" NR_ASSIGN_CATEGORY_DESC="Изберете категории" NR_ASSIGN_CATEGORY_CHILD="Също за дъщерни елементи" NR_ASSIGN_CATEGORY_CHILD_DESC="Също така да се присвои ли избор и на дъщерните елементи?" NR_NEW="Нов" NR_LIST="Списък" NR_DOCUMENTATION="Документация" NR_KNOWLEDGEBASE="База знания" NR_FAQ="FAQ" NR_INFORMATION="Информация" NR_EXTENSION="Разширение" NR_VERSION="Версия" NR_CHANGELOG="Дневник на промените" ; NR_DOWNLOAD="Download" NR_DOWNLOAD_KEY_MISSING="Ключът за изтегляне липсва" NR_DOWNLOAD_KEY="Ключ за изтегляне" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="За да можете да актуализирате %s чрез актуализатора на Joomla, ще трябва да въведете своя Ключ за изтегляне в настройките на Novarain Framework Plugin разширението." NR_DOWNLOAD_KEY_FIND="Намери Ключ за изтегляне" NR_DOWNLOAD_KEY_UPDATE="Обновяване на Ключа за изтегляне" NR_OK="OK" NR_MISSING="Липсва" NR_LICENSE="Лиценз" NR_AUTHOR="Автор" NR_FOLLOWME="Следвайте ме" NR_FOLLOW="Следвай %s" NR_TRANSLATE_INTEREST="Бихте ли се интересували да помогнете с превода на %s на вашия език?" NR_TRANSIFEX_REQUEST="Изпратете запитване на Transifex" NR_HELP_WITH_TRANSLATIONS="Помощ при преводи" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Разширени" NR_USEGLOBAL="Използва Глобални" NR_WEEKDAY="Ден от седмицата" NR_MONTH="Месец" NR_MONDAY="Понеделник" NR_TUESDAY="Вторник" NR_WEDNESDAY="Сряда" NR_THURSDAY="Четвъртък" NR_FRIDAY="Петък" NR_SATURDAY="Събота" NR_WEEKEND="Събота и Неделя" NR_WEEKDAYS="Делнични дни" NR_SUNDAY="Неделя" NR_JANUARY="Януари" NR_FEBRUARY="Февруари" NR_MARCH="Март" NR_APRIL="Април" NR_MAY="Май" NR_JUNE="Юни" NR_JULY="Юли" NR_AUGUST="Август" NR_SEPTEMBER="Септември" NR_OCTOBER="Октомври" NR_NOVEMBER="Ноември" NR_DECEMBER="Декември" NR_NEVER="Никога" NR_SECONDS="Секунди" NR_MINUTES="Минути" NR_HOURS="Часове" NR_DAYS="Дни" NR_SESSION="Сесия" NR_EVER="Винаги" NR_COOKIE="Биствитка" NR_BOTH="И двете" NR_NONE="Нищо" ; NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Декстоп" NR_MOBILES="Мобилен" NR_TABLETS="Таблет" NR_PER_SESSION="В сесия" NR_PER_DAY="На ден" NR_PER_WEEK="В седмица" NR_PER_MONTH="За месец" NR_FOREVER="Завинаги" NR_FEATURE_UNDER_DEV="Тази опция е в процес на разработка" NR_LIKE_THIS_EXTENSION="Харесва ли ви това разширение?" NR_LEAVE_A_REVIEW="Оставете отзив в JED" NR_SUPPORT="Поддръжка" NR_NEED_SUPPORT="Нуждаете се от поддръжка?" NR_DROP_EMAIL="Пишете ми по имейл" NR_READ_DOCUMENTATION="Прочетете документацията" NR_COPYRIGHT="%s – Tassos.gr Всички права запазени" NR_DASHBOARD="Табло" NR_NAME="Име" NR_WRONG_COORDINATES="Координатите, които сте предоставили, са невалидни" NR_ENTER_COORDINATES="Ширина, дължина" NR_NO_ITEMS_FOUND="Няма намерени елементи" NR_ITEM_IDS="Няма ID-та на елементи" NR_TOGGLE="Превключване" NR_EXPAND="Разтваряне" NR_COLLAPSE="Свиване" NR_SELECTED="Избрани" NR_MAXIMIZE="Максимизиране" NR_MINIMIZE="Минимизиране" NR_SELECTION="Избор" NR_INSTALL="Инсталиране" NR_INSTALL_NOW="Инсталирай сега" NR_INSTALLED="Инсталирано" NR_COMING_SOON="Очаквайте скоро" NR_ROADMAP="Планирано" NR_MEDIA_VERSIONING="Използвайте Медия версии" NR_MEDIA_VERSIONING_DESC="Изберете, за да добавите номер на версията в края на медийните (js/css) URL адреси, за да накарате браузърите да заредят правилния файл." NR_LOAD_JQUERY="Зарежда jQuery" NR_LOAD_JQUERY_DESC="Изберете, за да заредите core jQuery script. Можете да деактивирате това, ако с Вашия шаблон имате конфликти, или други разширения зареждат собствена версия на jQuery." NR_SELECT_CURRENCY="Изберете валута" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Кампания" NR_ASSIGN_CONVERTFORMS_DESC="Целево селектира посетителите, които са се абонирали за конкретни ConvertForms кампании " NR_CONVERTFORMS_LIST_DESC="Изберете ConvertForms кампании за назначаване." NR_LEFT="Ляво" NR_CENTER="Център" NR_RIGHT="Дясно" NR_BOTTOM="Долу" NR_TOP="Горе" NR_AUTO="Автоматично" NR_CUSTOM="Персонализиран" NR_UPLOAD="Качване" NR_IMAGE="Изображение" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" NR_IMAGE_SELECT="Избери изображение" NR_IMAGE_SIZE_COVER="Обложка" NR_IMAGE_SIZE_CONTAIN="Съдържа" NR_REPEAT="Повторение" NR_REPEAT_X="Повторение по Х" NR_REPEAT_Y="Повторение по У" NR_REPEAT_NO="Без повторение" NR_FIELD_STATE_DESC="Задаване състояние на елемента" NR_CREATED_DATE="Дата на създаване" NR_CREATED_DATE_DESC="Датата, на която елементът е създаден" NR_MODIFIFED_DATE="Дата на промяна" NR_MODIFIFED_DATE_DESC="Датата, на която елементът е последно променен." NR_CATEGORIES="Категория" NR_CATEGORIES_DESC="Изберете категориите, в които да присвоите." NR_ALSO_ON_CHILD_ITEMS="Също и върху дъщерни елементи " NR_ALSO_ON_CHILD_ITEMS_DESC="Да се присвои ли също така и на вложените дъщерни елементи?" NR_PAGE_TYPE="Тип страница" NR_PAGE_TYPES="Типове страници" NR_PAGE_TYPES_DESC="Изберете на кои типове страници назначаването да е активно." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" NR_CATEGORY_VIEW="Изглед на категория" NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Статии" NR_ARTICLES_DESC="Изберете статиите, към които да назначите." NR_ARTICLE="Статия" NR_ARTICLE_AUTHORS="Автори" NR_ARTICLE_AUTHORS_DESC="Изберете авторите, към които да назначите." NR_ONLY="Само" NR_OTHERS="Други" NR_SMARTTAGS="Умни тагове" NR_SMARTTAGS_SHOW="Покажи Умни тагове" NR_SMARTTAGS_NOTFOUND="Не са открити Умни тагове" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Търси за Умни тагове" NR_CONTACT_US="Свържете се с нас" NR_FONT_COLOR="Цвят на шрифта" NR_FONT_SIZE="Размер на шрифта" NR_FONT_SIZE_DESC="Изберете размер на шрифта в пиксели" NR_TEXT="Текст" NR_URL="URL адрес" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Активиране на предефиниране на изхода" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Разрешава изобразяването, когато оформлението на страницата (tmpl) е предефинирано и презаписано. Примери: tmpl=component or tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Активиране при предефинирането на формата" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Активира изобразяването на данни, когато форматът на страницата не е само от HTML. Примери: format=raw or format=json.." NR_GEOLOCATING="Геолокация" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="Геолокацията не винаги е 100% точна. Геолокацията се базира на IP адреса на посетителя. Не всички IP адреси са фиксирани или известни." NR_CITY="Град" NR_CITY_NAME="Име на град" NR_CONDITION_CITY_DESC="Въведете име на град на английски. За въвеждане на повече градове, разделете ги със запетая." NR_CONTINENT="Континент" NR_REGION="Област" NR_CONDITION_REGION_DESC="Стойността се състои от две части, двубуквеният код на ISO 3166-1 и регионалния код. Така че стойността трябва да бъде в следната форма: COUNTRY_CODE–REGION_CODE. За пълен списък с кодове на региони щракнете върху връзката Намери регионален код." NR_ASSIGN_COUNTRIES="Страна" NR_ASSIGN_COUNTRIES_DESC2="Селектира посетители, които са физически в конкретна държава" NR_ASSIGN_COUNTRIES_DESC="Изберете държави" NR_ASSIGN_CONTINENTS="Континент" NR_ASSIGN_CONTINENTS_DESC="Изберете континенти" NR_ASSIGN_CONTINENTS_DESC2="Целево селектира посетители, които са физически на определен континент" NR_ICONTACT_ACCOUNTID_ERROR="IContact AccountID не може да бъде извлечен" NR_TAG_CLIENTDEVICE="Тип устройство на посетителя" NR_TAG_CLIENTOS="Операционна система на посетителя" NR_TAG_CLIENTBROWSER="Браузър на посетителя" NR_TAG_CLIENTUSERAGENT="Visitor Agent String" NR_TAG_IP="IP Address на посетителя" NR_TAG_URL="URL адрес на страница" NR_TAG_URLENCODED="кодиран URL адрес на страница" NR_TAG_URLPATH="Път на страницата" NR_TAG_REFERRER="Препращаща страница" NR_TAG_SITENAME="Име на сайта" NR_TAG_SITEURL="URL на сайта" NR_TAG_PAGETITLE="Заглавие на страница" NR_TAG_PAGEDESC="Мета Описание на страницата" NR_TAG_PAGELANG="Езиков код на страницата" NR_TAG_USERID="ID на потребител" NR_TAG_USERNAME="Пълно име на потребителя" NR_TAG_USERLOGIN="Потребителски Login" NR_TAG_USEREMAIL="Потребителски имейл" NR_TAG_USERFIRSTNAME="Първо име на потребителя" NR_TAG_USERLASTNAME="Фамилия потребител" NR_TAG_USERGROUPS="ID на потребителски групи" NR_TAG_DATE="Дата" NR_TAG_TIME="Час" NR_TAG_RANDOMID="Случайно ID" NR_ICON="Икона" NR_SELECT_MODULE="Избери модул" NR_SELECT_CONTINENT="Избери континент" NR_SELECT_COUNTRY="Избери държава" NR_PLUGIN="Plugin" NR_GMAP_KEY="Google Maps API ключ" NR_GMAP_KEY_DESC="Ключът на Google Maps API се използва от разширенията на Tassos.gr. Ако имате някакви проблеми с това, че Google Map не се зарежда, вероятно е необходимо да въведете свой собствен API ключ." NR_GMAP_FIND_KEY="Вземи API ключ" NR_ARE_YOU_SURE="Сигурен ли си?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="Потребителски URL" NR_SAMPLE="Пример" NR_DEBUG="Отстраняване на грешки" NR_CUSTOMURL="Потребителски URL" NR_READMORE="Прочетете още" NR_IPADDRESS="IP адрес" NR_ASSIGN_BROWSERS="Браузър" NR_ASSIGN_BROWSERS_DESC="Изберете браузърите, на които да назначиете" NR_ASSIGN_BROWSERS_DESC2="Цебево селектирайте посетителите, които разглеждат вашия сайт с конкретни браузъри като Chrome, Firefox или Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Операционна система" NR_ASSIGN_OS_DESC="Изберете операционните системи, на които да назначите" NR_ASSIGN_OS_DESC2="Цебево селектирайте посетителите, които използват специфични операционни системи като Windows, Linux или Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Брой прегледи на страници" NR_ASSIGN_PAGEVIEWS_DESC="Целево селектирайте посетителите, които са прегледали определен брой страници" NR_ASSIGN_PAGEVIEWS_VIEWS="Показвания на страници" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Въведете броя на показванията на страници" NR_ASSIGN_COOKIENAME_NAME="Име на бисквитката" NR_ASSIGN_COOKIENAME_NAME_DESC="Въведете името, които да присвоите на бисквитката" NR_ASSIGN_COOKIENAME_NAME_DESC2="Целево селектиране на посетителите, които имат специфични бисквитки, съхранявани в браузъра им" NR_FEWER_THAN="По-малко от" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="По-голямо от" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Точно" NR_EXISTS="Съществува" ; NR_NOT_EXISTS="Does not exists" NR_IS_EQUAL="Равно на" ; NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Съдържа" ; NR_DOES_NOT_CONTAIN="Does not contain" NR_STARTS_WITH="Започва с" ; NR_DOES_NOT_START_WITH="Does not start with" NR_ENDS_WITH="Завършва със" ; NR_DOES_NOT_END_WITH="Does not end with" NR_ASSIGN_COOKIENAME_CONTENT="Съдържание на бисквитки" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Съдържанието на бисквитката" NR_ASSIGN_IP_ADDRESSES_DESC2="Целево селеектиране на посетителите, които стоят зад IP адрес (диапазон)" NR_ASSIGN_IP_ADDRESSES_DESC="Въведете списък разделени със запетаи и/или 'въведете' IP адреси и диапазони

Пример:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="ID на потребител" NR_ASSIGN_USER_ID_DESC="Целево селектиране на Joomla потребители по техните Joomla ID" NR_ASSIGN_USER_ID_SELECTION_DESC="Въведете разделени със запетая ID на Joomla потребители" NR_ASSIGN_COMPONENTS="Компонент" NR_ASSIGN_COMPONENTS_DESC="Изберете компоненти, към които да присвоите" NR_ASSIGN_COMPONENTS_DESC2="Целево селектиране на посетителите, които разглеждат конкретни компоненти" NR_ASSIGN_TIMERANGE="Времеви диапазон" NR_ASSIGN_TIMERANGE_DESC="Целево селектиране на посетителите според времето на вашия сървър" NR_START_TIME="Време начало" NR_END_TIME="Време край" NR_START_PUBLISHING_TIMERANGE_DESC="Въведете времето за начало на публикуване" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Въведете времето за край на публикуване" NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Ключ за сайт" NR_RECAPTCHA_SITE_KEY_DESC="Използва се в JavaScript кода, който се предоставя на вашите потребители." NR_RECAPTCHA_SECRET_KEY="Секретен ключ" NR_RECAPTCHA_SECRET_KEY_DESC="Използва се в комуникацията между вашия сървър и reCAPTCHA сървъра. Не забравяйте да го запазите в тайна." NR_RECAPTCHA_SITE_KEY_ERROR="reCaptcha Site Key ключ липсва или е невалиден" NR_PREVIOUS_MONTH="Предишен месец" NR_NEXT_MONTH="Следващия месец" NR_ASSIGN_GROUP_PAGE_URL="Страница / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Целево селектиране на посетителите, които разглеждат конкретни меню елементи или URL адреси" NR_ASSIGN_GROUP_DATETIME_DESC="Задействайте кутия въз основа на дата и час на вашия сървър" NR_ASSIGN_GROUP_USER_VISITOR="Joomla Потребител / Посетител" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Целево селектиране на регистрирани потребители или посетители, които са прегледали определен брой страници" NR_ASSIGN_GROUP_PLATFORM="Платформа на посетителя" NR_ASSIGN_GROUP_PLATFORM_DESC="Целево селектиране на посетителите, които използват мобилни устройства, Google Chrome или дори Windows" NR_ASSIGN_GROUP_GEO_DESC="Целево селектиране на посетители, които са физически в определен регион" NR_ASSIGN_GROUP_JCONTENT="Joomla! съдържание" NR_ASSIGN_GROUP_JCONTENT_DESC="Целево селектиране на посетителите, които разглеждат конкретни статии или категории на Joomla" NR_ASSIGN_GROUP_SYSTEM="Система / Интеграции" ; NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Целево селектиране на посетителите, които са взаимодействали с конкретни Joomla разширения на трета страна" NR_ASSIGN_GROUP_ADVANCED="Разширено селектиране на посетители" NR_ASSIGN_USERGROUP_DESC="Целево селектиране конкретни Joomla групи потребители " NR_ASSIGN_ARTICLE_DESC="Целево селектиране на посетителите, които разглеждат конкретни статии на Joomla" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Целево селектиране на посетителите, които разглеждат конкретни Joomla категории" NR_EXTENSION_REQUIRED="%s компонент изисква %s плъгин да бъде активиран, за да функционира правилно." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Целево селектиране на посетителите, които разглеждат специфични K2 елементи, категории или тагове" NR_ASSIGN_K2_ITEMS="Елемент" NR_ASSIGN_K2_ITEMS_DESC="Целево селеттиране на посетителите, които разглеждат конкретни K2 елементи." NR_ASSIGN_K2_ITEMS_LIST_DESC="Изберете K2 елементи, към които да назначите" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Съвпадение по конкретни ключови думи в съдържанието. Отделете ги със запетая или на нов ред." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Съвпадение по мета ключовите думи на съдържанието. Отделете ги със запетая или на нов ред." NR_ASSIGN_K2_PAGETYPES_DESC="Целево селектиране на посетителите, които разглеждат конкретни типове страници от компонента K2 " NR_ASSIGN_K2_ITEM_OPTION="Item елемент" NR_ASSIGN_K2_LATEST_OPTION="Последно съдържание от потребители или категории" NR_ASSIGN_K2_TAG_OPTION="Таг на страница" NR_ASSIGN_K2_CATEGORY_OPTION="Страница категории" NR_ASSIGN_K2_ITEM_FORM_OPTION="Форма за редактиране на елемент" NR_ASSIGN_K2_USER_PAGE_OPTION="Потребителска страница (блог)" NR_ASSIGN_K2_TAGS_DESC="Целево селектиране на посетителите, които разглеждат K2 елементи с конкретни тагове" NR_ASSIGN_K2_CATEGORIES_DESC="Целево селектиране на посетителите, които разглеждат конкретни категории K2" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Категории" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Елементи" NR_ASSIGN_PAGE_TYPES_DESC="Изберете типовете страници, на които да назначите" NR_ASSIGN_TAGS_DESC="Изберете тагове, на които да назначите" NR_CONTENT_KEYWORDS="Ключови думи в съдържанието" NR_META_KEYWORDS="Мета ключови думи" NR_TAG="Таг, етикет" NR_NORMAL="Нормален" NR_COMPACT="Компактен" NR_LIGHT="Светъл" NR_DARK="Тъмен" NR_SIZE="Размер" NR_THEME="Тема" NR_SINGLE="Единичен" NR_MULTIPLE="Множество" NR_RANGE="Диапазон" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Моля, потвърдете" NR_RECAPTCHA_INVALID_SECRET_KEY="Невалиден секретен ключ" NR_PAGE="Страница" NR_YOU_ARE_USING_EXTENSION="Използвате %s %s" NR_UPDATE="Актуализация" NR_SHOW_UPDATE_NOTIFICATION="Покажи съобщение за актуализация" NR_SHOW_UPDATE_NOTIFICATION_DESC="Ако е избрано, известие за обновление актуализация ще бъде показвано в изгледа на основния компонент, когато има нова версия за това разширение." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s е наличен" NR_ERROR_EMAIL_IS_DISABLED="Изпращането на поща е изключено. Имейлите не може да се изпращат." NR_ASSIGN_ITEMS="Елемент" NR_COUNTRY_AF="Афганистан" NR_COUNTRY_AX="Аландски острови" NR_COUNTRY_AL="Албания" NR_COUNTRY_DZ="Алжир" NR_COUNTRY_AS="Американска Самоа" NR_COUNTRY_AD="Андора" NR_COUNTRY_AO="Ангола" NR_COUNTRY_AI="Ангила" NR_COUNTRY_AQ="Антарктида" NR_COUNTRY_AG="Антигуа и Барбуда" NR_COUNTRY_AR="Аржентина" NR_COUNTRY_AM="Армения" NR_COUNTRY_AW="Аруба" NR_COUNTRY_AU="Австралия" NR_COUNTRY_AT="Австрия" NR_COUNTRY_AZ="Азербайджан" NR_COUNTRY_BS="Бахамски острови" NR_COUNTRY_BH="Бахрейн" NR_COUNTRY_BD="Бангладеш" NR_COUNTRY_BB="Барбадос" NR_COUNTRY_BY="Беларус" NR_COUNTRY_BE="Белгия" NR_COUNTRY_BZ="Белиз" NR_COUNTRY_BJ="Бенин" NR_COUNTRY_BM="Бермуда" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" NR_COUNTRY_BT="Бутан" NR_COUNTRY_BO="Боливия" NR_COUNTRY_BA="Босна и Херцеговина" NR_COUNTRY_BW="Ботсвана" NR_COUNTRY_BV="Остров Буве" NR_COUNTRY_BR="Бразилия" NR_COUNTRY_IO="Британска територия в Индийския океан" NR_COUNTRY_BN="Бруней Дарусалам" NR_COUNTRY_BG="България" NR_COUNTRY_BF="Буркина Фасо" NR_COUNTRY_BI="Бурунди" NR_COUNTRY_KH="Камбоджа" NR_COUNTRY_CM="Камерун" NR_COUNTRY_CA="Канада" NR_COUNTRY_CV="Кабо Верде" NR_COUNTRY_KY="Кайманови острови" NR_COUNTRY_CF="Централноафриканска република" NR_COUNTRY_TD="Чад" NR_COUNTRY_CL="Чили" NR_COUNTRY_CN="Китай" NR_COUNTRY_CX="Коледен остров" NR_COUNTRY_CC="Кокосови (Килинг) острови" NR_COUNTRY_CO="Колумбия" NR_COUNTRY_KM="Коморски острови" NR_COUNTRY_CG="Конго" NR_COUNTRY_CD="Конго, Демократична република" NR_COUNTRY_CK="Острови Кук" NR_COUNTRY_CR="Коста Рика" NR_COUNTRY_CI="Кот д'Ивоар" NR_COUNTRY_HR="Хърватия" NR_COUNTRY_CU="Куба" ; NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Кипър" NR_COUNTRY_CZ="Чехия" NR_COUNTRY_DK="Дания" NR_COUNTRY_DJ="Джибути" NR_COUNTRY_DM="Доминика" NR_COUNTRY_DO="Доминиканска република" NR_COUNTRY_EC="Еквадор" NR_COUNTRY_EG="Египет" NR_COUNTRY_SV="Ел Салвадор" NR_COUNTRY_GQ="Екваториална Гвинея" NR_COUNTRY_ER="Еритрея" NR_COUNTRY_EE="Естония" NR_COUNTRY_ET="Етиопия" NR_COUNTRY_FK="Фолклендски острови (Малвини)" NR_COUNTRY_FO="Фарьорски острови" NR_COUNTRY_FJ="Фиджи" NR_COUNTRY_FI="Финландия" NR_COUNTRY_FR="Франция" NR_COUNTRY_GF="Френска Гвиана" NR_COUNTRY_PF="Френска полинезия" NR_COUNTRY_TF="Френски южни територии" NR_COUNTRY_GA="Габон" NR_COUNTRY_GM="Гамбия" NR_COUNTRY_GE="Грузия" NR_COUNTRY_DE="Германия" NR_COUNTRY_GH="Гана" NR_COUNTRY_GI="Гибралтар" NR_COUNTRY_GR="Гърция" NR_COUNTRY_GL="Гренландия" NR_COUNTRY_GD="Гренада" NR_COUNTRY_GP="Гваделупа" NR_COUNTRY_GU="Гуам" NR_COUNTRY_GT="Гватемала" NR_COUNTRY_GG="Гърнзи" NR_COUNTRY_GN="Гвинея" NR_COUNTRY_GW="Гвинея-Бисау" NR_COUNTRY_GY="Гвиана" NR_COUNTRY_HT="Хаити" NR_COUNTRY_HM="Острови Хърд и Макдоналд" NR_COUNTRY_VA="Свети Престол (град Ватикана)" NR_COUNTRY_HN="Хондурас" NR_COUNTRY_HK="Хонг Конг" NR_COUNTRY_HU="Унгария" NR_COUNTRY_IS="Исландия" NR_COUNTRY_IN="Индия" NR_COUNTRY_ID="Индонезия" NR_COUNTRY_IR="Иран, Ислямска република" NR_COUNTRY_IQ="Ирак" NR_COUNTRY_IE="Ирландия" NR_COUNTRY_IM="Остров Ман" NR_COUNTRY_IL="Израел" NR_COUNTRY_IT="Италия" NR_COUNTRY_JM="Ямайка" NR_COUNTRY_JP="Япония" NR_COUNTRY_JE="Джърси" NR_COUNTRY_JO="Йордания" NR_COUNTRY_KZ="Казахстан" NR_COUNTRY_KE="Кения" NR_COUNTRY_KI="Кирибати" NR_COUNTRY_KP="Корея, Демократична народна република" NR_COUNTRY_KR="Корея, Република" NR_COUNTRY_KW="Кувейт" NR_COUNTRY_KG="Киргизстан" NR_COUNTRY_LA="Лаоска Народна демократична република" NR_COUNTRY_LV="Латвия" NR_COUNTRY_LB="Ливан" NR_COUNTRY_LS="Лесото" NR_COUNTRY_LR="Либерия" NR_COUNTRY_LY="Либийска арабска Джамахирия" NR_COUNTRY_LI="Лихтенщайн" NR_COUNTRY_LT="Литва" NR_COUNTRY_LU="Люксембург" NR_COUNTRY_MO="Макао" NR_COUNTRY_MK="Северна Македония" NR_COUNTRY_MG="Мадагаскар" NR_COUNTRY_MW="Малави" NR_COUNTRY_MY="Малайзия" NR_COUNTRY_MV="Малдиви" NR_COUNTRY_ML="Мали" NR_COUNTRY_MT="Малта" NR_COUNTRY_MH="Маршалови острови" NR_COUNTRY_MQ="Мартиника" NR_COUNTRY_MR="Мавритания" NR_COUNTRY_MU="Мавриций" NR_COUNTRY_YT="Майот" NR_COUNTRY_MX="Мексико" NR_COUNTRY_FM="Микронезия" NR_COUNTRY_MD="Молдова" NR_COUNTRY_MC="Монако" NR_COUNTRY_MN="Монголия" NR_COUNTRY_ME="Черна гора" NR_COUNTRY_MS="Монсерат" NR_COUNTRY_MA="Мароко" NR_COUNTRY_MZ="Мозамбик" NR_COUNTRY_MM="Мианмар" NR_COUNTRY_NA="Намибия" NR_COUNTRY_NR="Науру" ; NR_COUNTRY_NM="North Macedonia" NR_COUNTRY_NP="Непал" NR_COUNTRY_NL="Холандия" NR_COUNTRY_AN="Холандски Антили" NR_COUNTRY_NC="Нова Каледония" NR_COUNTRY_NZ="Нова Зеландия" NR_COUNTRY_NI="Никарагуа" NR_COUNTRY_NE="Нигер" NR_COUNTRY_NG="Нигерия" NR_COUNTRY_NU="Ниуе" NR_COUNTRY_NF="Остров Норфолк" NR_COUNTRY_MP="Северни Мариански острови" NR_COUNTRY_NO="Норвегия" NR_COUNTRY_OM="Оман" NR_COUNTRY_PK="Пакистан" NR_COUNTRY_PW="Палау" NR_COUNTRY_PS="Палестинска територия" NR_COUNTRY_PA="Панама" NR_COUNTRY_PG="Папуа-Нова Гвинея" NR_COUNTRY_PY="Парагвай" NR_COUNTRY_PE="Перу" NR_COUNTRY_PH="Филипини" NR_COUNTRY_PN="Питкерн" NR_COUNTRY_PL="Полша" NR_COUNTRY_PT="Португалия" NR_COUNTRY_PR="Пуерто Рико" NR_COUNTRY_QA="Катар" NR_COUNTRY_RE="Реюнион" NR_COUNTRY_RO="Румъния" NR_COUNTRY_RU="Руска федерация" NR_COUNTRY_RW="Руанда" NR_COUNTRY_SH="Света Елена" NR_COUNTRY_KN="Сейнт Китс и Невис" NR_COUNTRY_LC="Света Лусия" NR_COUNTRY_PM="Сен Пиер и Микелон" NR_COUNTRY_VC="Свети Винсънт и Гренадини" NR_COUNTRY_WS="Самоа" NR_COUNTRY_SM="Сан Марино" NR_COUNTRY_ST="Сао Томе и Принсипи" NR_COUNTRY_SA="Саудитска Арабия" NR_COUNTRY_SN="Сенегал" NR_COUNTRY_RS="Сърбия" NR_COUNTRY_SC="Сейшелските острови" NR_COUNTRY_SL="Сиера Леоне" NR_COUNTRY_SG="Сингапур" NR_COUNTRY_SK="Словакия" NR_COUNTRY_SI="Словения" NR_COUNTRY_SB="Соломоновите острови" NR_COUNTRY_SO="Сомалия" NR_COUNTRY_ZA="Южна Африка" NR_COUNTRY_GS="Южна Джорджия и Южните Сандвичеви острови" NR_COUNTRY_ES="Испания" NR_COUNTRY_LK="Шри Ланка" NR_COUNTRY_SD="Судан" NR_COUNTRY_SS="Южен Судан" NR_COUNTRY_SR="Суринам" NR_COUNTRY_SJ="Свалбард и Ян Майен" NR_COUNTRY_SZ="Свазиленд" NR_COUNTRY_SE="Швеция" NR_COUNTRY_CH="Швейцария" NR_COUNTRY_SY="Сирийска Арабска Република" NR_COUNTRY_TW="Тайван" NR_COUNTRY_TJ="Таджикистан" NR_COUNTRY_TZ="Танзания, Обединена република" NR_COUNTRY_TH="Тайланд" NR_COUNTRY_TL="Източен Тимор" NR_COUNTRY_TG="Того" NR_COUNTRY_TK="Токелау" NR_COUNTRY_TO="Тонга" NR_COUNTRY_TT="Тринидад и Тобаго" NR_COUNTRY_TN="Тунис" NR_COUNTRY_TR="Турция" NR_COUNTRY_TM="Туркменистан" NR_COUNTRY_TC="Острови Търкс и Кайкос" NR_COUNTRY_TV="Тувалу" NR_COUNTRY_UG="Уганда" NR_COUNTRY_UA="Украйна" NR_COUNTRY_AE="Обединени арабски емирства" NR_COUNTRY_GB="Великобритания" NR_COUNTRY_US="Съединени щати" NR_COUNTRY_UM="Малки отдалечени острови на САЩ" NR_COUNTRY_UY="Уругвай" NR_COUNTRY_UZ="Узбекистан" NR_COUNTRY_VU="Вануату" NR_COUNTRY_VE="Венецуела" NR_COUNTRY_VN="Виетнам" NR_COUNTRY_VG="Вирджински острови, британски" NR_COUNTRY_VI="Вирджински острови, САЩ" NR_COUNTRY_WF="Уолис и Футуна" NR_COUNTRY_EH="Западна Сахара" NR_COUNTRY_YE="Йемен" NR_COUNTRY_ZM="Замбия" NR_COUNTRY_ZW="Зимбабве" NR_CONTINENT_AF="Африка" NR_CONTINENT_AS="Азия" NR_CONTINENT_EU="Европа" NR_CONTINENT_NA="Северна Америка" NR_CONTINENT_SA="Южна Америка" NR_CONTINENT_OC="Океания" NR_CONTINENT_AN="Антарктида" NR_FRONTEND="Преден край" NR_BACKEND="Заден край" NR_EMBED="Вграден" NR_RATE="Ставка %s" NR_REPORT_ISSUE="Подаване на сигнал за проблем" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!NN,Bsystem/nrframework/language/cs-CZ/cs-CZ.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Systém - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - používán rozšířeními od Tassos.gr" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignorovat" NR_INCLUDE="Zahrnout" NR_EXCLUDE="Vyloučit" NR_SELECTION="Výběr" NR_ASSIGN_MENU_NOITEM="Neobsahuje žádný Itemid" NR_ASSIGN_MENU_NOITEM_DESC="Přiřadit také, pokud není nastavené Itemid v URL?" NR_ASSIGN_MENU_CHILD="Také na zděděné položky" NR_ASSIGN_MENU_CHILD_DESC="Přiřadit také k podřízeným položkám vybraných položek?" NR_COPY_OF="Kopie %s" NR_ASSIGN_DATETIME_DESC="Cílový návštěvníci na základě času a data na vašem serveru" NR_DATETIME="Datum a čas" NR_TIME="Čas" NR_DATE="Datum" NR_DATETIME_DESC="Zadejte datum a čas, kdy dojde k automatickému zveřejnění/zneveřejnění" NR_START_PUBLISHING="Počáteční datum" NR_START_PUBLISHING_DESC="Zadejte datum začátku zveřejnění" NR_FINISH_PUBLISHING="Koncové datum" NR_FINISH_PUBLISHING_DESC="Zadejte datum ukončení zveřejnění" NR_DATETIME_NOTE="Při přiřazování data a času se používá datum/čas vašich serverů, nikoli ze systém návštěvníků." NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP kód" NR_ASSIGN_PHP_DESC="Vložte část PHP kódu k ověření." NR_ASSIGN_PHP_DESC2="Vlastní PHP kód, který zpracovává informace o vracejících návštevnících. Kód musí vracet hodnotu true nebo false.

Napříkla:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Čas na stránce" NR_SECONDS="Sekund" NR_ASSIGN_TIMEONSITE_DESC="Zadejte dobu trvání v sekundách, abyste ji mohli porovnat s celkovým časem, který uživatel strávil na celém webu (doba trvání návštěvy).

Příklad:
Pokud chcete zobrazit box poté, co uživatel strávil na celém webu 3 minuty, zadejte 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Cílový návštěvníci, kteří procházejí konkrétní URL adresy" NR_ASSIGN_URLS_DESC="Zadejte adresy URL (nebo jejich části), které chcete porovnat.
Pro každou shodu použijte nový řádek." NR_ASSIGN_URLS_LIST="Shoda URL" NR_ASSIGN_URLS_REGEX="Použít regulární výraz" NR_ASSIGN_URLS_REGEX_DESC="Vyberte, zda chcete s hodnotou zacházet jako s regulárními výrazy." NR_ASSIGN_LANGS="Jazyk" NR_ASSIGN_LANGS_DESC="Cílový návštěvníci, kteří procházejí stránky v konkrétním jazyce" NR_ASSIGN_LANGS_LIST_DESC="Zvolte jazyk k přiřazení" NR_ASSIGN_DEVICES="Zařízení" NR_ASSIGN_DEVICES_DESC2="Cílový návštěvníci, kteří používají konkrétní zařízení jako telefon, tablet nebo stolní počítač." NR_ASSIGN_DEVICES_DESC="Zvolte zařízení k přiřazení" NR_ASSIGN_DEVICES_NOTE="Mějte na paměti, že detekce zařízení není vždy 100% přesná. Uživatelé mohou svůj prohlížeč záměrně nastavit tak, aby napodoboval jiná zařízení." NR_MENU="Menu" NR_MENU_ITEMS="Položka menu" NR_MENU_ITEMS_DESC="Cílení na návštěvníky, kteří si prohlížejí konkrétní položky menu" NR_USERGROUP="Skupina uživatelů" NR_USERGROUP_DESC="Vyberte skupiny uživatelů, které chcete přiřadit.

Poznámka: Pokud chcete, aby byla veřejná, stačí nastavit možnost Ignorovat a nezvolit možnost Veřejné." NR_ACCESSLEVEL="Skupina uživatelů" NR_USERACCESSLEVEL="Úroveň pro přístup uživatele" NR_USERACCESSLEVEL_DESC="Vyberte úrovně přístupu k zobrazení, které chcete přiřadit uživateli." NR_SHOW_COPYRIGHT="Zobrazovat copyright" NR_SHOW_COPYRIGHT_DESC="Pokud je tato možnost vybrána, zobrazí se v zobrazeních správce další informace o autorských právech. Rozšíření Tassos.gr nikdy nezobrazují informace o autorských právech ani zpětné odkazy na frontend." NR_WIDTH="Šířka" NR_WIDTH_DESC="Zadejte šířku v px, em nebo %

Příklad: 400px" NR_HEIGHT="Výška" NR_HEIGHT_DESC="Zadejte výšku v px, em nebo %

Příklad: 400px" NR_PADDING="Šířka vnitřního okraje" NR_PADDING_DESC="Enter šířku vnitřního okraje v px, em nebo %

Příklad: 20px" NR_MARGIN="Okraj" NR_MARGIN_DESC="Vlastnost CSS okraj se používá k vytvoření prostoru kolem rámečku a nastavení velikosti bílého místa mimo rámeček v pixelech nebo v %.

Příklad 1: 25px
Příklad 2: 5%

Určení okraje pro každou stranu [horní pravá dolní levá]:

Pouze nahoře: 25px 0 0 0
Pouze vpravo: 0 25px 0 0
Pouze dole: 0 0 25px
Pouze vlevo: 0 0 0 25px" NR_COLOR_HOVER="Barva odkazu při přejetí myší" NR_COLOR="Barva" NR_COLOR_DESC="Určete barvu ve formátu HEX nebo RGBA." NR_TEXT_COLOR="Barva textu" NR_BACKGROUND="Pozadí" NR_BACKGROUND_COLOR="Barva pozadí" NR_BACKGROUND_COLOR_DESC="Zadejte údaje o barvě pozadí ve formátu HEX nebo RGBA. Batvu zrušíte parametrem 'none'. V případě, že požadujete průhlednost vložte 'transparent'." NR_URL_SHORTENING_FAILED="Zkrácení %s s %s selhalo. %s." NR_EXPORT="Export" NR_IMPORT="Import" NR_PLEASE_CHOOSE_A_VALID_FILE="Prosím zvolte platný název souboru" NR_IMPORT_ITEMS="Import položek" NR_PUBLISH_ITEMS="Zveřejnit položky" NR_AS_EXPORTED="Jak je exportováno" NR_TITLE="Název" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="AcyMailing seznam" NR_ACYMAILING_LIST_DESC="Vyberte AcyMailing seznam k přiřazení." NR_ASSIGN_ACYMAILING_DESC="Cílení na návštěvníky, kteří se přihlásili do konkrétních seznamů AcyMailing." NR_AKEEBASUBS="Akeeba předplatné" NR_AKEEBASUBS_LEVELS="Úrovně" NR_AKEEBASUBS_LEVELS_DESC="Zvolte úroveň Předplatného Akeeba k přiřazení." NR_ASSIGN_AKEEBASUBS_DESC="Cílení na návštěvníky, kteří se přihlásili k odběru konkrétních odběrů Akeeba." NR_MATCH="Shoda" NR_MATCH_DESC="Způsob použitý k porovnání hodnoty" NR_ASSIGN_MATCHING_METHOD="Metoda shody" NR_ASSIGN_MATCHING_METHOD_DESC="Mají být všechna nebo pouze některá přiřazení porovnána?

Všechna
Bude zveřejněno, pokud Všechna níže uvedených přiřazení.

Každéy
Bude zveřejněno, pokud bude přiřazenoKaždé (jedno nebo více) níže uvedených přiřazení.
Skupiny přiřazení, u kterých je vybrána možnost \"Ignorovat\", budou ignorovány." NR_ANY="Jakýkoli" NR_ALL="Vše" NR_ASSIGN_REFERRER="Referrer URL" NR_ASSIGN_REFERRER_DESC2="Zaměřte se na návštěvníky, kteří na vaše stránky přicházejí z určitého zdroje provozu" NR_ASSIGN_REFERRER_DESC="Vložte jednu Referrer URL na řádek: Např.:

google.com
facebook.com/mojestranka" NR_ASSIGN_REFERRER_NOTE="Mějte na paměti, že zjišťování odkazů URL není vždy 100% přesné. Některé servery mohou používat proxy servery, které tyto informace odstraňují, a lze je také snadné zfalšovat." NR_PROFEATURE_HEADER="%s je funkce PRO verze" NR_PROFEATURE_DESC="Je nám líto, ale %s není součástí vašeho předplatnéhoo. Přejděte na PRO, které vám zpřístupní všechny skvělé funkce." NR_PROFEATURE_DISCOUNT="Bonus: %s uživatelé volné verze získají 20% slevu z běžné ceny, která se automaticky použije při platbě." NR_ONLY_AVAILABLE_IN_PRO="Dostupné pouze ve verzi PRO" NR_UPGRADE_TO_PRO="Upgradujte na Pro verzi" NR_UPGRADE_TO_PRO_TO_UNLOCK="Upgradujte na Pro verzi pro odblokování" NR_UPGRADE_TO_PRO_VERSION="Skvěle! Zbývá poslední krok. Klikněte na tlačítko níže a dokončete přechod na verzi Pro." NR_UNLOCK_PRO_FEATURE="Odblokujte Pro funkce" NR_USING_THE_FREE_VERSION="Používáte volnou verzi Convert Forms. Pokud chcete využít všechny funkce, zakupte si Pro verzi." NR_LEFT_TO_RIGHT="Zleva doprava" NR_RIGHT_TO_LEFT="Zprava doleva" NR_BGIMAGE="Obrázek na pozadí" NR_BGIMAGE_DESC="Nastavit obrázek pozadí" NR_BGIMAGE_FILE="Obrázek" NR_BGIMAGE_FILE_DESC="Vyberte nebo nahrejte soubor, který bude zobrazen jako pozadí." NR_BGIMAGE_REPEAT="Opakovat" NR_BGIMAGE_REPEAT_DESC="Vlastnost background-repeat nastavuje, zda se obrázek na pozadí bude opakovat. Ve výchozím nastavení se obrázek na pozadí opakuje vertikálně i horizontálně.

Opakování: Obrázek na pozadí se bude opakovat vertikálně i horizontálně.

Opakování-x: Obrázek na pozadí se bude opakovat pouze vodorovně

Opakování-y: Obrázek na pozadí se bude opakovat pouze vertikálně

Neopakovat: Obrázek na pozadí se nebude opakovat." NR_BGIMAGE_SIZE="Velikost" NR_BGIMAGE_SIZE_DESC="Zadejte velikost obrázku na pozadí.

Auto: Obrázek na pozadí obsahuje jeho šířku a výšku

Krytí: Obrázek na pozadí se škáluje tak, aby byl co největší a aby byla oblast pozadí zcela pokryta obrázkem na pozadí. Některé části obrázku na pozadí nemusí být v oblasti umístění pozadí viditelné

Přizpůsobení: Škálujte obrázek na největší velikost tak, aby se jeho šířka i výška vešly do oblasti obsahu

100% 100%: Roztáhne obrázek na pozadí tak, aby zcela zakrýval oblast obsahu." NR_BGIMAGE_POSITION="Umístění" NR_BGIMAGE_POSITION_DESC="Vlastnost background-position nastavuje počáteční pozici obrázku na pozadí. Ve výchozím nastavení je obrázek na pozadí umístěn v levém horním rohu. První hodnota je horizontální pozice a druhá hodnota je vertikální pozice.

Můžete použít jednu z předdefinovaných hodnot nebo zadat vlastní hodnotu v procentech: x% y% nebo v pixelech xPos yPos." NR_RTL="Zapnout RTL" NR_RTL_DESC="Směr čtení zprava-doleva pro abecedy jako jsou arabská, hebrejská, syrská a Tana." NR_HORIZONTAL="Horizontální" NR_VERTICAL="Vertikální" NR_FORM_ORIENTATION="Orientace formuláře" NR_FORM_ORIENTATION_DESC="Zvolte orientaci formuláře" NR_ASSIGN_CATEGORY="Kategorie" NR_ASSIGN_CATEGORY_DESC="Zvolte kategorii k přiřazení" NR_ASSIGN_CATEGORY_CHILD="Také na zděděné položky" NR_ASSIGN_CATEGORY_CHILD_DESC="Přiřadit také k podřízeným položkám vybraných položek?" NR_NEW="Nový" NR_LIST="Seznam" NR_DOCUMENTATION="Dokumentace" NR_KNOWLEDGEBASE="Znalostní báze" NR_FAQ="FAQ" NR_INFORMATION="Informace" NR_EXTENSION="Rozšíření" NR_VERSION="Verze" NR_CHANGELOG="Změnový soubor" NR_DOWNLOAD="Stažení" NR_DOWNLOAD_KEY_MISSING="Chybí klíč ke stahování" NR_DOWNLOAD_KEY="Klíč ke stahování" NR_DOWNLOAD_KEY_DESC="Chcete-li najít svůj klíč ke stažení, přihlaste se ke svému účtu na webu Tassos.gr a přejděte do sekce Downloads.

Poznámka: Nastavením klíče ke stažení neprovedete upgrade bezplatné verze na verzi Pro. Chcete-li odemknout funkce Pro, budete muset nahradit verzi Free verzí Pro." NR_DOWNLOAD_KEY_HOW="Aby bylo možné provádět aktualizaci %s s pomocí Joomla autualizace, je nutné zadat váš Klíč ke stahování v nastavení zásuvného modulu Novarain Framework" NR_DOWNLOAD_KEY_FIND="Najít klíč ke stahování" NR_DOWNLOAD_KEY_UPDATE="Aktualizovat klíč ke stahování" NR_OK="OK" NR_MISSING="Chybí" NR_LICENSE="Licence" NR_AUTHOR="Autor" NR_FOLLOWME="Sledujte mě" NR_FOLLOW="Sledovat %s" NR_TRANSLATE_INTEREST="Měli byste zájem o pomoc s překladem %s do vašeho jazyka?" NR_TRANSIFEX_REQUEST="Pošlete mi požadavek na Transifex" NR_HELP_WITH_TRANSLATIONS="Podílejte se na překladu" NR_PUBLISHING_ASSIGNMENTS="Podmínky zobrazení" NR_ADVANCED="Rozšířené" NR_USEGLOBAL="Použít globální" NR_WEEKDAY="Den v týdnu" NR_MONTH="Měsíc" NR_MONDAY="Pondělí" NR_TUESDAY="Úterý" NR_WEDNESDAY="Středa" NR_THURSDAY="Čtvrtek" NR_FRIDAY="Pátek" NR_SATURDAY="Sobota" NR_WEEKEND="Víkend" NR_WEEKDAYS="Víkendové dny" NR_SUNDAY="Neděle" NR_JANUARY="Leden" NR_FEBRUARY="Únor" NR_MARCH="Březen" NR_APRIL="Duben" NR_MAY="Květen" NR_JUNE="Červen" NR_JULY="Červenec" NR_AUGUST="Srpen" NR_SEPTEMBER="Září" NR_OCTOBER="Říjen" NR_NOVEMBER="Listopad" NR_DECEMBER="Prosinec" NR_NEVER="Nikdy" NR_SECONDS="Sekund" NR_MINUTES="Minuty" NR_HOURS="Hodiny" NR_DAYS="Dny" NR_SESSION="Sezení" NR_EVER="Vždy" NR_COOKIE="Cookie" NR_BOTH="Oba" NR_NONE="Žádný" NR_NONE_SELECTED="Nic nevybráno" NR_DESKTOPS="Stolní" NR_MOBILES="Mobil" NR_TABLETS="Tablet" NR_PER_SESSION="Za sezení" NR_PER_DAY="Za den" NR_PER_WEEK="Za týden" NR_PER_MONTH="Za měsíc" NR_FOREVER="Navždy" NR_FEATURE_UNDER_DEV="Tato funkce se stále vyvíjí" NR_LIKE_THIS_EXTENSION="Líbí se vám toto rozšíření?" NR_LEAVE_A_REVIEW="Napište hodnocení na JED" NR_SUPPORT="Podpora" NR_NEED_SUPPORT="Potřebujete pomoc?" NR_DROP_EMAIL="Napište mi e-mail" NR_READ_DOCUMENTATION="Prostudujte si dokumentaci" NR_COPYRIGHT="%s - Tassos.gr Všechna práva vyhrazena" NR_DASHBOARD="Dashboard" NR_NAME="Název" NR_WRONG_COORDINATES="Zadané souřadnice nejsou platné" NR_ENTER_COORDINATES="Zeměpiská šířka a délka" NR_NO_ITEMS_FOUND="Žádné položky" NR_ITEM_IDS="Žádná ID položek" NR_TOGGLE="Přepínač" NR_EXPAND="Rozbalit" NR_COLLAPSE="Sbalit" NR_SELECTED="Vybrané" NR_MAXIMIZE="Maximalizovat" NR_MINIMIZE="Minimalizovat" NR_SELECTION="Výběr" NR_INSTALL="Instalovat" NR_INSTALL_NOW="Instalovat nyní" NR_INSTALLED="Nainstalováno" NR_COMING_SOON="Již brzy" NR_ROADMAP="Plánováno" NR_MEDIA_VERSIONING="Používat verzování médií" NR_MEDIA_VERSIONING_DESC="Zvolte přidání čísla verze přípony na konec URL adres médií (js/css), aby prohlížeče vynutily načtení správného souboru." NR_LOAD_JQUERY="Nahrát jQuery" NR_LOAD_JQUERY_DESC="Zvolte načtení jádra skriptu jQuery. Tuto možnost můžete zakázat, pokud bude docházet ke konfliktům, pokud vaše šablona nebo jiná rozšíření načítají vlastní verzi jQuery." NR_SELECT_CURRENCY="Zvolte měnu" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Kampaň" NR_ASSIGN_CONVERTFORMS_DESC="Cílení na návštěvníky, kteří se přihlásili k odběru konkrétních kampaní ConvertForms" NR_CONVERTFORMS_LIST_DESC="Vyberte kampaně ConvertForms, které chcete přiřadit." NR_LEFT="Vlevo" NR_CENTER="Na střed" NR_RIGHT="Vpravo" NR_BOTTOM="Dolů" NR_TOP="Nahoru" NR_AUTO="Auto" NR_CUSTOM="Vlastní" NR_UPLOAD="Nahrát" NR_IMAGE="Obrázek" NR_INTRO_IMAGE="Úvodní obrázek" NR_FULL_IMAGE="Plný obrázek" NR_IMAGE_SELECT="Vybrat obrázek" NR_IMAGE_SIZE_COVER="Obálka" NR_IMAGE_SIZE_CONTAIN="Obsahuje" NR_REPEAT="Opakovat" NR_REPEAT_X="Opakovat x" NR_REPEAT_Y="Opakovat y" NR_REPEAT_NO="Neopakovat" NR_FIELD_STATE_DESC="Nastavit stav položky" NR_CREATED_DATE="Datum vytvoření" NR_CREATED_DATE_DESC="Datum vytvoření položky" NR_MODIFIFED_DATE="Datum úpravy" NR_MODIFIFED_DATE_DESC="Datum, kdy byla položka naposledy upravena." NR_CATEGORIES="Kategorie" NR_CATEGORIES_DESC="Zvolte kategorie k přřazení" NR_ALSO_ON_CHILD_ITEMS="Také na zděděné položky" NR_ALSO_ON_CHILD_ITEMS_DESC="Přiřadit také k podřízeným položkám vybraných položek?" NR_PAGE_TYPE="Typ stránky" NR_PAGE_TYPES="Typy stránky" NR_PAGE_TYPES_DESC="Vyberte, na jakých typech stránek má být přiřazení aktivní." NR_CONTENT_VIEW_CATEGORY_BLOG="Kategorie Blog" NR_CONTENT_VIEW_CATEGORY_LIST="Seznam kategorií" NR_CONTENT_VIEW_CATEGORIES="Zobrazit všechny kategorie" NR_CONTENT_VIEW_ARCHIVED="Archivované články" NR_CONTENT_VIEW_FEATURES="Oblíbené články" NR_CONTENT_VIEW_CREATE_ARTICLE="Vytvořit článek" NR_CONTENT_VIEW_ARTICLE="Jeden článek" NR_ARTICLE_VIEW_DESC="Umožňuje zohlednit zobrazení článku" NR_CATEGORY_VIEW="Zobrazení kategorie" NR_CATEGORY_VIEW_DESC="Povolit zohlednění zobrazení Kategorie" NR_CONTENT_VIEW="Zobrazení komponenty obsahu" NR_CONTENT_VIEW_DESC="Vyberte pohledy, které chcete přiřadit." NR_ARTICLES="Články" NR_ARTICLES_DESC="Zvolte články k přiřazení." NR_ARTICLE="Článek" NR_ARTICLE_AUTHORS="Autoři" NR_ARTICLE_AUTHORS_DESC="Zvolte autory k přiřazení" NR_ONLY="Pouze" NR_OTHERS="Ostatní" NR_SMARTTAGS="Chytré štítky" NR_SMARTTAGS_SHOW="Zobrazit chytré štítky" NR_SMARTTAGS_NOTFOUND="Žádné chytré štítky" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Hledat chytré štítky" NR_CONTACT_US="Kontaktujte nás" NR_FONT_COLOR="Barva mísma" NR_FONT_SIZE="Velikost písma" NR_FONT_SIZE_DESC="Zvolte velikost písma v pixelech" NR_TEXT="Text" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Zapnout přepsání výstupu" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Povolí vykreslování rozšíření při přepsání rozvržení stránky (tmpl). Příklady: tmpl=component nebo tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Zapnout přepis formátu" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Povolí vykreslování rozšíření, pokud formát stránky není jiný než HTML. Příklady: format=raw nebo format=json." NR_GEOLOCATING="Geolokace" NR_GEOLOCATION="Geolokace" NR_GEOLOCATING_DESC="Geolokace není vždy 100% přesná. Geolokace je založena na IP adrese návštěvníka. Ne všechny IP adresy jsou pevné nebo známé." NR_CITY="Město" NR_CITY_NAME="Název města" NR_CONDITION_CITY_DESC="Zadejte název města v angličtině. Více měst oddělte čárkou." NR_CONTINENT="Kontinent" NR_REGION="Region" NR_CONDITION_REGION_DESC="Hodnota se skládá ze dvou částí, z dvouznakového kódu země ISO 3166-1 a z kódu regionu. Hodnota by tedy měla mít následující tvar: KÓD_ZEMĚ-KÓD_OBLASTI. Úplný seznam kódů regionů naleznete po kliknutí na odkaz Vyhledat kód regionu." NR_ASSIGN_COUNTRIES="Země" NR_ASSIGN_COUNTRIES_DESC2="Cílení na návštěvníky, kteří se fyzicky nacházejí v určité zemi" NR_ASSIGN_COUNTRIES_DESC="Zvolte státy k přiřazení" NR_ASSIGN_CONTINENTS="Kontinent" NR_ASSIGN_CONTINENTS_DESC="Zvolte kontinenty k přřazení" NR_ASSIGN_CONTINENTS_DESC2="Cílení na návštěvníky, kteří se fyzicky nacházejí na určitém kontinentu" NR_ICONTACT_ACCOUNTID_ERROR="Nepodařilo se získat iContact AccountID" NR_TAG_CLIENTDEVICE="Typ zařízení návštěvníka" NR_TAG_CLIENTOS="Operační systém návštěníka" NR_TAG_CLIENTBROWSER="Prohlížeč návštevníka" NR_TAG_CLIENTUSERAGENT="Řetězec agenta návštěvníka" NR_TAG_IP="IP adresa návštěvníka" NR_TAG_URL="URL stránky" NR_TAG_URLENCODED="Šifrované URL stránky" NR_TAG_URLPATH="Cesta ke stránce" NR_TAG_REFERRER="Referrer stránky" NR_TAG_SITENAME="Název webu" NR_TAG_SITEURL="URL webu" NR_TAG_PAGETITLE="Název stránky" NR_TAG_PAGEDESC="Meta popis stránky" NR_TAG_PAGELANG="Jazykový kód stránky" NR_TAG_USERID="Uživatel ID" NR_TAG_USERNAME="Plné jméno uživatele" NR_TAG_USERLOGIN="Login uživatele" NR_TAG_USEREMAIL="E-mail uživatele" NR_TAG_USERFIRSTNAME="Jméno uživatele" NR_TAG_USERLASTNAME="Příjmení uživatele" NR_TAG_USERGROUPS="ID skupin uživatelů" NR_TAG_DATE="Datum" NR_TAG_TIME="Čas" NR_TAG_RANDOMID="Náhodné ID" NR_ICON="Ikona" NR_SELECT_MODULE="Zvolte modul" NR_SELECT_CONTINENT="Zvolte kontinent" NR_SELECT_COUNTRY="Zvolte zemi" NR_PLUGIN="Zásuvný modul" NR_GMAP_KEY="Google Maps API klíč" NR_GMAP_KEY_DESC="Klíč Google Maps API používají rozšíření Tassos.gr. Pokud se potýkáte s problémy s nenačtením mapy Google, pravděpodobně budete muset zadat vlastní klíč API." NR_GMAP_FIND_KEY="Získat API klíč" NR_ARE_YOU_SURE="Jste si jistý?" NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Opravdu chcete tuto položku odstranit?" NR_CUSTOMURL="Vlastní URL" NR_SAMPLE="Vzor" NR_DEBUG="Debug" NR_CUSTOMURL="Vlastní URL" NR_READMORE="Číst dále" NR_IPADDRESS="IP adresa" NR_ASSIGN_BROWSERS="Prohlížeč" NR_ASSIGN_BROWSERS_DESC="Zvolte prohlížeče k přiřazení" NR_ASSIGN_BROWSERS_DESC2="Cílení na návštěvníky, kteří si prohlížejí vaše stránky v konkrétních prohlížečích, jako je Chrome, Firefox nebo Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Operační systém" NR_ASSIGN_OS_DESC="Zvolte operační systém k přiřazení" NR_ASSIGN_OS_DESC2="Cílení na návštěvníky, kteří používají konkrétní operační systémy, například Windows, Linux nebo Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Počet shlédnutých stran" NR_ASSIGN_PAGEVIEWS_DESC="Cílový návštěvníci, kteří shlédli stanovený počet stran" NR_ASSIGN_PAGEVIEWS_VIEWS="Shlédnutí stran" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Zadejte počet shlednutí stránky" NR_ASSIGN_COOKIENAME_NAME="Název cookie" NR_ASSIGN_COOKIENAME_NAME_DESC="Zadejte název cookie k přiřazení" NR_ASSIGN_COOKIENAME_NAME_DESC2="Cílový návštěvníci, kteří mají uložené konkrétní cookie v prohlížeči" NR_FEWER_THAN="Méně než" NR_FEWER_THAN_OR_EQUAL_TO="Méně nebo rovno" NR_GREATER_THAN="Větší než" NR_GREATER_THAN_OR_EQUAL_TO="Větší nebo rovno" NR_EXACTLY="Přesně" NR_EXISTS="Existuje" NR_NOT_EXISTS="Neexistuje" NR_IS_EQUAL="Je rovno" NR_DOES_NOT_EQUAL="Nerovná se" NR_CONTAINS="Obsahuje" NR_DOES_NOT_CONTAIN="Neobsahuje" NR_STARTS_WITH="Začíná" NR_DOES_NOT_START_WITH="Nezačíná" NR_ENDS_WITH="Končí" NR_DOES_NOT_END_WITH="Nekončí" NR_ASSIGN_COOKIENAME_CONTENT="Obsah cookie" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Obsah cookie" NR_ASSIGN_IP_ADDRESSES_DESC2="Cílový uživatelé jsou za konkrétní IP adresou (rozsahem)" NR_ASSIGN_IP_ADDRESSES_DESC="Zadejte seznam ip adres oddělených čárkou a/nebo rozsahy oddělených 'enterem'

Příklad:
127.0.0.1,
192.10-120.2,
168" NR_USER="Uživatel" NR_ASSIGN_USER_SELECTION_DESC="Vyberte uživatele systému Joomla, kterým chcete přiřadit." NR_ASSIGN_USER_ID="Uživatel ID" NR_ASSIGN_USER_ID_DESC="Cílit na konkrétní Joomla uživatele podle jejich ID" NR_ASSIGN_USER_ID_SELECTION_DESC="Zadejte ID uživatelů Joomla, oddělené čárkou " NR_ASSIGN_COMPONENTS="Komponenta" NR_ASSIGN_COMPONENTS_DESC="Zvolte komponenty k přiřazení" NR_ASSIGN_COMPONENTS_DESC2="Cílení na návštěvníky, kteří si prohlížejí konkrétní komponenty" NR_ASSIGN_TIMERANGE="Rozsah času" NR_ASSIGN_TIMERANGE_DESC="Cílový návštěvníci na základě času serveru" NR_START_TIME="Čas začátku" NR_END_TIME="Čas konce" NR_START_PUBLISHING_TIMERANGE_DESC="Zadejte čas do začátku zveřejnění" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Zadejte čas do ukončení zveřejnění" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_DESC="Chcete-li získat web a tajný klíč pro svou doménu, přejděte na stránku https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Klíč webu" NR_RECAPTCHA_SITE_KEY_DESC="Používá se v k'du JavaScript , který je odesílán vašim uživatelům." NR_RECAPTCHA_SECRET_KEY="Tajný klíč" NR_RECAPTCHA_SECRET_KEY_DESC="Používá se při komunikaci mezi vaším a reCAPTCHA serverem. Uchovejte v bezpečí." NR_RECAPTCHA_SITE_KEY_ERROR="Klíč reCaptcha pro web chybí nebo není platný" NR_PREVIOUS_MONTH="Předchozí měsíc" NR_NEXT_MONTH="Následující měsíc" NR_ASSIGN_GROUP_PAGE_URL="Stránka / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Cílení na návštěvníky, kteří si prohlížejí konkrétní položky menu nebo adresy URL" NR_ASSIGN_GROUP_DATETIME_DESC="Spouštěč boxu založený na datu a čase serveru" NR_ASSIGN_GROUP_USER_VISITOR="Joomla uživatel / Návštevník" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Cílení na registrované uživatele nebo návštěvníky, kteří si prohlédli určitý počet stránek" NR_ASSIGN_GROUP_PLATFORM="Platforma návštevníka" NR_ASSIGN_GROUP_PLATFORM_DESC="Cílení na návštěvníky, kteří používají mobilní zařízení, Google Chrome nebo Windows" NR_ASSIGN_GROUP_GEO_DESC="Cílový návštěvníci, kteří jsou fyzicky v určité oblasti" NR_ASSIGN_GROUP_JCONTENT="Joomla! obsah" NR_ASSIGN_GROUP_JCONTENT_DESC="Cílení na návštěvníky, kteří si prohlížejí konkrétní články nebo kategorie systému Joomla" NR_ASSIGN_GROUP_SYSTEM="Systém / Integrace" NR_INTEGRATIONS="Integrace" NR_ASSIGN_GROUP_SYSTEM_DESC="Cílení na návštěvníky, kteří interagovali s konkrétními rozšířeními Joomla 3. stran" NR_ASSIGN_GROUP_ADVANCED="Rozšířené cílení na návštěvníky" NR_ASSIGN_USERGROUP_DESC="Zacílit na určitou skupinu Joomla uživatelů" NR_ASSIGN_ARTICLE_DESC="Cílový návštěvníci, kteří prohlížejí určité Joomla články" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Cílový návštěvníci, kteří prohlížejí určité Joomla kategorie" NR_EXTENSION_REQUIRED="%s aby kompomeneta fungovala správně, zásuvný modul %s musí být povolen." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Cílení na návštěvníky, kteří si prohlížejí konkrétní položky, kategorie nebo značky K2" NR_ASSIGN_K2_ITEMS="Položka" NR_ASSIGN_K2_ITEMS_DESC="Cílový návštěvníci, kteří procházejí určité položky K2." NR_ASSIGN_K2_ITEMS_LIST_DESC="Zvolte K2 článek k přiřazení" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Shoda s konkrétními klíčovými slovy v obsahu položky. Oddělte je čárkou nebo nebo vložením na nový řádek." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Shoda na meta klíčových slovech položky. Oddělte je čárkou nebo nebo vložením na nový řádek." NR_ASSIGN_K2_PAGETYPES_DESC="Cílový návštěvníci, kteří procházejí určité typy K2 stránek" NR_ASSIGN_K2_ITEM_OPTION="Položka" NR_ASSIGN_K2_LATEST_OPTION="Poslední položky od uživatelů nebo kategorií" NR_ASSIGN_K2_TAG_OPTION="Oštítkovat stránku" NR_ASSIGN_K2_CATEGORY_OPTION="Stránka kategorií" NR_ASSIGN_K2_ITEM_FORM_OPTION="Formulář pro úpravu položky" NR_ASSIGN_K2_USER_PAGE_OPTION="Stránka uživatele (blog)" NR_ASSIGN_K2_TAGS_DESC="Cílení na návštěvníky, kteří si prohlížejí položky K2 s konkrétními značkami" NR_ASSIGN_K2_CATEGORIES_DESC="Cílení na návštěvníky, kteří si prohlížejí konkrétní kategorie K2" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Kategorie" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Položky" NR_ASSIGN_PAGE_TYPES_DESC="Zvolte typy stránek k přiřazení" NR_ASSIGN_TAGS_DESC="Zvolte šítky k přiřazení" NR_CONTENT_KEYWORDS="Klíčová slova obsahu" NR_META_KEYWORDS="Meta klíčová slova" NR_TAG="Štítek" NR_NORMAL="Normální" NR_COMPACT="Kompaktní" NR_LIGHT="Světlý" NR_DARK="Tmavý" NR_SIZE="Velikost" NR_THEME="Šablona" NR_SINGLE="Jeden" NR_MULTIPLE="Více" NR_RANGE="Rozsah" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Prosím ověřte" NR_RECAPTCHA_INVALID_SECRET_KEY="Neplatný tajný klíč" NR_PAGE="Stránka" NR_YOU_ARE_USING_EXTENSION="Používáte %s %s" NR_UPDATE="Aktualizace" NR_SHOW_UPDATE_NOTIFICATION="Zobrazit upozornění na aktualizace" NR_SHOW_UPDATE_NOTIFICATION_DESC="Pokud je tato možnost vybrána, zobrazí se v hlavním zobrazení komponenty oznámení o aktualizaci pokaždé, když je vydána nová verze tohoto rozšíření." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s je dostupná" NR_ERROR_EMAIL_IS_DISABLED="Posílání e-mailů je vypnuté. E-maily není možné odeslat." NR_ASSIGN_ITEMS="Položka" NR_COUNTRY_AF="Afghánistán" NR_COUNTRY_AX="Ostrov Aland" NR_COUNTRY_AL="Albánie" NR_COUNTRY_DZ="Alžírsko" NR_COUNTRY_AS="Americká Samoa" NR_COUNTRY_AD="Andorra" NR_COUNTRY_AO="Angola" NR_COUNTRY_AI="Anguilla" NR_COUNTRY_AQ="Antarktida" NR_COUNTRY_AG="Antigua a Barbuda" NR_COUNTRY_AR="Argentina" NR_COUNTRY_AM="Arménie" NR_COUNTRY_AW="Aruba" NR_COUNTRY_AU="Austrálie" NR_COUNTRY_AT="Rakousko" NR_COUNTRY_AZ="Ázerbájdžán" NR_COUNTRY_BS="Bahamy" NR_COUNTRY_BH="Bahrain" NR_COUNTRY_BD="Bangladéš" NR_COUNTRY_BB="Barbados" NR_COUNTRY_BY="Bělorusko" NR_COUNTRY_BE="Belgie" NR_COUNTRY_BZ="Belize" NR_COUNTRY_BJ="Benin" NR_COUNTRY_BM="Bermudy" NR_COUNTRY_BQ_BO="Bonaire" NR_COUNTRY_BQ_SA="Saba" NR_COUNTRY_BQ_SE="Sint Eustatius" NR_COUNTRY_BT="Bhután" NR_COUNTRY_BO="Bolivie" NR_COUNTRY_BA="Bosna a Herzegovina" NR_COUNTRY_BW="Botswana" NR_COUNTRY_BV="ostrov Bouvet" NR_COUNTRY_BR="Brazílie" NR_COUNTRY_IO="Britské indickoocenánské území" NR_COUNTRY_BN="Brunei Darussalam" NR_COUNTRY_BG="Bulharsko" NR_COUNTRY_BF="Burkina Faso" NR_COUNTRY_BI="Burundi" NR_COUNTRY_KH="Kambodža" NR_COUNTRY_CM="Kamerun" NR_COUNTRY_CA="Kanada" NR_COUNTRY_CV="Kapverdy" NR_COUNTRY_KY="Kajmanské ostrovy" NR_COUNTRY_CF="Středoafrická republika" NR_COUNTRY_TD="Čad" NR_COUNTRY_CL="Chile" NR_COUNTRY_CN="Čína" NR_COUNTRY_CX="Vánoční ostrov" NR_COUNTRY_CC="Kokosové ostrovy" NR_COUNTRY_CO="Kolumbie" NR_COUNTRY_KM="Komorské ostrovy" NR_COUNTRY_CG="Kongo" NR_COUNTRY_CD="Demokratická republika Kongo" NR_COUNTRY_CK="Cookovy ostrovy" NR_COUNTRY_CR="Kostarika" NR_COUNTRY_CI="Pobřeží slonoviny" NR_COUNTRY_HR="Chrovatsko" NR_COUNTRY_CU="Kuba" NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Kypr" NR_COUNTRY_CZ="Česká republika" NR_COUNTRY_DK="Dánsko" NR_COUNTRY_DJ="Džibuti" NR_COUNTRY_DM="Dominika" NR_COUNTRY_DO="Dominikánská republika" NR_COUNTRY_EC="Ekvádor" NR_COUNTRY_EG="Egypt" NR_COUNTRY_SV="Salvador" NR_COUNTRY_GQ="Rovníková Guinea" NR_COUNTRY_ER="Eritrea" NR_COUNTRY_EE="Estonsko" NR_COUNTRY_ET="Etiopie" NR_COUNTRY_FK="Falklandy (Malvíny)" NR_COUNTRY_FO="Faerské ostrovy" NR_COUNTRY_FJ="Fiji" NR_COUNTRY_FI="Finsko" NR_COUNTRY_FR="Francie" NR_COUNTRY_GF="Francouzská Guyana" NR_COUNTRY_PF="Francouzská Guyana" NR_COUNTRY_TF="Francouzská jižní a antarktická území" NR_COUNTRY_GA="Gabon" NR_COUNTRY_GM="Gambie" NR_COUNTRY_GE="Gruzie" NR_COUNTRY_DE="Německo" NR_COUNTRY_GH="Ghana" NR_COUNTRY_GI="Gibraltar" NR_COUNTRY_GR="Řecko" NR_COUNTRY_GL="Greenland" NR_COUNTRY_GD="Grenada" NR_COUNTRY_GP="Guadeloupe" NR_COUNTRY_GU="Guam" NR_COUNTRY_GT="Guatemala" NR_COUNTRY_GG="Guernsey" NR_COUNTRY_GN="Guinea" NR_COUNTRY_GW="Guinea-Bissau" NR_COUNTRY_GY="Guyana" NR_COUNTRY_HT="Haiti" NR_COUNTRY_HM="Heardův ostrov a McDonaldovy ostrovy" NR_COUNTRY_VA="Svatý stolec (Vatikán)" NR_COUNTRY_HN="Honduras" NR_COUNTRY_HK="Hong Kong" NR_COUNTRY_HU="Maďarsko" NR_COUNTRY_IS="Island" NR_COUNTRY_IN="Indie" NR_COUNTRY_ID="Indonézie" NR_COUNTRY_IR="Írán" NR_COUNTRY_IQ="Irák" NR_COUNTRY_IE="Irsko" NR_COUNTRY_IM="ostrov Man" NR_COUNTRY_IL="Izrael" NR_COUNTRY_IT="Itálie" NR_COUNTRY_JM="Jamaika" NR_COUNTRY_JP="Japonsko" NR_COUNTRY_JE="Jersey" NR_COUNTRY_JO="Jordánsko" NR_COUNTRY_KZ="Kazachstán" NR_COUNTRY_KE="Keňa" NR_COUNTRY_KI="Kiribati" NR_COUNTRY_KP="Jižní Korea" NR_COUNTRY_KR="Severní Korea" NR_COUNTRY_KW="Kuvajt" NR_COUNTRY_KG="Kyrgyzstán" NR_COUNTRY_LA="Laos" NR_COUNTRY_LV="Lotyšsko" NR_COUNTRY_LB="Libanon" NR_COUNTRY_LS="Lesotho" NR_COUNTRY_LR="Libérie" NR_COUNTRY_LY="Lybie" NR_COUNTRY_LI="Lichtenštejnsko" NR_COUNTRY_LT="Litva" NR_COUNTRY_LU="Lucembursko" NR_COUNTRY_MO="Macao" NR_COUNTRY_MK="Makedonie" NR_COUNTRY_MG="Madagascar" NR_COUNTRY_MW="Malawi" NR_COUNTRY_MY="Malajsie" NR_COUNTRY_MV="Maledivy" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Malta" NR_COUNTRY_MH="Marshallovy ostrovy" NR_COUNTRY_MQ="Martinik" NR_COUNTRY_MR="Mauretánie" NR_COUNTRY_MU="Mauritius" NR_COUNTRY_YT="Mayotte" NR_COUNTRY_MX="Mexiko" NR_COUNTRY_FM="Federativní státy Mikronésie" NR_COUNTRY_MD="Moldavsko" NR_COUNTRY_MC="Monako" NR_COUNTRY_MN="Mongolsko" NR_COUNTRY_ME="Černá Hora" NR_COUNTRY_MS="Montserrat" NR_COUNTRY_MA="Maroko" NR_COUNTRY_MZ="Mozambik" NR_COUNTRY_MM="Myanmar (Barma)" NR_COUNTRY_NA="Namibie" NR_COUNTRY_NR="Nauru" NR_COUNTRY_NM="Severní Makedonie" NR_COUNTRY_NP="Nepál" NR_COUNTRY_NL="Nizozemí" NR_COUNTRY_AN="Nizozemské Antily" NR_COUNTRY_NC="Nová Kaledonie" NR_COUNTRY_NZ="Nový Zéland" NR_COUNTRY_NI="Nikaragua" NR_COUNTRY_NE="Niger" NR_COUNTRY_NG="Nigerie" NR_COUNTRY_NU="Niue" NR_COUNTRY_NF="ostrov Norfolk" NR_COUNTRY_MP="Severní Mariany" NR_COUNTRY_NO="Norsko" NR_COUNTRY_OM="Omán" NR_COUNTRY_PK="Pákistan" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Okupovaná palestinská území" NR_COUNTRY_PA="Panama" NR_COUNTRY_PG="Papua-Nová Guinea" NR_COUNTRY_PY="Paraguay" NR_COUNTRY_PE="Peru" NR_COUNTRY_PH="Filipíny" NR_COUNTRY_PN="Pitcairnovy ostrovy" NR_COUNTRY_PL="Polsko" NR_COUNTRY_PT="Portugalsko" NR_COUNTRY_PR="Portoriko" NR_COUNTRY_QA="Katar" NR_COUNTRY_RE="Reunion" NR_COUNTRY_RO="Rumunsko" NR_COUNTRY_RU="Ruská federace" NR_COUNTRY_RW="Rwanda" NR_COUNTRY_SH="Svatá Helena" NR_COUNTRY_KN="Svatý Kryštof a Nevis" NR_COUNTRY_LC="Svatá Lucie" NR_COUNTRY_PM="Saint Pierre a Miquelon" NR_COUNTRY_VC="Svatý Vincenc a Grenadiny" NR_COUNTRY_WS="Samoa" NR_COUNTRY_SM="San Marino" NR_COUNTRY_ST="Sao Tome a Principe" NR_COUNTRY_SA="Saúdská Arábie" NR_COUNTRY_SN="Senegal" NR_COUNTRY_RS="Srbsko" NR_COUNTRY_SC="Seychelly" NR_COUNTRY_SL="Sierra Leone" NR_COUNTRY_SG="Singapur" NR_COUNTRY_SK="Slovensko" NR_COUNTRY_SI="Slovinsko" NR_COUNTRY_SB="Šalamounovy ostrovy " NR_COUNTRY_SO="Somálsko" NR_COUNTRY_ZA="Jižní Afrika" NR_COUNTRY_GS="Jižní Georgie a Jižní Sandwichovy ostrovy" NR_COUNTRY_ES="Španělsko" NR_COUNTRY_LK="Srí Lanka" NR_COUNTRY_SD="Súdán" NR_COUNTRY_SS="Jižní Súdán" NR_COUNTRY_SR="Surinam" NR_COUNTRY_SJ="Špicberky a Jan Mayen" NR_COUNTRY_SZ="Svazijsko" NR_COUNTRY_SE="Švédsko" NR_COUNTRY_CH="Švýcarsko" NR_COUNTRY_SY="Sýrie" NR_COUNTRY_TW="Tchaj-wan" NR_COUNTRY_TJ="Tádžikistán" NR_COUNTRY_TZ="Tanzánie" NR_COUNTRY_TH="Thajsko" NR_COUNTRY_TL="Východní Timor" NR_COUNTRY_TG="Togo" NR_COUNTRY_TK="Tokelau" NR_COUNTRY_TO="Tonga" NR_COUNTRY_TT="Trinidad a Tobago" NR_COUNTRY_TN="Tunisko" NR_COUNTRY_TR="Turecko" NR_COUNTRY_TM="Turkmenistán" NR_COUNTRY_TC="ostrovy Turks a Caicos" NR_COUNTRY_TV="Tuvalu" NR_COUNTRY_UG="Uganda" NR_COUNTRY_UA="Ukrajina" NR_COUNTRY_AE="Spojené arabské emiráty" NR_COUNTRY_GB="Velká Británie" NR_COUNTRY_US="Spojené státy americké" NR_COUNTRY_UM="Menší odlehlé ostrovy USA" NR_COUNTRY_UY="Uruguay" NR_COUNTRY_UZ="Uzbekistán" NR_COUNTRY_VU="Vanuatu" NR_COUNTRY_VE="Venezuela" NR_COUNTRY_VN="Vietnam" NR_COUNTRY_VG="Britské Panenské ostrovy" NR_COUNTRY_VI="Britské Panenské ostrovy" NR_COUNTRY_WF="Wallis a Futuna" NR_COUNTRY_EH="Západní Sahara" NR_COUNTRY_YE="Jemen" NR_COUNTRY_ZM="Zambie" NR_COUNTRY_ZW="Zimbabwe" NR_CONTINENT_AF="Afrika" NR_CONTINENT_AS="Asie" NR_CONTINENT_EU="Evropa" NR_CONTINENT_NA="Severní Amerika" NR_CONTINENT_SA="Jižní Amerika" NR_CONTINENT_OC="Oceánie" NR_CONTINENT_AN="Antarktida" NR_FRONTEND="Front-end" NR_BACKEND="Administrace" NR_EMBED="Vložený kód" NR_RATE="Ohodnoťte %s" NR_REPORT_ISSUE="Nahlásit chybu" NR_RESPONSIVE_CONTROL_TITLE="Nastavení hodnoty pro zařízení" NR_TAG_PAGEGENERATOR="Generátor stránky" NR_TAG_PAGELANGURL="URL stránky jazyka" NR_TAG_PAGEKEYWORDS="Klíčová slova stránky" NR_TAG_SITEEMAIL="E-mail stránky" NR_TAG_DAY="Den" NR_TAG_MONTH="Měsíc" NR_TAG_YEAR="Rok" NR_TAG_USERREGISTERDATE="Datum registrace" NR_TAG_PAGEBROWSERTITLE="Název stránky v prohlížeči" NR_TAG_EBID="ID Boxu" NR_TAG_EBTITLE="Název boxu" NR_TAG_QUERYSTRINGOPTION="Řetězec dotazu : Možnosti" NR_TAG_QUERYSTRINGVIEW="Řetězec dotazu : Zobrazení" NR_TAG_QUERYSTRINGLAYOUT="Řetězec dotazu : Vzhled" NR_TAG_QUERYSTRINGTMPL="Řetězec dotazu : Šablona" NR_CANNOT_CREATE_FOLDER="Nelze vytvořit adresář nebo přesunout soubor. %s" NR_CANNOT_MOVE_FILE="Nelze přesunout soubor: %s" NR_UPLOAD_INVALID_FILE_TYPE="Nepodporovaný typ souboru: %s (%s). Povolené typy souborů jsou: %s" NR_UPLOAD_NO_MIME_TYPE="Nelze odhadnout typ mime souboru: %s. Zkontrolujte, zda je povoleno rozšíření PHP fileinfo." NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Nelze nahrát soubor: %s" NR_START_OVER="Začít znovu" NR_TRY_AGAIN="Zkusit zvova" NR_ERROR="Chyba" NR_CANCEL="Zrušit" NR_PLEASE_WAIT="Prosím čekejte" NR_STAR="hvězda%s" NR_HCAPTCHA="hCaptcha" NR_TYPE="Typ" NR_CHECKBOX="Zaškrtávací políčko" NR_INVISIBLE="Neviditelný" NR_HCAPTCHA_DESC="Chcete-li získat web a tajný klíč pro svou doménu, přejděte na stránku https://dashboard.hcaptcha.com/sites." NR_HCAPTCHA_SECRET_KEY_DESC="Používá se při komunikaci mezi vaším serverem a serverem hCaptcha. Ujistěte se, že jej uchováte v tajnosti." NR_OUTDATED_EXTENSION="Vaše verze %s je starší než %d dní a s největší pravděpodobností je již zastaralá. Zkontrolujte prosím, zda nebyla vydána %snovější verze%s a nainstalujte ji." NR_GENERAL="Obecné" NR_GALLERY_MANAGER_BROWSE="Procházet" NR_GALLERY_MANAGER_ADD_IMAGES="Vložit obrázky" NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Procházet knihovnu médií" NR_GALLERY_MANAGER_REMOVE_IMAGES="Odstranit všechny opbrázky" NR_GALLERY_MANAGER_TITLE_HINT="Zadejte název" NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Popis" NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Vložte popis" NR_GALLERY_MANAGER_FILE_MISSING="Soubor chybí. Zkuste jej nahrát znovu." NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Chybí nastavení widgetu." NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Nastavení widgetu je neplatné." NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Soubor nelze nahrát" NR_GALLERY_MANAGER_ERROR_INVALID_FILE="Tento soubor vypadá nebezpečně nebo je neplatný, proto ho nelze nahrát." NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Opravdu chcete odstranit všechny položky galerie?" NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Opravdu chcete odstranit všechny vybrané položky galerie?" NR_GALLERY_MANAGER_CONFIRM_DELETE="Opravdu chcete tuto položku galerie odstranit?" NR_GALLERY_MANAGER_IN_QUEUE="Ve frontě" NR_GALLERY_MANAGER_UPLOADING="Nahrávání..." NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Odstranění vybraných obrázků" NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Zkontrolujte, zda chcete odstranit více obrázků" NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Kliknutím odstraníte obrázek" NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Vybrat vše" NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Zrušit výběr všeho" NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Výběr nebo zrušení výběru všech obrázků" NR_GALLERY_MANAGER_ADD_DROPDOWN="Zobrazit/skrýt možnosti nabídky" NR_GALLERY_MANAGER_SELECT_ITEM="Vyberte položku galerie" NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Přetáhněte obrázky sem nebo" NR_TECHNOLOGY="Technologie" NR_ENGAGEBOX_SELECT_BOX="Vybrané boxy" NR_CONTENT_ARTICLE="Obsah článku" NR_CONTENT_CATEGORY="Kategore obsahu" NR_VIEWED_ANOTHER_BOX="EngageBox - Zobrazeno další vyskakovací okno" NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Kampaň" NR_K2_ITEM="K2 - Položka" NR_K2_CATEGORY="K2 - Kategorie" NR_K2_TAG="K2 - Štítek" NR_K2_PAGE_TYPE="K2 - Typ stránky" NR_AKEEBASUBS_LEVEL="AkeebaSubs Úroveň" NR_CB_SELECT_CONDITION="Zvolte podmínku" NR_CB_ADD_CONDITION_GROUP="Přidat sadu podmínek" NR_CB_SELECT_CONDITION_GET_STARTED="Chcete-li začít, vyberte podmínku." NR_CB_TRASH_CONDITION="Smazat podmínku" NR_CB_TRASH_CONDITION_GROUP="Smazat skupinu podmínek" NR_CB_ADD_CONDITION="Přidat podmínku" NR_CB_SHOW_WHEN="Zobrazit, když" NR_CB_OF_THE_CONDITIONS_MATCH="jsou splněny níže uvedené podmínky" NR_PHP_COLLECTION_SCRIPTS="K dispozici je sbírka skriptů PHP připravených k použití.. Zobrazit sbírku" NR_IS="Je" NR_IS_NOT="Není" NR_IS_EMPTY="Je prázdný" NR_IS_NOT_EMPTY="Není prázdný" NR_IS_BETWEEN="Je mezi" NR_IS_NOT_BETWEEN="Není mezi" NR_DISPLAY_CONDITIONS_LOADING="Načítání podmínek zobrazení..." NR_CB_TOGGLE_RULE_GROUP_STATUS="Povolení nebo zakázání sady podmínek" NR_CB_TOGGLE_RULE_STATUS="Povolit nebo zakázat podmínku" NR_DISPLAY_CONDITIONS_HINT_DATE="Čas a datum na vašem serveru je %s." NR_DISPLAY_CONDITIONS_HINT_TIME="Čas na veašem serveru je %s." NR_DISPLAY_CONDITIONS_HINT_DAY="Dnes je %s." NR_DISPLAY_CONDITIONS_HINT_MONTH="Aktuální měsíc je %s." NR_DISPLAY_CONDITIONS_HINT_USERID="ID účtu, ke kterému jste přihlášeni, je %s." NR_DISPLAY_CONDITIONS_HINT_USERGROUP="K přihlášenému účtu jsou přiřazeny tyto skupiny uživatelů: %s." NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="Úrovně přístupu k prohlížení přiřazené přihlášenému účtu jsou následující: %s." NR_DISPLAY_CONDITIONS_HINT_DEVICE="Typ zařízení, které používáte, je %s." NR_DISPLAY_CONDITIONS_HINT_BROWSER="Prohlížeč, který používáte je %s." NR_DISPLAY_CONDITIONS_HINT_OS="Operační systém, který používáte, je %s." NR_DISPLAY_CONDITIONS_HINT_GEO="Na základě vaší IP adresy (%s), %s se fyzicky nacházíte v %s." NR_DISPLAY_CONDITIONS_HINT_IP="Vaše IP adresa je %s." NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Na základě vaší IP adresy (%s), jsme nemohli určit, kde se fyzicky nacházíte." NR_GEO_MAINTENANCE="Údržba geolokační databáze" NR_GEO_MAINTENANCE_DESC="Databáze používaná k určení zeměpisné polohy návštěvníků je zastaralá nebo není nainstalována. Klikněte prosím na spodní část níže a databázi aktualizujte. Doporučujeme vám, abyste ji aktualizovali alespoň jednou za měsíc." NR_EDIT="Upravit" NR_GEO_PLUGIN_DISABLED="Geolokační zásuvný modul je vypnutý" NR_GEO_PLUGIN_DISABLED_DESC="Aktivujte prosím plugin %s\"System - Tassos.gr GeoIP Plugin\"%s , aby bylo možné používat geolokační služby." NR_INVALID_IMAGE_PATH="Neplatná cesta k obrázku: %s" PK!Bsystem/nrframework/language/tr-TR/tr-TR.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Sistem - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - geliştirici Tassos.gr eklentileri" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE ; NR_IGNORE="Ignore" ; NR_INCLUDE="Include" ; NR_EXCLUDE="Exclude" NR_SELECTION="Seçim" ; NR_ASSIGN_MENU_NOITEM="Include no Itemid" ; NR_ASSIGN_MENU_NOITEM_DESC="Also assign when no menu Itemid is set in URL?" ; NR_ASSIGN_MENU_CHILD="Also on child items" ; NR_ASSIGN_MENU_CHILD_DESC="Also assign to child items of the selected items?" NR_COPY_OF="%s kopyası" ; NR_ASSIGN_DATETIME_DESC="Target visitors based on your server's datetime" NR_DATETIME="Tarihsaat" NR_TIME="Zaman" NR_DATE="Tarih" NR_DATETIME_DESC="Otomatik olarak yayınla/yayınlama tarihi girin" ; NR_START_PUBLISHING="Start Datetime" NR_START_PUBLISHING_DESC="Yayınlanmaya başlama tarihini girin" ; NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="Yayınlamayı bitirmek için tarihi girin" NR_DATETIME_NOTE="Tarih ve saat atamaları, ziyaretçilerin sistem tarihlerini değil, sunucularınızın tarih/saatini kullanır." ; NR_ASSIGN_PHP="PHP" ; NR_PHPCODE="PHP Code" ; NR_ASSIGN_PHP_DESC="Enter a piece of PHP code to evaluate." ; NR_ASSIGN_PHP_DESC2="Target visitors evaluating custom PHP code. The code must return the value true or false.

For instance:
return ($user->name == 'Tassos Marinos');" ; NR_ASSIGN_TIMEONSITE="Time on Site" NR_SECONDS="Saniye" NR_ASSIGN_TIMEONSITE_DESC="Sitenizin tamamında geçirilen kullanıcının toplam zamanı (Ziyaret süresi) ile karşılaştırmak için saniye cinsinden bir süre girin. Örnek:
Kullanıcı, sitenizin tamamında 3 dakika geçirdikten sonra bir kutu görüntülemek istiyorsanız, 180 girin." NR_ASSIGN_URLS="URL" ; NR_ASSIGN_URLS_DESC2="Target visitors who are browsing specific URLs" NR_ASSIGN_URLS_DESC="Eşleştirilecek URL'lerin (bir kısmını) girin.
Her farklı eşleşmeler için yeni bir çizgi kullanın." NR_ASSIGN_URLS_LIST="URL Eşleşmeler" ; NR_ASSIGN_URLS_REGEX="Use Regular Expression" NR_ASSIGN_URLS_REGEX_DESC="Değeri normal ifadeler olarak kabul etmek için seçin." NR_ASSIGN_LANGS="Dil" ; NR_ASSIGN_LANGS_DESC="Target visitors who are browsing your website in specific language" NR_ASSIGN_LANGS_LIST_DESC="Atamak istediğiniz Dilleri seçin" NR_ASSIGN_DEVICES="Aygıt" ; NR_ASSIGN_DEVICES_DESC2="Target visitors using specific device such as Mobile, Tablet or Desktop." NR_ASSIGN_DEVICES_DESC="Atanacak aygıtları seçin." ; NR_ASSIGN_DEVICES_NOTE="Keep in mind that device detection is not always 100% accurate. Users can setup their browser to mimic other devices" ; NR_MENU="Menu" ; NR_MENU_ITEMS="Menu Item" ; NR_MENU_ITEMS_DESC="Target visitors who are browsing specific menu items" ; NR_USERGROUP="User Group" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." ; NR_ACCESSLEVEL="User Group" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Telif hakkı göster" NR_SHOW_COPYRIGHT_DESC="Seçilirse, ekstra telif hakkı bilgisi yönetici görünümlerinde görüntülenecektir. Tassos.gr uzantıları hiçbir zaman ön uçta telif hakkı bilgisi veya geri bağlantıları göstermez." NR_WIDTH="Genişlik" NR_WIDTH_DESC="Genişliği px, em veya % olarak Örnek: 400px" NR_HEIGHT="Yükseklik" NR_HEIGHT_DESC="Yüksekliği px, em veya % olarak Örnek: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Padding px, em veya % cinsinden Örnek: 20px" ; NR_MARGIN="Margin" ; NR_MARGIN_DESC="The CSS margin propertiy is used to generate space around the box and set the size of the white space outside the border in pixels or in %.

Example 1: 25px
Example 2: 5%

Specifying the margin for each side [top right bottom left]:

Top side only: 25px 0 0 0
Right side only: 0 25px 0 0
Bottom side only: 0 0 25px 0
Left side only: 0 0 0 25px" ; NR_COLOR_HOVER="Hover Color" NR_COLOR="Renk" NR_COLOR_DESC="Bir renk, HEX veya RGBA formatında tanımlayın." NR_TEXT_COLOR="Metin Rengi" ; NR_BACKGROUND="Background" NR_BACKGROUND_COLOR="Arkaplan Rengi" ; NR_BACKGROUND_COLOR_DESC="Define a background color in HEX or RGBA format. To disable enter 'none'. For absolute transparency enter 'transparent'." ; NR_URL_SHORTENING_FAILED="Shortening %s with %s failed. %s." ; NR_EXPORT="Export" ; NR_IMPORT="Import" ; NR_PLEASE_CHOOSE_A_VALID_FILE="Please choose a valid filename" ; NR_IMPORT_ITEMS="Import Items" ; NR_PUBLISH_ITEMS="Publish items" ; NR_AS_EXPORTED="As exported" ; NR_TITLE="Title" ; NR_ACYMAILING="AcyMailing" ; NR_ACYMAILING_LIST="AcyMailing List" ; NR_ACYMAILING_LIST_DESC="Select AcyMailing lists to assign to." ; NR_ASSIGN_ACYMAILING_DESC="Target visitors who have subscribed to specific AcyMailing lists" ; NR_AKEEBASUBS="Akeeba Subscriptions" ; NR_AKEEBASUBS_LEVELS="Levels" ; NR_AKEEBASUBS_LEVELS_DESC="Select Akeeba Subscription levels to assign to." ; NR_ASSIGN_AKEEBASUBS_DESC="Target visitors who have subscribed to specific Akeeba Subscriptions" ; NR_MATCH="Match" ; NR_MATCH_DESC="The used matching method to compare the value" ; NR_ASSIGN_MATCHING_METHOD="Matching Method" ; NR_ASSIGN_MATCHING_METHOD_DESC="Should all or any assignments be matched?

All
Will be published if All of below assignments are matched.

Any
Will be published if Any (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." ; NR_ANY="Any" ; NR_ALL="All" ; NR_ASSIGN_REFERRER="Referrer URL" ; NR_ASSIGN_REFERRER_DESC2="Target visitors who land on your site from a specific traffic source" ; NR_ASSIGN_REFERRER_DESC="Enter one Referrer URL per line: Eg:

google.com
facebook.com/mypage" ; NR_ASSIGN_REFERRER_NOTE="Keep in mind that URL Referrer discovery is not always 100% accurate. Some servers may use proxies that strip this information out and it can be easily forged." ; NR_PROFEATURE_HEADER="%s is a PRO Feature" ; NR_PROFEATURE_DESC="We're sorry, %s is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features." ; NR_PROFEATURE_DISCOUNT="Bonus: %s free users get 20% off regular price, automatically applied at checkout." ; NR_ONLY_AVAILABLE_IN_PRO="Only available in PRO version" ; NR_UPGRADE_TO_PRO="Upgrade to Pro" ; NR_UPGRADE_TO_PRO_TO_UNLOCK="Upgrade to Pro version to unlock" ; NR_UPGRADE_TO_PRO_VERSION="Awesome! Only one step left. Click on the button below to complete the upgrade to the Pro version." ; NR_UNLOCK_PRO_FEATURE="Unlock Pro Feature" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." ; NR_LEFT_TO_RIGHT="Left to Right" ; NR_RIGHT_TO_LEFT="Right to Left" ; NR_BGIMAGE="Background Image" ; NR_BGIMAGE_DESC="Sets a background image" ; NR_BGIMAGE_FILE="Image" ; NR_BGIMAGE_FILE_DESC="Select or a upload a file for the background-image." ; NR_BGIMAGE_REPEAT="Repeat" ; NR_BGIMAGE_REPEAT_DESC="The background-repeat property sets if/how a background image will be repeated. By default, a background-image is repeated both vertically and horizontally.

Repeat: The background image will be repeated both vertically and horizontally.

Repeat-x: The background image will be repeated only horizontally

Repeat-y: The background image will be repeated only vertically

No-repeat: The background-image will not be repeated" ; NR_BGIMAGE_SIZE="Size" ; NR_BGIMAGE_SIZE_DESC="Specify the size of a background image.

Auto:The background-image contains its width and height

Cover: Scale the background image to be as large as possible so that the background area is completely covered by the background image. Some parts of the background image may not be in view within the background positioning area

Contain: Scale the image to the largest size such that both its width and its height can fit inside the content area

100% 100%: Stretch the background image to completely cover the content area." ; NR_BGIMAGE_POSITION="Position" ; NR_BGIMAGE_POSITION_DESC="The background-position property sets the starting position of a background image. By default, a background-image is placed at the top-left corner. The first value is the horizontal position and the second value is the vertical.

You can use either one of the predefined values, or enter a custom value in percentage: x% y% or in pixel xPos yPos." ; NR_RTL="Enable RTL" ; NR_RTL_DESC="The right-to-left text direction is essential for right-to-left scripts such as Arabic, Hebrew, Syriac, and Thaana." ; NR_HORIZONTAL="Horizontal" ; NR_VERTICAL="Vertical" ; NR_FORM_ORIENTATION="Form Orientation" ; NR_FORM_ORIENTATION_DESC="Select the form orientation" ; NR_ASSIGN_CATEGORY="Categories" ; NR_ASSIGN_CATEGORY_DESC="Select the categories to assign to" ; NR_ASSIGN_CATEGORY_CHILD="Also on child items" ; NR_ASSIGN_CATEGORY_CHILD_DESC="Also assign to child items of the selected items?" ; NR_NEW="New" ; NR_LIST="List" ; NR_DOCUMENTATION="Documentation" ; NR_KNOWLEDGEBASE="Knowledgebase" ; NR_FAQ="FAQ" ; NR_INFORMATION="Information" ; NR_EXTENSION="Extension" ; NR_VERSION="Version" ; NR_CHANGELOG="Changelog" ; NR_DOWNLOAD="Download" ; NR_DOWNLOAD_KEY_MISSING="Download Key is missing" ; NR_DOWNLOAD_KEY="Download Key" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." ; NR_DOWNLOAD_KEY_HOW="To be able to update %s via the Joomla updater, you will need enter your Download Key in the settings of the Novarain Framework Plugin" ; NR_DOWNLOAD_KEY_FIND="Find Download Key" ; NR_DOWNLOAD_KEY_UPDATE="Update Download Key" ; NR_OK="OK" ; NR_MISSING="Missing" ; NR_LICENSE="License" ; NR_AUTHOR="Author" ; NR_FOLLOWME="Follow me" ; NR_FOLLOW="Follow %s" ; NR_TRANSLATE_INTEREST="Would you be interested in helping out with translating %s into your Language?" ; NR_TRANSIFEX_REQUEST="Send me a request on Transifex" ; NR_HELP_WITH_TRANSLATIONS="Help with translations" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" ; NR_ADVANCED="Advanced" ; NR_USEGLOBAL="Use Global" ; NR_WEEKDAY="Day of Week" ; NR_MONTH="Month" ; NR_MONDAY="Monday" ; NR_TUESDAY="Tuesday" ; NR_WEDNESDAY="Wednesday" ; NR_THURSDAY="Thursday" ; NR_FRIDAY="Friday" ; NR_SATURDAY="Saturday" ; NR_WEEKEND="Weekend" ; NR_WEEKDAYS="Weekdays" ; NR_SUNDAY="Sunday" ; NR_JANUARY="January" ; NR_FEBRUARY="February" ; NR_MARCH="March" ; NR_APRIL="April" ; NR_MAY="May" ; NR_JUNE="June" ; NR_JULY="July" ; NR_AUGUST="August" ; NR_SEPTEMBER="September" ; NR_OCTOBER="October" ; NR_NOVEMBER="November" ; NR_DECEMBER="December" ; NR_NEVER="Never" NR_SECONDS="Saniye" ; NR_MINUTES="Minutes" ; NR_HOURS="Hours" ; NR_DAYS="Days" ; NR_SESSION="Session" ; NR_EVER="Ever" ; NR_COOKIE="Cookie" ; NR_BOTH="Both" ; NR_NONE="None" ; NR_NONE_SELECTED="None Selected" ; NR_DESKTOPS="Desktop" ; NR_MOBILES="Mobile" ; NR_TABLETS="Tablet" ; NR_PER_SESSION="Per Session" ; NR_PER_DAY="Per Day" ; NR_PER_WEEK="Per Week" ; NR_PER_MONTH="Per Month" ; NR_FOREVER="Forever" ; NR_FEATURE_UNDER_DEV="This feature is under development" ; NR_LIKE_THIS_EXTENSION="Like this extension?" ; NR_LEAVE_A_REVIEW="Leave a review on JED" ; NR_SUPPORT="Support" ; NR_NEED_SUPPORT="Need support?" ; NR_DROP_EMAIL="Drop me an e-mail" ; NR_READ_DOCUMENTATION="Read the Documentation" ; NR_COPYRIGHT="%s - Tassos.gr All Rights Reserved" ; NR_DASHBOARD="Dashboard" ; NR_NAME="Name" ; NR_WRONG_COORDINATES="The coordinates you provided are not valid" ; NR_ENTER_COORDINATES="Latitude,Longitude" ; NR_NO_ITEMS_FOUND="No Items Found" ; NR_ITEM_IDS="No Item IDs" ; NR_TOGGLE="Toggle" ; NR_EXPAND="Expand" ; NR_COLLAPSE="Collapse" ; NR_SELECTED="Selected" ; NR_MAXIMIZE="Maximize" ; NR_MINIMIZE="Minimize" NR_SELECTION="Seçim" ; NR_INSTALL="Install" ; NR_INSTALL_NOW="Install Now" ; NR_INSTALLED="Installed" ; NR_COMING_SOON="Coming soon" ; NR_ROADMAP="On the roadmap" ; NR_MEDIA_VERSIONING="Use Media Versioning" ; NR_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." ; NR_LOAD_JQUERY="Load jQuery" ; NR_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." ; NR_SELECT_CURRENCY="Select a Currency" ; NR_CONVERTFORMS="Convert Forms" ; NR_CONVERTFORMS_LIST="Campaign" ; NR_ASSIGN_CONVERTFORMS_DESC="Target visitors who have subscribed to specific ConvertForms campaigns" ; NR_CONVERTFORMS_LIST_DESC="Select ConvertForms campaigns to assign to." NR_LEFT="Sol" NR_CENTER="Ortala" NR_RIGHT="Sağ" NR_BOTTOM="Alt" NR_TOP="Üst" NR_AUTO="Otomatik" NR_CUSTOM="Özel" NR_UPLOAD="Yükle" NR_IMAGE="Resim" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" NR_IMAGE_SELECT="Resim Seç" NR_IMAGE_SIZE_COVER="Cover" NR_IMAGE_SIZE_CONTAIN="Contain" NR_REPEAT="Repeat" NR_REPEAT_X="Repeat x" NR_REPEAT_Y="Repeat y" NR_REPEAT_NO="No repeat" NR_FIELD_STATE_DESC="Öğe durumunu ayarla" NR_CREATED_DATE="Oluşturma Tarihi" NR_CREATED_DATE_DESC="Haberin oluşturulduğu tarih" NR_MODIFIFED_DATE="Değiştirilme Tarihi" NR_MODIFIFED_DATE_DESC="Haberin son değiştirilme tarihi." ; NR_CATEGORIES="Category" NR_CATEGORIES_DESC="Atanacak kategorileri seçin." NR_ALSO_ON_CHILD_ITEMS="Ayrıca çocuklar için" NR_ALSO_ON_CHILD_ITEMS_DESC="Ayrıca seçili öğelerin alt öğelerine atamak mı istiyorsunuz?" ; NR_PAGE_TYPE="Page type" NR_PAGE_TYPES="Sayfa türleri" NR_PAGE_TYPES_DESC="Atamanın hangi sayfa türlerinde olması gerektiğini seçin." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" ; NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" ; NR_CATEGORY_VIEW="Category View" ; NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Makaleler" NR_ARTICLES_DESC="Atanacak makaleleri seçin." NR_ARTICLE="Makale" NR_ARTICLE_AUTHORS="Yazarlar" NR_ARTICLE_AUTHORS_DESC="Atanacak yazarları seçin." NR_ONLY="Sadece" NR_OTHERS="Diğerleri" ; NR_SMARTTAGS="Smart Tags" NR_SMARTTAGS_SHOW="Akıllı Etiketleri Göster" ; NR_SMARTTAGS_NOTFOUND="No Smart Tags found" ; NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" NR_CONTACT_US="Bize Ulaşın" NR_FONT_COLOR="Yazı Rengi" NR_FONT_SIZE="Yazı Boyutu" NR_FONT_SIZE_DESC="Piksel cinsinden bir font boyutu seçin" NR_TEXT="Metin" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Çıktıyı geçersiz kılmayı etkinleştir" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Sayfa düzeni (tmpl) geçersiz kılındığında uzantı oluşturma işlemini etkinleştirir. Örnekler: tmpl=bileşen veya tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Biçim Geçersiz Kıl seçeneğini etkinleştirin" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Sayfa biçimi HTML haricinde olmadığında uzantı oluşturmayı etkinleştirir. Örnekler: format=raw veya format=json." NR_GEOLOCATING="Coğrafi konumlandırma" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="Coğrafi konumlandırma her zaman %100 doğru değildir. Konum bilgisi, ziyaretçinin IP adresine dayanır. Tüm IP adresleri sabit veya bilinmektedir." ; NR_CITY="City" ; NR_CITY_NAME="City Name" ; NR_CONDITION_CITY_DESC="Enter a city name in English. Enter multiple cities separated by comma." ; NR_CONTINENT="Continent" ; NR_REGION="Region" ; NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." ; NR_ASSIGN_COUNTRIES="Country" ; NR_ASSIGN_COUNTRIES_DESC2="Target visitors who are physically in a specific country" NR_ASSIGN_COUNTRIES_DESC="Atamak istediğiniz ülkeleri seçin" ; NR_ASSIGN_CONTINENTS="Continent" NR_ASSIGN_CONTINENTS_DESC="Atamak için kıtaları seçin" ; NR_ASSIGN_CONTINENTS_DESC2="Target visitors who are physically in a specific continent" ; NR_ICONTACT_ACCOUNTID_ERROR="The iContact AccountID could not be retrieved" ; NR_TAG_CLIENTDEVICE="Visitor Device Type" ; NR_TAG_CLIENTOS="Visitor Operating System" ; NR_TAG_CLIENTBROWSER="Visitor Browser" ; NR_TAG_CLIENTUSERAGENT="Visitor Agent String" ; NR_TAG_IP="Visitor IP Address" ; NR_TAG_URL="Page URL" ; NR_TAG_URLENCODED="Page URL Encoded" ; NR_TAG_URLPATH="Page Path" ; NR_TAG_REFERRER="Page Referrer" ; NR_TAG_SITENAME="Site Name" ; NR_TAG_SITEURL="Site URL" ; NR_TAG_PAGETITLE="Page Title" ; NR_TAG_PAGEDESC="Page Meta Description" ; NR_TAG_PAGELANG="Page Language Code" ; NR_TAG_USERID="User ID" ; NR_TAG_USERNAME="User Full Name" ; NR_TAG_USERLOGIN="User Login" ; NR_TAG_USEREMAIL="User Email" ; NR_TAG_USERFIRSTNAME="User First Name" ; NR_TAG_USERLASTNAME="User Last Name" ; NR_TAG_USERGROUPS="User Groups IDs" ; NR_TAG_DATE="Date" ; NR_TAG_TIME="Time" ; NR_TAG_RANDOMID="Random ID" ; NR_ICON="Icon" ; NR_SELECT_MODULE="Select a Module" ; NR_SELECT_CONTINENT="Select a Continent" ; NR_SELECT_COUNTRY="Select a Country" ; NR_PLUGIN="Plugin" ; NR_GMAP_KEY="Google Maps API Key" ; NR_GMAP_KEY_DESC="The Google Maps API Key is being used by Tassos.gr extensions. If you face any troubles with a Google Map not being loaded then you probably need to enter your own API Key." ; NR_GMAP_FIND_KEY="Get an API key" ; NR_ARE_YOU_SURE="Are you sure?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" ; NR_CUSTOMURL="Custom URL" ; NR_SAMPLE="Sample" ; NR_DEBUG="Debug" ; NR_CUSTOMURL="Custom URL" ; NR_READMORE="Read More" ; NR_IPADDRESS="IP Address" ; NR_ASSIGN_BROWSERS="Browser" ; NR_ASSIGN_BROWSERS_DESC="Select the browsers to assign to" ; NR_ASSIGN_BROWSERS_DESC2="Target visitors who are browsing your site with specific browsers such as Chrome, Firefox or Internet Explorer" ; NR_CHROME="Chrome" ; NR_FIREFOX="Firefox" ; NR_EDGE="Edge" ; NR_IE="Internet Explorer" ; NR_SAFARI="Safari" ; NR_OPERA="Opera" ; NR_ASSIGN_OS="Operating System" ; NR_ASSIGN_OS_DESC="Select the operating systems to assign to" ; NR_ASSIGN_OS_DESC2="Target visitors who are using specific operating systems such as Windows, Linux or Mac" ; NR_LINUX="Linux" ; NR_MAC="MacOS" ; NR_ANDROID="Android" ; NR_IOS="iOS" ; NR_WINDOWS="Windows" ; NR_BLACKBERRY="Blackberry" ; NR_CHROMEOS="Chrome OS" ; NR_ASSIGN_PAGEVIEWS="Number of Pageviews" ; NR_ASSIGN_PAGEVIEWS_DESC="Target visitors who have viewed certain number of pages" ; NR_ASSIGN_PAGEVIEWS_VIEWS="Pageviews" ; NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Enter the number of page views" ; NR_ASSIGN_COOKIENAME_NAME="Cookie Name" ; NR_ASSIGN_COOKIENAME_NAME_DESC="Enter the name of the cookie to assign to" ; NR_ASSIGN_COOKIENAME_NAME_DESC2="Target visitors who have specific cookies stored in their browser" ; NR_FEWER_THAN="Fewer than" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" ; NR_GREATER_THAN="Greater than" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" ; NR_EXACTLY="Exactly" ; NR_EXISTS="Exists" ; NR_NOT_EXISTS="Does not exists" ; NR_IS_EQUAL="Equals" ; NR_DOES_NOT_EQUAL="Does not equal" ; NR_CONTAINS="Contains" ; NR_DOES_NOT_CONTAIN="Does not contain" ; NR_STARTS_WITH="Starts with" ; NR_DOES_NOT_START_WITH="Does not start with" ; NR_ENDS_WITH="Ends with" ; NR_DOES_NOT_END_WITH="Does not end with" ; NR_ASSIGN_COOKIENAME_CONTENT="Cookie Content" ; NR_ASSIGN_COOKIENAME_CONTENT_DESC="The cookie's content" ; NR_ASSIGN_IP_ADDRESSES_DESC2="Target visitors who are behind a specific IP address (range)" ; NR_ASSIGN_IP_ADDRESSES_DESC="Enter a list of comma and/or 'enter' separated ip addresses and ranges

Example:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." ; NR_ASSIGN_USER_ID="User ID" ; NR_ASSIGN_USER_ID_DESC="Target specific Joomla Users by their IDs" ; NR_ASSIGN_USER_ID_SELECTION_DESC="Enter comma separated Joomla user IDs" ; NR_ASSIGN_COMPONENTS="Component" ; NR_ASSIGN_COMPONENTS_DESC="Select the components to assign to" ; NR_ASSIGN_COMPONENTS_DESC2="Target visitors who are browsing specific components" ; NR_ASSIGN_TIMERANGE="Time Range" ; NR_ASSIGN_TIMERANGE_DESC="Target visitors based on your server's time" ; NR_START_TIME="Start Time" ; NR_END_TIME="End Time" ; NR_START_PUBLISHING_TIMERANGE_DESC="Enter the time to start publishing" ; NR_FINISH_PUBLISHING_TIMERANGE_DESC="Enter the time to end publishing" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." ; NR_RECAPTCHA_SITE_KEY="Site Key" ; NR_RECAPTCHA_SITE_KEY_DESC="Used in the JavaScript code that is served to your users." ; NR_RECAPTCHA_SECRET_KEY="Secret Key" ; NR_RECAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret." ; NR_RECAPTCHA_SITE_KEY_ERROR="The reCaptcha Site Key is either missing or invalid" ; NR_PREVIOUS_MONTH="Previous Month" ; NR_NEXT_MONTH="Next Month" ; NR_ASSIGN_GROUP_PAGE_URL="Page / URL" ; NR_ASSIGN_GROUP_PAGE_URL_DESC="Target visitors who are browsing specific menu items or URLs" ; NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" ; NR_ASSIGN_GROUP_USER_VISITOR="Joomla User / Visitor" ; NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" ; NR_ASSIGN_GROUP_PLATFORM="Visitor Platform" ; NR_ASSIGN_GROUP_PLATFORM_DESC="Target visitors who are using Mobile, Google Chrome, or even Windows" ; NR_ASSIGN_GROUP_GEO_DESC="Target visitors who are physically in a specific region" ; NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" ; NR_ASSIGN_GROUP_JCONTENT_DESC="Target visitors who are viewing specific Joomla articles or categories" ; NR_ASSIGN_GROUP_SYSTEM="System / Integrations" ; NR_INTEGRATIONS="Integrations" ; NR_ASSIGN_GROUP_SYSTEM_DESC="Target visitors who have interacted with specific 3rd party Joomla Extensions" ; NR_ASSIGN_GROUP_ADVANCED="Advanced visitor targeting" ; NR_ASSIGN_USERGROUP_DESC="Target specific Joomla user groups" ; NR_ASSIGN_ARTICLE_DESC="Target visitors who are viewing specific Joomla articles" ; NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target visitors who are viewing specific Joomla categories" ; NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." ; NR_ASSIGN_K2="K2" ; NR_ASSIGN_K2_DESC="Target visitors who are browsing specific K2 Items, Categories or Tags" ; NR_ASSIGN_K2_ITEMS="Item" ; NR_ASSIGN_K2_ITEMS_DESC="Target visitors who are browsing specific K2 items." ; NR_ASSIGN_K2_ITEMS_LIST_DESC="Select the K2 Items to assign to" ; NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Match on specific keywords in the item's content. Seperate by a comma or a new line." ; NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Match on the item's meta keywords. Seperate by a comma or a new line." ; NR_ASSIGN_K2_PAGETYPES_DESC="Target visitors who are browsing specific K2 page types" ; NR_ASSIGN_K2_ITEM_OPTION="Item" ; NR_ASSIGN_K2_LATEST_OPTION="Latest items from users or categories" ; NR_ASSIGN_K2_TAG_OPTION="Tag Page" ; NR_ASSIGN_K2_CATEGORY_OPTION="Category Page" ; NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Edit Form" ; NR_ASSIGN_K2_USER_PAGE_OPTION="User Page (blog)" ; NR_ASSIGN_K2_TAGS_DESC="Target visitors who are browsing K2 items with specific tags" ; NR_ASSIGN_K2_CATEGORIES_DESC="Target visitors who are browsing specific K2 categories" ; NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" ; NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" ; NR_ASSIGN_PAGE_TYPES_DESC="Select the page types to assign to" ; NR_ASSIGN_TAGS_DESC="Select the tags to assign to" ; NR_CONTENT_KEYWORDS="Content keywords" ; NR_META_KEYWORDS="Meta keywords" ; NR_TAG="Tag" ; NR_NORMAL="Normal" ; NR_COMPACT="Compact" ; NR_LIGHT="Light" ; NR_DARK="Dark" ; NR_SIZE="Size" ; NR_THEME="Theme" ; NR_SINGLE="Single" ; NR_MULTIPLE="Multiple" ; NR_RANGE="Range" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_PLEASE_VALIDATE="Please validate" ; NR_RECAPTCHA_INVALID_SECRET_KEY="Invalid secret key" ; NR_PAGE="Page" ; NR_YOU_ARE_USING_EXTENSION="You are using %s %s" ; NR_UPDATE="Update" ; NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" ; NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." ; NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!w^ƠƠBsystem/nrframework/language/es-ES/es-ES.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Sistema - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - usado por Tassos.gr extensiones" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignorar" NR_INCLUDE="Incluir" NR_EXCLUDE="Excluir" NR_SELECTION="Selección" NR_ASSIGN_MENU_NOITEM="No incluir Itemid" NR_ASSIGN_MENU_NOITEM_DESC="¿Asignar también cuando ningún menú Itemid está establecido en URL?" NR_ASSIGN_MENU_CHILD="Asignar en elementos hijo" NR_ASSIGN_MENU_CHILD_DESC="¿Asignar también a los elementos hijo de los elementos seleccionados?" NR_COPY_OF="Copiar de %s" NR_ASSIGN_DATETIME_DESC="Orientar a los visitantes en función de la hora de la fecha de su servidor" NR_DATETIME="Fecha y hora" NR_TIME="Hora" NR_DATE="Fecha" NR_DATETIME_DESC="Introduzca la fecha y hora para publicar/despublicar automáticamente" NR_START_PUBLISHING="Fecha y hora de inicio" NR_START_PUBLISHING_DESC="Introduzca la fecha para comenzar la publicación" NR_FINISH_PUBLISHING="Fecha y hora finalización" NR_FINISH_PUBLISHING_DESC="Introduzca la fecha para terminar la publicación" NR_DATETIME_NOTE="Las asignaciones de fecha y hora utilizan la fecha y la hora de los servidores, no la del sistema de los visitantes." NR_ASSIGN_PHP="PHP" NR_PHPCODE="Código PHP" NR_ASSIGN_PHP_DESC="Introduzca una parte de código PHP para evaluar." NR_ASSIGN_PHP_DESC2="Orientación a los visitantes a evaluar código PHP personalizado. El código debe devolver el valor verdadero o falso.

Por ejemplo:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Tiempo en el Sitio" NR_SECONDS="Segundos" NR_ASSIGN_TIMEONSITE_DESC="Ingrese una duración en segundos para compararla con el tiempo total del usuario (duración de la visita) gastado en todo el sitio.

Ejemplo:
Si desea mostrar una casilla después de que el usuario haya pasado 3 minutos en su sitio completo, escriba 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Orientar a visitantes que navegan por URL específicas" NR_ASSIGN_URLS_DESC="Escriba (parte de) las URL a comparar
Utilice una nueva línea para cada coincidencia diferente." NR_ASSIGN_URLS_LIST="Emparejar URL" NR_ASSIGN_URLS_REGEX="Usar Expresión Regular" NR_ASSIGN_URLS_REGEX_DESC="Seleccione esta opción para tratar el valor como expresiones regulares." NR_ASSIGN_LANGS="Idioma" NR_ASSIGN_LANGS_DESC="Orientar a visitantes que están navegando por tu sitio web en un idioma específico" NR_ASSIGN_LANGS_LIST_DESC="Seleccione los idiomas para asignar a" NR_ASSIGN_DEVICES="Dispositivo" NR_ASSIGN_DEVICES_DESC2="Orientar a visitantes que utilizan dispositivos específicos como Móviles, Tablet u Ordenadores" NR_ASSIGN_DEVICES_DESC="Seleccione los dispositivos para asignar a" NR_ASSIGN_DEVICES_NOTE="Tenga en cuenta que la detección de dispositivos no siempre es 100% precisa. Los usuarios pueden configurar su navegador para imitar otros dispositivos" NR_MENU="Menú" NR_MENU_ITEMS="Elementos del Menú" NR_MENU_ITEMS_DESC="Orientar a visitantes que navegan por elementos del menú específicos" NR_USERGROUP="Grupo de Usuarios" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Grupo de Usuarios" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Mostrar Copyright" NR_SHOW_COPYRIGHT_DESC="Si se selecciona, se mostrará información adicional sobre copyright en las vistas de administración. Las extensione de Tassos.gr nunca muestran información de copyright o vínculos de retroceso en el frontend." NR_WIDTH="Anchura" NR_WIDTH_DESC="Introduzca el ancho en px, em o %

Ejemplo: 400px" NR_HEIGHT="Altura" NR_HEIGHT_DESC="Introduzca la altura en px, em o %

Ejemplo: 400px" NR_PADDING="Relleno" NR_PADDING_DESC="Introduzca el relleno en px, em o %

Ejemplo: 20px" NR_MARGIN="Margen" NR_MARGIN_DESC="La propiedad de margen CSS se utiliza para generar espacio alrededor de la caja y establecer el tamaño del espacio en blanco fuera del borde en píxeles o en %.

Ejemplo 1: 25px
Ejemplo 2: 5%

Especificando el margen para cada lado [arriba a la derecha abajo a la izquierda]:

Parte superior solamente: 25px 0 0 0
Lado derecho solamente: 0 25px 0 0
Parte inferior solamente: 0 0 25px 0
Lado izquierdo solamente: 0 0 0 25px" NR_COLOR_HOVER="Color Activo" NR_COLOR="Color" NR_COLOR_DESC="Define el color en formato HEX o RGBA." NR_TEXT_COLOR="Color del texto" NR_BACKGROUND="Fondo" NR_BACKGROUND_COLOR="Color de fondo" NR_BACKGROUND_COLOR_DESC="Defina un color de fondo en formato HEX o RGBA. Para deshabilitar, escriba 'none'. Para una transparencia absoluta escriba 'transparent'." NR_URL_SHORTENING_FAILED="Acortamiento %s con %s fallido. %s" NR_EXPORT="Exportar" NR_IMPORT="Importar" NR_PLEASE_CHOOSE_A_VALID_FILE="Elija un nombre de archivo válido" NR_IMPORT_ITEMS="Importar Elementos" NR_PUBLISH_ITEMS="Publicar Elementos" NR_AS_EXPORTED="Como exportado" NR_TITLE="Título" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="Listado AcyMailing" NR_ACYMAILING_LIST_DESC="Seleccione las listas de Acymailing a las que asignar." NR_ASSIGN_ACYMAILING_DESC="Orientar a visitantes que se han suscrito a listas específicas de Acymailing" NR_AKEEBASUBS="Suscripciones Akeeba" NR_AKEEBASUBS_LEVELS="Niveles" NR_AKEEBASUBS_LEVELS_DESC="Seleccione los niveles de suscripción de Akeeba a asignar." NR_ASSIGN_AKEEBASUBS_DESC="Orientar a visitantes que se han suscrito a suscripciones específicas de Akeeba" NR_MATCH="Combinar" NR_MATCH_DESC="El método utilizado para comparar el valor" NR_ASSIGN_MATCHING_METHOD="Método de Emparejamiento" NR_ASSIGN_MATCHING_METHOD_DESC="¿Todas las asignaciones deben ser emparejadas?

Todo
Se publicará siTodaslas asignaciones inferiores coinciden.

Cualquiera
Se publicará si Cualquier(una o más) de las asignaciones inferiores se coinciden.
Grupos de asignación donde 'Ignore' es seleccionado será ignorado." NR_ANY="Cualquiera" ; NR_ALL="All" NR_ASSIGN_REFERRER="URL de referencia " ; NR_ASSIGN_REFERRER_DESC2="Target visitors who land on your site from a specific traffic source" ; NR_ASSIGN_REFERRER_DESC="Enter one Referrer URL per line: Eg:

google.com
facebook.com/mypage" ; NR_ASSIGN_REFERRER_NOTE="Keep in mind that URL Referrer discovery is not always 100% accurate. Some servers may use proxies that strip this information out and it can be easily forged." ; NR_PROFEATURE_HEADER="%s is a PRO Feature" ; NR_PROFEATURE_DESC="We're sorry, %s is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features." ; NR_PROFEATURE_DISCOUNT="Bonus: %s free users get 20% off regular price, automatically applied at checkout." NR_ONLY_AVAILABLE_IN_PRO="Solo disponible en la versión PRO" NR_UPGRADE_TO_PRO="Mejorar a Pro" NR_UPGRADE_TO_PRO_TO_UNLOCK="Actualizar a la versión Pro para desbloquear" NR_UPGRADE_TO_PRO_VERSION="¡Impresionante! Solo un paso más. Haga clic en el botón de abajo para completar la actualización a la versión Pro. " NR_UNLOCK_PRO_FEATURE="Desbloquear Función PRO" NR_USING_THE_FREE_VERSION="Está utilizando la versión GRATUITA de Convert Forms. Compre la versión PRO para obtener todas las funcionalidades. " NR_LEFT_TO_RIGHT="Izquierda a derecha" NR_RIGHT_TO_LEFT="Derecha a izquierda" NR_BGIMAGE="Imagen de fondo" NR_BGIMAGE_DESC="Establecer una imagen de fondo" NR_BGIMAGE_FILE="Imagen" NR_BGIMAGE_FILE_DESC="Seleccione o cargue un archivo para la imagen de fondo." NR_BGIMAGE_REPEAT="Repetir" NR_BGIMAGE_REPEAT_DESC="La propiedad repetir fondo establece si/cómo se repetirá una imagen de fondo. De forma predeterminada, una imagen de fondo se repite tanto verticalmente como horizontalmente.

Repetir: La imagen de fondo se repetirá tanto verticalmente como horizontalmente.

Repetir-x: La imagen de fondo solo se repetirá horizontalmente

Repetir-y: La imagen de fondo solo se repetirá verticalmente

No repetir: La imagen de fondo no se repetirá" NR_BGIMAGE_SIZE="Tamaño" NR_BGIMAGE_SIZE_DESC="Especifique el tamaño de una imagen de fondo.

Auto: La imagen de fondo contiene su ancho y altura

Cubierta: Escala la imagen de fondo para que sea lo más grande posible para que el área de fondo esté completamente cubierto por la imagen de fondo. Algunas partes de la imagen de fondo pueden no estar a la vista dentro del área de posicionamiento de fondo

Contenido: Escala la imagen al tamaño más grande de manera que tanto su ancho como su altura puedan caber en el área de contenido

100% 100%: Estira la imagen de fondo para cubrir completamente el área de contenido." NR_BGIMAGE_POSITION="Posición" NR_BGIMAGE_POSITION_DESC="La propiedad posición de fondo establece la posición inicial de una imagen de fondo. De forma predeterminada, una imagen de fondo se coloca en la esquina superior izquierda. El primer valor es la posición horizontal y el segundo es la vertical.

Puede utilizar uno de los valores predefinidos o introducir un valor personalizado en porcentaje: x% y% o en píxeles xPos yPos." NR_RTL="Habilitar RTL" NR_RTL_DESC="La dirección del texto de derecha a izquierda es esencial para los scripts de derecha a izquierda como el Árabe, el Hebreo, el Siríaco y el Thaana." NR_HORIZONTAL="Horizontal" NR_VERTICAL="Vertical" NR_FORM_ORIENTATION="Orientación del Formulario" NR_FORM_ORIENTATION_DESC="Seleccione la orientación del formulario" NR_ASSIGN_CATEGORY="Categorías" NR_ASSIGN_CATEGORY_DESC="Seleccione las categorías a asignar a" NR_ASSIGN_CATEGORY_CHILD="También en elementos heredados" NR_ASSIGN_CATEGORY_CHILD_DESC="¿Asignar también a los elementos heredados de los elementos seleccionados?" NR_NEW="Nuevo" NR_LIST="Lista" NR_DOCUMENTATION="Documentación" NR_KNOWLEDGEBASE="Conocimiento" NR_FAQ="Preguntas Frecuentes" NR_INFORMATION="Información" NR_EXTENSION="Extensión" NR_VERSION="Versión" NR_CHANGELOG="Registro de cambios" NR_DOWNLOAD="Descargar" NR_DOWNLOAD_KEY_MISSING="Falta la clave del producto" NR_DOWNLOAD_KEY="Descargar clave" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="Para poder actualizar %s a través del actualizador de Joomla, necesitará ingresar su código de descarga en la configuración del Novarain Framework Plugin" NR_DOWNLOAD_KEY_FIND="Encontrar Clave de Descarga" NR_DOWNLOAD_KEY_UPDATE="Actualizar Clave de Descarga" NR_OK="De acuerdo" NR_MISSING="Perdido" NR_LICENSE="Licencia" NR_AUTHOR="Autor" NR_FOLLOWME="Sígueme" NR_FOLLOW="Seguir %s" NR_TRANSLATE_INTEREST="¿Estaría interesado en ayudar a traducir %s a su idioma?" NR_TRANSIFEX_REQUEST="Envíeme una solicitud para Transifex" NR_HELP_WITH_TRANSLATIONS="Ayuda con las traducciones" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Avanzado" NR_USEGLOBAL="Usar Global" NR_WEEKDAY="Día de la Semana" NR_MONTH="Mes" NR_MONDAY="Lunes" NR_TUESDAY="Martes" NR_WEDNESDAY="Miércoles" NR_THURSDAY="Jueves" NR_FRIDAY="Viernes" NR_SATURDAY="Sábado" NR_WEEKEND="Fin de Semana" NR_WEEKDAYS="Días Laborables" NR_SUNDAY="Domingo" NR_JANUARY="Enero" NR_FEBRUARY="Febrero" NR_MARCH="Marzo" NR_APRIL="Abril" NR_MAY="Mayo" NR_JUNE="Junio" NR_JULY="Julio" NR_AUGUST="Agosto" NR_SEPTEMBER="Septiembre" NR_OCTOBER="Octubre" NR_NOVEMBER="Noviembre" NR_DECEMBER="Diciembre" NR_NEVER="Nunca" NR_SECONDS="Segundos" NR_MINUTES="Minutos" NR_HOURS="Horas" NR_DAYS="Días" NR_SESSION="Sesión" NR_EVER="Nunca" NR_COOKIE="Cookie" NR_BOTH="Ambos" NR_NONE="Ninguno" ; NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Escritorio" NR_MOBILES="Móvil" NR_TABLETS="Tableta" NR_PER_SESSION="Por Sesión" NR_PER_DAY="Por Día" NR_PER_WEEK="Por Semana" NR_PER_MONTH="Por Mes" NR_FOREVER="Para siempre" NR_FEATURE_UNDER_DEV="Esta característica está en desarrollo" NR_LIKE_THIS_EXTENSION="¿Te gusta esta extensión?" NR_LEAVE_A_REVIEW="Dejar un comentado en JED" NR_SUPPORT="Soporte" NR_NEED_SUPPORT="¿Necesita ayuda?" NR_DROP_EMAIL="Envíame un correo electrónico" NR_READ_DOCUMENTATION="Lea la documentación" NR_COPYRIGHT="%s - Tassos.gr Todos los derechos reservados" NR_DASHBOARD="Tablero" NR_NAME="Nombre" NR_WRONG_COORDINATES="Las coordenadas proporcionadas no son válidas" NR_ENTER_COORDINATES="Latitud,Longitud" NR_NO_ITEMS_FOUND="No se encontraron elementos" NR_ITEM_IDS="No hay elementos IDs" NR_TOGGLE="Palanca" NR_EXPAND="Expandir" NR_COLLAPSE="Contraer" NR_SELECTED="Seleccionado" NR_MAXIMIZE="Maximizar" NR_MINIMIZE="Minimizar" NR_SELECTION="Selección" NR_INSTALL="Instalar" NR_INSTALL_NOW="Instalar Ahora" NR_INSTALLED="Instalado" NR_COMING_SOON="Próximamente" NR_ROADMAP="En la hoja de ruta" NR_MEDIA_VERSIONING="Utilizar el versionamiento de medios" NR_MEDIA_VERSIONING_DESC="Seleccione para agregar el número de versión de extensión al final de las urls de medios (js/css), para que los navegadores fuercen la carga del archivo correcto." NR_LOAD_JQUERY="Cargar jQuery" NR_LOAD_JQUERY_DESC="Seleccione para cargar el script jQuery principal. Puede desactivar esto si experimenta conflictos si su plantilla u otras extensiones cargan su propia versión de jQuery." NR_SELECT_CURRENCY="Seleccione Divisa" NR_CONVERTFORMS="Convertir Formularios" NR_CONVERTFORMS_LIST="Campaña" NR_ASSIGN_CONVERTFORMS_DESC="Visitantes destinatarios que se han suscrito a campañas específicas de Convertforms" NR_CONVERTFORMS_LIST_DESC="Seleccione las campañas de ConvertForms para asignar." NR_LEFT="Izquierda" NR_CENTER="Centro" NR_RIGHT="Derecha" NR_BOTTOM="Inferior" NR_TOP="Superior" NR_AUTO="Auto" NR_CUSTOM="Personalizado" NR_UPLOAD="Subir" NR_IMAGE="Imagen" NR_INTRO_IMAGE="Imagen de introducción" NR_FULL_IMAGE="Imagen completa" NR_IMAGE_SELECT="Seleccionar Imagen" NR_IMAGE_SIZE_COVER="Cubierta" NR_IMAGE_SIZE_CONTAIN="Contiene" NR_REPEAT="Repetir" NR_REPEAT_X="Repetir x" NR_REPEAT_Y="Repetir Y" NR_REPEAT_NO="No repetir" NR_FIELD_STATE_DESC="Establecer estados de los elementos" NR_CREATED_DATE="Fecha de Creación" NR_CREATED_DATE_DESC="La fecha del elemento ha sido creada" NR_MODIFIFED_DATE="Fecha Modificada" NR_MODIFIFED_DATE_DESC="La fecha en que el elemento se modificó por última vez." NR_CATEGORIES="Categoría" NR_CATEGORIES_DESC="Seleccione las categorías para asignar." NR_ALSO_ON_CHILD_ITEMS="También en los elementos secundarios" NR_ALSO_ON_CHILD_ITEMS_DESC="¿Asignar también a los elementos secundarios de los elementos seleccionados? " NR_PAGE_TYPE="Tipo de página" NR_PAGE_TYPES="Tipos de páginas" NR_PAGE_TYPES_DESC="Seleccione en qué tipos de página debe estar activa la tarea. " NR_CONTENT_VIEW_CATEGORY_BLOG="Categoría en formato blog" NR_CONTENT_VIEW_CATEGORY_LIST="Categoría en formato lista" NR_CONTENT_VIEW_CATEGORIES="Listar todas las categorías" NR_CONTENT_VIEW_ARCHIVED="Artículos archivados" NR_CONTENT_VIEW_FEATURES="Artículos destacados" NR_CONTENT_VIEW_CREATE_ARTICLE="Crear Artículo" NR_CONTENT_VIEW_ARTICLE="Un solo artículo" ; NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" NR_CATEGORY_VIEW="Vista de la Categoría" ; NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Artículos" NR_ARTICLES_DESC="Seleccione los artículos para asignar a." NR_ARTICLE="Artículo" NR_ARTICLE_AUTHORS="Autor" NR_ARTICLE_AUTHORS_DESC="Seleccione los autores a asignar a" NR_ONLY="Solo" NR_OTHERS="Otros" ; NR_SMARTTAGS="Smart Tags" ; NR_SMARTTAGS_SHOW="Show Smart Tags" ; NR_SMARTTAGS_NOTFOUND="No Smart Tags found" ; NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" NR_CONTACT_US="Contacta con nosotros" NR_FONT_COLOR="Color de la Fuente" NR_FONT_SIZE="Tamaño de la fuente" NR_FONT_SIZE_DESC="Escoge un tamaño de fuente en píxeles" NR_TEXT="Texto" NR_URL="URL" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE="Enable on Output Override" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Enables the extension rendering when the page layout (tmpl) is overriden. Examples: tmpl=component or tmpl=modal." ; NR_EXECUTE_ON_FORMAT_OVERRIDE="Enable on Format Override" ; NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Enables the extension rendering when the page format is not other than HTML. Examples: format=raw or format=json." NR_GEOLOCATING="Geolocalización" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="La geolocalización no siempre es 100% precisa. La geolocalización se basa en la dirección IP del visitante. No todas las direcciones IP son fijas o conocidas. " NR_CITY="Ciudad" NR_CITY_NAME="Nombre de la ciudad" NR_CONDITION_CITY_DESC="Ingrese el nombre de una ciudad en inglés. Ingrese varias ciudades separadas por comas. " NR_CONTINENT="Continente" NR_REGION="Región" ; NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." NR_ASSIGN_COUNTRIES="País" NR_ASSIGN_COUNTRIES_DESC2="Elegir visitantes que se encuentran físicamente en un país específico" NR_ASSIGN_COUNTRIES_DESC="Seleccione los países a los que asignar " NR_ASSIGN_CONTINENTS="Continente" NR_ASSIGN_CONTINENTS_DESC="Seleccione los continentes a los que asignar " NR_ASSIGN_CONTINENTS_DESC2="Elegir visitantes que se encuentran físicamente en un continente específico" ; NR_ICONTACT_ACCOUNTID_ERROR="The iContact AccountID could not be retrieved" NR_TAG_CLIENTDEVICE="Tipo de dispositivo del visitante" NR_TAG_CLIENTOS="Tipo de Sistema Operativo del visitante" NR_TAG_CLIENTBROWSER="Tipo de navegador web del visitante" ; NR_TAG_CLIENTUSERAGENT="Visitor Agent String" NR_TAG_IP="Dirección IP del visitante " NR_TAG_URL="URL de la página" ; NR_TAG_URLENCODED="Page URL Encoded" NR_TAG_URLPATH="Ruta de la página" ; NR_TAG_REFERRER="Page Referrer" NR_TAG_SITENAME="Nombre del Sitio" NR_TAG_SITEURL="URL del Sitio" NR_TAG_PAGETITLE="Título de la página" ; NR_TAG_PAGEDESC="Page Meta Description" NR_TAG_PAGELANG="Código de idioma de la página" NR_TAG_USERID="ID de Usuario" NR_TAG_USERNAME="Nombre completo de Usuario" ; NR_TAG_USERLOGIN="User Login" NR_TAG_USEREMAIL="Correo electrónico del usuario" NR_TAG_USERFIRSTNAME="Nombre del usuario" NR_TAG_USERLASTNAME="Apellido del usuario" ; NR_TAG_USERGROUPS="User Groups IDs" NR_TAG_DATE="Fecha" NR_TAG_TIME="Hora" NR_TAG_RANDOMID="ID aleatorio" NR_ICON="Icono" NR_SELECT_MODULE="Selecciona un módulo" NR_SELECT_CONTINENT="Seleccione un Continente" NR_SELECT_COUNTRY="Seleccione un país" ; NR_PLUGIN="Plugin" ; NR_GMAP_KEY="Google Maps API Key" ; NR_GMAP_KEY_DESC="The Google Maps API Key is being used by Tassos.gr extensions. If you face any troubles with a Google Map not being loaded then you probably need to enter your own API Key." ; NR_GMAP_FIND_KEY="Get an API key" NR_ARE_YOU_SURE="¿Está usted Seguro?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="URL Personalizada" NR_SAMPLE="Muestra" ; NR_DEBUG="Debug" NR_CUSTOMURL="URL Personalizada" NR_READMORE="Leer Más" NR_IPADDRESS="Dirección IP" NR_ASSIGN_BROWSERS="Navegador" NR_ASSIGN_BROWSERS_DESC="Seleccione los navegadores a asignar" NR_ASSIGN_BROWSERS_DESC2="Los visitantes que están navegando por su sitio con navegadores específicos como Chrome, Firefox o Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Sistema Operativo" ; NR_ASSIGN_OS_DESC="Select the operating systems to assign to" ; NR_ASSIGN_OS_DESC2="Target visitors who are using specific operating systems such as Windows, Linux or Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Número de Páginas vistas" ; NR_ASSIGN_PAGEVIEWS_DESC="Target visitors who have viewed certain number of pages" NR_ASSIGN_PAGEVIEWS_VIEWS="Páginas Vistas" ; NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Enter the number of page views" NR_ASSIGN_COOKIENAME_NAME="Nombre de la Cookie" ; NR_ASSIGN_COOKIENAME_NAME_DESC="Enter the name of the cookie to assign to" ; NR_ASSIGN_COOKIENAME_NAME_DESC2="Target visitors who have specific cookies stored in their browser" NR_FEWER_THAN="Menos que" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="Más grande que" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Exactamante" NR_EXISTS="Existe" ; NR_NOT_EXISTS="Does not exists" NR_IS_EQUAL="Es igual a" ; NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Contiene" ; NR_DOES_NOT_CONTAIN="Does not contain" NR_STARTS_WITH="Comienza con" ; NR_DOES_NOT_START_WITH="Does not start with" NR_ENDS_WITH="Termina con" ; NR_DOES_NOT_END_WITH="Does not end with" ; NR_ASSIGN_COOKIENAME_CONTENT="Cookie Content" ; NR_ASSIGN_COOKIENAME_CONTENT_DESC="The cookie's content" ; NR_ASSIGN_IP_ADDRESSES_DESC2="Target visitors who are behind a specific IP address (range)" ; NR_ASSIGN_IP_ADDRESSES_DESC="Enter a list of comma and/or 'enter' separated ip addresses and ranges

Example:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="ID de Usuario" NR_ASSIGN_USER_ID_DESC="Escoge usuarios específicos de Joomla por su ID " NR_ASSIGN_USER_ID_SELECTION_DESC="Ingrese los ID de usuario de Joomla separados por comas" NR_ASSIGN_COMPONENTS="Componente" ; NR_ASSIGN_COMPONENTS_DESC="Select the components to assign to" NR_ASSIGN_COMPONENTS_DESC2="Escoge a los visitantes que navegan con componentes específicos " NR_ASSIGN_TIMERANGE="Intervalo de tiempo" NR_ASSIGN_TIMERANGE_DESC="Escoge a los visitantes según el tiempo en su servidor " NR_START_TIME="Hora de inicio" NR_END_TIME="Hora de finalización" NR_START_PUBLISHING_TIMERANGE_DESC="Ingrese la hora para comenzar a publicar" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Ingrese la hora para finalizar la publicación" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Clave del Sitio" ; NR_RECAPTCHA_SITE_KEY_DESC="Used in the JavaScript code that is served to your users." NR_RECAPTCHA_SECRET_KEY="Clave secreta" ; NR_RECAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret." ; NR_RECAPTCHA_SITE_KEY_ERROR="The reCaptcha Site Key is either missing or invalid" NR_PREVIOUS_MONTH="Mes anterior" NR_NEXT_MONTH="Mes siguiente" ; NR_ASSIGN_GROUP_PAGE_URL="Page / URL" ; NR_ASSIGN_GROUP_PAGE_URL_DESC="Target visitors who are browsing specific menu items or URLs" ; NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" ; NR_ASSIGN_GROUP_USER_VISITOR="Joomla User / Visitor" ; NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" ; NR_ASSIGN_GROUP_PLATFORM="Visitor Platform" ; NR_ASSIGN_GROUP_PLATFORM_DESC="Target visitors who are using Mobile, Google Chrome, or even Windows" ; NR_ASSIGN_GROUP_GEO_DESC="Target visitors who are physically in a specific region" ; NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" ; NR_ASSIGN_GROUP_JCONTENT_DESC="Target visitors who are viewing specific Joomla articles or categories" ; NR_ASSIGN_GROUP_SYSTEM="System / Integrations" ; NR_INTEGRATIONS="Integrations" ; NR_ASSIGN_GROUP_SYSTEM_DESC="Target visitors who have interacted with specific 3rd party Joomla Extensions" ; NR_ASSIGN_GROUP_ADVANCED="Advanced visitor targeting" ; NR_ASSIGN_USERGROUP_DESC="Target specific Joomla user groups" ; NR_ASSIGN_ARTICLE_DESC="Target visitors who are viewing specific Joomla articles" ; NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target visitors who are viewing specific Joomla categories" ; NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." ; NR_ASSIGN_K2="K2" ; NR_ASSIGN_K2_DESC="Target visitors who are browsing specific K2 Items, Categories or Tags" ; NR_ASSIGN_K2_ITEMS="Item" ; NR_ASSIGN_K2_ITEMS_DESC="Target visitors who are browsing specific K2 items." ; NR_ASSIGN_K2_ITEMS_LIST_DESC="Select the K2 Items to assign to" ; NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Match on specific keywords in the item's content. Seperate by a comma or a new line." ; NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Match on the item's meta keywords. Seperate by a comma or a new line." ; NR_ASSIGN_K2_PAGETYPES_DESC="Target visitors who are browsing specific K2 page types" ; NR_ASSIGN_K2_ITEM_OPTION="Item" ; NR_ASSIGN_K2_LATEST_OPTION="Latest items from users or categories" ; NR_ASSIGN_K2_TAG_OPTION="Tag Page" ; NR_ASSIGN_K2_CATEGORY_OPTION="Category Page" ; NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Edit Form" ; NR_ASSIGN_K2_USER_PAGE_OPTION="User Page (blog)" ; NR_ASSIGN_K2_TAGS_DESC="Target visitors who are browsing K2 items with specific tags" ; NR_ASSIGN_K2_CATEGORIES_DESC="Target visitors who are browsing specific K2 categories" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categorías" ; NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" ; NR_ASSIGN_PAGE_TYPES_DESC="Select the page types to assign to" ; NR_ASSIGN_TAGS_DESC="Select the tags to assign to" ; NR_CONTENT_KEYWORDS="Content keywords" ; NR_META_KEYWORDS="Meta keywords" ; NR_TAG="Tag" NR_NORMAL="Normal" ; NR_COMPACT="Compact" NR_LIGHT="Claro" NR_DARK="Oscuro" NR_SIZE="Tamaño" NR_THEME="Tema" ; NR_SINGLE="Single" ; NR_MULTIPLE="Multiple" NR_RANGE="Rango" ; NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Por favor validar" NR_RECAPTCHA_INVALID_SECRET_KEY="Clave secreta no válida" NR_PAGE="Página" ; NR_YOU_ARE_USING_EXTENSION="You are using %s %s" NR_UPDATE="Actualizar" ; NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" ; NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." ; NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" NR_TAG_DAY="Día" NR_TAG_MONTH="Mes" NR_TAG_YEAR="Año" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" NR_CANCEL="Cancelar" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!,sRRBsystem/nrframework/language/et-EE/et-EE.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Süsteem - Novarain raamistik" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain raamistik - kasutatakse Tassos.gr lisade juures" NOVARAIN_FRAMEWORK="Novarain raamistik" ; TRANSLATABLE NR_IGNORE="Ignoreeri" NR_INCLUDE="Kaasa" NR_EXCLUDE="Vlista" NR_SELECTION="Vali" NR_ASSIGN_MENU_NOITEM="Ära kaasa Itemid'd" NR_ASSIGN_MENU_NOITEM_DESC="Kaasa ka siis kui menüü Itemid on URL's määratud?" NR_ASSIGN_MENU_CHILD="Ka alamkirjetele" NR_ASSIGN_MENU_CHILD_DESC="Kas määrata ka alamkirjetele sinu valikus?" NR_COPY_OF="Kopeeri %s" NR_ASSIGN_DATETIME_DESC="Sihtitud külastajad käsitletakse sinu serveri kuupäev-kellaaja järgi" NR_DATETIME="Kuupäev-kellaaeg" NR_TIME="Kellaaeg" NR_DATE="Kuupäev" NR_DATETIME_DESC="Sisesta kuupäev-kellaaeg mil toimub atomaatne avalikustamine/peitmine" NR_START_PUBLISHING="Alguse kuupäev-kellaaeg" NR_START_PUBLISHING_DESC="Sisesta avalikustamise kuupäev" NR_FINISH_PUBLISHING="Lõpu kuupäev-kellaaeg" NR_FINISH_PUBLISHING_DESC="Sisesta peitmise kuupäev" NR_DATETIME_NOTE="Kuupäeva ja aja määrangutes kasuta serveri kuupäeva/aega mitte kasutajapoolset." NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP kood" NR_ASSIGN_PHP_DESC="Sisesta PHP kood mida analüüsida." NR_ASSIGN_PHP_DESC2="Sihitud külastajale suunatud PHP kood. Kood peab tagastama väärtuse õige või vale.

Näiteks:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Aeg lehel" NR_SECONDS="Sekundit" ; NR_ASSIGN_TIMEONSITE_DESC="Enter a duration in seconds to compare with the user's total time (Visit duration) spent on your entire site .

Example:
If you want to display a box after the user has spent 3 minutes on your the entire site, enter 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Sihitav külastaja kes külastab määratud URL-e" NR_ASSIGN_URLS_DESC="Sisesta (osa) URL-st mida otsida.
Kasuta iga erineva otsingu jaoks uut rida." NR_ASSIGN_URLS_LIST="URL-ide kookkulangevus" NR_ASSIGN_URLS_REGEX="Kasuta regulaaravaldisi" NR_ASSIGN_URLS_REGEX_DESC="Saad otsitavas väärtuses kasutada regulaaravaldisi." NR_ASSIGN_LANGS="Keel" NR_ASSIGN_LANGS_DESC="Külastajal, kes külastab sinu lehte, on ettemääratud keel" NR_ASSIGN_LANGS_LIST_DESC="Määra keel millega siduda" NR_ASSIGN_DEVICES="Seade" NR_ASSIGN_DEVICES_DESC2="Külastaja kasutab määratud seadet nagu Mobiil, Tahvel või Arvuti." NR_ASSIGN_DEVICES_DESC="Määra seadmed millega siduda." NR_ASSIGN_DEVICES_NOTE="Tea, et seadme tuvastamine ei ole alati 100% õige. Kasutajad saavad oma brauserites emuleerida muid seadmeid." NR_MENU="Menüü" NR_MENU_ITEMS="Menüükirje" NR_MENU_ITEMS_DESC="Külastajad, kes saavad kasutada ette määratud menüükirjeid" NR_USERGROUP="Kasutajagrupp" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Kasutajagrupp" NR_USERACCESSLEVEL="Kasutaja õiguste tase" NR_USERACCESSLEVEL_DESC="Vali kasutaja vaatamise õiguste tase." NR_SHOW_COPYRIGHT="Näita autoriõigusi" NR_SHOW_COPYRIGHT_DESC="Kui on määratud, siis näidatakse admin vaadetes autoriõigusi. Tassos.gr lisad ei näita ise autoriõigusi kunagi ja ei loo ka linke oma lehele." NR_WIDTH="Laius" NR_WIDTH_DESC="Sisesta laius px, em or %

Näiteks: 400px" NR_HEIGHT="Kõrgus" NR_HEIGHT_DESC="Sisesta kõrgus px, em or %

Näiteks: 400px" NR_PADDING="Nihe" NR_PADDING_DESC="Sisesta nihe px, em or %

Näiteks: 20px" NR_MARGIN="Lüke" ; NR_MARGIN_DESC="The CSS margin propertiy is used to generate space around the box and set the size of the white space outside the border in pixels or in %.

Example 1: 25px
Example 2: 5%

Specifying the margin for each side [top right bottom left]:

Top side only: 25px 0 0 0
Right side only: 0 25px 0 0
Bottom side only: 0 0 25px 0
Left side only: 0 0 0 25px" NR_COLOR_HOVER="Üleliikumise värv" NR_COLOR="Värv" NR_COLOR_DESC="Määra värv HEX või RGBA formaadis." NR_TEXT_COLOR="Teksti värv" NR_BACKGROUND="Taust" NR_BACKGROUND_COLOR="Tausta värv" NR_BACKGROUND_COLOR_DESC="Määra värv HEX või RGBA formaadis. Et keelat, sisesta 'none'. Täielikuks läbipaistvuseks sisesta 'transparent'." NR_URL_SHORTENING_FAILED="Lühendamine %s selliseks %s ebaõnnesuts. %s." NR_EXPORT="Eksport" NR_IMPORT="Import" NR_PLEASE_CHOOSE_A_VALID_FILE="Palun vali korralik failinimi" NR_IMPORT_ITEMS="Impordi kirjeid" NR_PUBLISH_ITEMS="Avalikusta kirjeid" NR_AS_EXPORTED="Nagu eksporditud" NR_TITLE="Pealkiri" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="AcyMailing uudiskiri" NR_ACYMAILING_LIST_DESC="Vali AcyMailing uudiskiri millega siduda." NR_ASSIGN_ACYMAILING_DESC="Külastajad, keda liita AcyMailing uudiskirjaga" NR_AKEEBASUBS="Akeeba liikmelisused" NR_AKEEBASUBS_LEVELS="Tasemed" NR_AKEEBASUBS_LEVELS_DESC="Vali Akeeba liikmelisuse tasemed millega siduda." NR_ASSIGN_AKEEBASUBS_DESC="Külastajad kes liidetakse Akeeba liikmelisusega" NR_MATCH="Kokkulangevus" NR_MATCH_DESC="Kasutatud kokkusobivuse meetod millega väärtust võrrelda" NR_ASSIGN_MATCHING_METHOD="Kokkusobivuse meetod" ; NR_ASSIGN_MATCHING_METHOD_DESC="Should all or any assignments be matched?

All
Will be published if All of below assignments are matched.

Any
Will be published if Any (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." NR_ANY="Iga" NR_ALL="Kõik" NR_ASSIGN_REFERRER="Saatev URL" ; NR_ASSIGN_REFERRER_DESC2="Target visitors who land on your site from a specific traffic source" ; NR_ASSIGN_REFERRER_DESC="Enter one Referrer URL per line: Eg:

google.com
facebook.com/mypage" ; NR_ASSIGN_REFERRER_NOTE="Keep in mind that URL Referrer discovery is not always 100% accurate. Some servers may use proxies that strip this information out and it can be easily forged." NR_PROFEATURE_HEADER="%s On Pro võimalus" NR_PROFEATURE_DESC="Vabandame, aga %sei ole saadaval. Palun uuenda Pro versioonile, et avada need võimalused." NR_PROFEATURE_DISCOUNT="Boonus: %s tasuta kasutajad saavad 20% alla täishinnast, lisatakse automaatselt ostukorvis." NR_ONLY_AVAILABLE_IN_PRO="Saadaval vaid Pro versioonis" NR_UPGRADE_TO_PRO="Uuenda Pro versioonile" NR_UPGRADE_TO_PRO_TO_UNLOCK="Uuenda Pro versioonile et avada" NR_UPGRADE_TO_PRO_VERSION="Hiilgav! Ainult üks samm veel: kliki nupule, et lõpetada uuendamine Pro versioonile." NR_UNLOCK_PRO_FEATURE="Ava Pro võimalused" NR_USING_THE_FREE_VERSION="Kasutad TASUTA versiooni Convert Forms lisast. Soeta Pro versioon, et kasutada täit funktsionaalsust." NR_LEFT_TO_RIGHT="Vasakult paremale" NR_RIGHT_TO_LEFT="Paremalt vasakule" NR_BGIMAGE="Taustapilt" NR_BGIMAGE_DESC="Määrab taustapildi" NR_BGIMAGE_FILE="Pilt" NR_BGIMAGE_FILE_DESC="Vali või lae pilt üles, et seda taustana kasutada." NR_BGIMAGE_REPEAT="Korda" ; NR_BGIMAGE_REPEAT_DESC="The background-repeat property sets if/how a background image will be repeated. By default, a background-image is repeated both vertically and horizontally.

Repeat: The background image will be repeated both vertically and horizontally.

Repeat-x: The background image will be repeated only horizontally

Repeat-y: The background image will be repeated only vertically

No-repeat: The background-image will not be repeated" NR_BGIMAGE_SIZE="Mõõt" ; NR_BGIMAGE_SIZE_DESC="Specify the size of a background image.

Auto:The background-image contains its width and height

Cover: Scale the background image to be as large as possible so that the background area is completely covered by the background image. Some parts of the background image may not be in view within the background positioning area

Contain: Scale the image to the largest size such that both its width and its height can fit inside the content area

100% 100%: Stretch the background image to completely cover the content area." NR_BGIMAGE_POSITION="Asukoht" ; NR_BGIMAGE_POSITION_DESC="The background-position property sets the starting position of a background image. By default, a background-image is placed at the top-left corner. The first value is the horizontal position and the second value is the vertical.

You can use either one of the predefined values, or enter a custom value in percentage: x% y% or in pixel xPos yPos." NR_RTL="Luba RTL" ; NR_RTL_DESC="The right-to-left text direction is essential for right-to-left scripts such as Arabic, Hebrew, Syriac, and Thaana." NR_HORIZONTAL="Horisontaalne" NR_VERTICAL="Vertikaalne" NR_FORM_ORIENTATION="Vormi orientatsioon" NR_FORM_ORIENTATION_DESC="Määra vormi orientatsioon" NR_ASSIGN_CATEGORY="Kategooriad" NR_ASSIGN_CATEGORY_DESC="Määra kategooriad millega sisuda" NR_ASSIGN_CATEGORY_CHILD="Kaasa alamad" NR_ASSIGN_CATEGORY_CHILD_DESC="Kas kaasata ka alamad valitud kirjetele?" NR_NEW="Uus" NR_LIST="Nimekiri" NR_DOCUMENTATION="Dokumentatsioon" NR_KNOWLEDGEBASE="Teadmistepagas" NR_FAQ="KKK" NR_INFORMATION="Informatsioon" NR_EXTENSION="Laiendus" NR_VERSION="Versioon" NR_CHANGELOG="Muutuste logi" NR_DOWNLOAD="Lae alla" NR_DOWNLOAD_KEY_MISSING="Allalaadimisvõti on puudu" NR_DOWNLOAD_KEY="Allalaadimisvõti" NR_DOWNLOAD_KEY_DESC="Et leida allalaadimisvõti, logi oma kontoga Tassos.gr lehele sisse ja mine allalaadimiste sektsiooni.

Tähelepanu: Määrates siin allalaadimisvõtme, ei uuenda see tasuta versiooni Pro versioonile. Et avada Pro võimalused, pead paigaldama Pro versiooni tasuta versiooni peale." NR_DOWNLOAD_KEY_HOW="Et uuendada lisa %s üle Joomla uuendaja, pead sisestama allalaadimisvõtme Novarian Framework pluginas." NR_DOWNLOAD_KEY_FIND="Leia allalaadimisvõti" NR_DOWNLOAD_KEY_UPDATE="Uuenda allalaadimisvõtit" NR_OK="OK" NR_MISSING="Puudu" NR_LICENSE="Litsents" NR_AUTHOR="Autor" NR_FOLLOWME="Jälgi mind" NR_FOLLOW="Jälgi %s" NR_TRANSLATE_INTEREST="Soovid aidata %s tõlkimisega oma keelde?" NR_TRANSIFEX_REQUEST="Saada mulle taotlus Transifexis" NR_HELP_WITH_TRANSLATIONS="Aita tõlkimisega" NR_PUBLISHING_ASSIGNMENTS="Kuva seisund" NR_ADVANCED="Täpsemalt" NR_USEGLOBAL="Kasuta üldist" NR_WEEKDAY="Nädalapäev" NR_MONTH="Kuu" NR_MONDAY="Esmaspäev" NR_TUESDAY="Teisipäev" NR_WEDNESDAY="Kolmapäev" NR_THURSDAY="Neljapäev" NR_FRIDAY="Reede" NR_SATURDAY="Laupäev" NR_WEEKEND="Nädalavahetus" NR_WEEKDAYS="Tööpäevad" NR_SUNDAY="Pühapäev" NR_JANUARY="Jaanuar" NR_FEBRUARY="Veebruar" NR_MARCH="Märts" NR_APRIL="Aprill" NR_MAY="Mai" NR_JUNE="Juuni" NR_JULY="Juuli" NR_AUGUST="August" NR_SEPTEMBER="September" NR_OCTOBER="Oktoober" NR_NOVEMBER="November" NR_DECEMBER="Detsember" NR_NEVER="MItte kunagi" NR_SECONDS="Sekundit" NR_MINUTES="Minutit" NR_HOURS="Tundi" NR_DAYS="Päeva" NR_SESSION="Sessioon" NR_EVER="Eales" NR_COOKIE="Küpsis" NR_BOTH="Mõlemad" NR_NONE="Pole" NR_NONE_SELECTED="Midagi ei ole valitud" NR_DESKTOPS="Lauaarvuti" NR_MOBILES="Mobiil" NR_TABLETS="Tahvel" NR_PER_SESSION="Sessioonil" NR_PER_DAY="Päevas" NR_PER_WEEK="Nädalalas" NR_PER_MONTH="Kuus" NR_FOREVER="Alati" NR_FEATURE_UNDER_DEV="See võimalus on arenduses" NR_LIKE_THIS_EXTENSION="Meeldib see laiendus?" NR_LEAVE_A_REVIEW="Jäta JED'i oma hinnang" NR_SUPPORT="Toeta" NR_NEED_SUPPORT="Vajad tuge?" NR_DROP_EMAIL="Saada mulle e.mail" NR_READ_DOCUMENTATION="Loe dokumentatsiooni" NR_COPYRIGHT="%s - Tassos.gr kõik õigused kaitstud" NR_DASHBOARD="Töölaud" NR_NAME="Nimi" NR_WRONG_COORDINATES="Sisestatud koordinaadid ei passi" NR_ENTER_COORDINATES="Latitude,Longitude" NR_NO_ITEMS_FOUND="Ühtegi kirjet ei leitud" NR_ITEM_IDS="ID'sid ei leitud" NR_TOGGLE="Lülita" NR_EXPAND="Laienda" NR_COLLAPSE="Ahenda" NR_SELECTED="Valitud" NR_MAXIMIZE="Maksimeeri" NR_MINIMIZE="Minimeeri" NR_SELECTION="Vali" NR_INSTALL="Paigalda" NR_INSTALL_NOW="Paigalda kohe" NR_INSTALLED="Paigaldatud" NR_COMING_SOON="Tuleb varsti" NR_ROADMAP="Tegevuskavas" NR_MEDIA_VERSIONING="Kasuta meedia versioone" NR_MEDIA_VERSIONING_DESC="Vali, et määrata versiooninumber meedia (js/css) URL'le, et brauserid laeks õige faili." NR_LOAD_JQUERY="Lae jQuery" NR_LOAD_JQUERY_DESC="Vali, kas jQuery fail laetakse. Sa saad selle keelata kui sul võib lehel konflikte tekkida teiste jQuery versioonidega." NR_SELECT_CURRENCY="Vali valuuta" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Kampaania" NR_ASSIGN_CONVERTFORMS_DESC="Suuna kasutajaid kes on liitunud Convert Formsi kampaaniaga" NR_CONVERTFORMS_LIST_DESC="Vali, milline Convert Forms kampaania määratakse." NR_LEFT="Vasakul" NR_CENTER="Keskel" NR_RIGHT="Paremal" NR_BOTTOM="All" NR_TOP="Üleval" NR_AUTO="Auto" NR_CUSTOM="Oma" NR_UPLOAD="Lae üles" NR_IMAGE="Pilt" NR_INTRO_IMAGE="Sissejuhatav pilt" NR_FULL_IMAGE="Täispilt" NR_IMAGE_SELECT="Vali pilt" NR_IMAGE_SIZE_COVER="Kaas" NR_IMAGE_SIZE_CONTAIN="Sisaldab" NR_REPEAT="Korda" NR_REPEAT_X="Korda x" NR_REPEAT_Y="Korda y" NR_REPEAT_NO="Ei korda" NR_FIELD_STATE_DESC="Määra kirje staatus" NR_CREATED_DATE="Loomise kuupäev" NR_CREATED_DATE_DESC="Aeg, millal kirje loodi" NR_MODIFIFED_DATE="Muutmise aeg" NR_MODIFIFED_DATE_DESC="Aeg, millal kirjet muudeti." NR_CATEGORIES="Kategooria" NR_CATEGORIES_DESC="Vali kategooria millega siduda." NR_ALSO_ON_CHILD_ITEMS="Kaasa alamad" NR_ALSO_ON_CHILD_ITEMS_DESC="Kas valik kaasatakse ka alamatele?" NR_PAGE_TYPE="Lehe tüüp" NR_PAGE_TYPES="Lehe tüübid" NR_PAGE_TYPES_DESC="Vali milliste lehe tüüpide korral on sidumine aktiivne." NR_CONTENT_VIEW_CATEGORY_BLOG="Kategooria blogi" NR_CONTENT_VIEW_CATEGORY_LIST="Kategooria nimekiri" NR_CONTENT_VIEW_CATEGORIES="Näita kõiki kategooriaid" NR_CONTENT_VIEW_ARCHIVED="Arhiveeritud artiklid" NR_CONTENT_VIEW_FEATURES="Esiletõstetud artiklid" NR_CONTENT_VIEW_CREATE_ARTICLE="Loo artikkel" NR_CONTENT_VIEW_ARTICLE="Üks artikkel" NR_ARTICLE_VIEW_DESC="Luba kontole artikli vaade" NR_CATEGORY_VIEW="Kategooria vaade" NR_CATEGORY_VIEW_DESC="Luba kontole kategooria vaade" NR_CONTENT_VIEW="Sisu komponendi vaade" NR_CONTENT_VIEW_DESC="Vali vaated mida siduda." NR_ARTICLES="Artiklid" NR_ARTICLES_DESC="Vali artiklid mida siduda." NR_ARTICLE="Artikkel" NR_ARTICLE_AUTHORS="Autorid" NR_ARTICLE_AUTHORS_DESC="Vali autorid mida siduda." NR_ONLY="Ainult" NR_OTHERS="Teised" NR_SMARTTAGS="Nutikad võtmesõnad" NR_SMARTTAGS_SHOW="Näita nutikaid võtmesõnu" NR_SMARTTAGS_NOTFOUND="Nutikaid võtmesõnu ei leitud" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Otsi nutikaid võtmesõnu" NR_CONTACT_US="Võta meiega ühendust" NR_FONT_COLOR="Fondi värv" NR_FONT_SIZE="Fondi suurus" NR_FONT_SIZE_DESC="Määra fondi suurus pikslites" NR_TEXT="Tekst" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Luba väljundi ülekirjutuse korral" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Lubab lisa töötlemise kui lehe kujundus (tmpl) on üle kirjutatud. Näide: tmpl=component või tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Luba formaadi ülekirjutamise korral" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Lubab lisa töötlemise kui lehe formaat on midagi muud kui HTML. Näide: format=raw or format=json." NR_GEOLOCATING="Geolokeerin" NR_GEOLOCATION="Geolokeerimine" NR_GEOLOCATING_DESC="Geolokeerimine ei ole alati 100% õige. Geolokeerimine toimib kasutaja IP aadressi põhjal. Kõik IP aadressid ei ole fikseeritud ja teada." NR_CITY="Linn" NR_CITY_NAME="Linna nimi" NR_CONDITION_CITY_DESC="Sisesta linna nimi inglise keeles. Mitme linna korral eralda need komaga." NR_CONTINENT="Kontinent" NR_REGION="Regioon" NR_CONDITION_REGION_DESC="Väärtus koosneb kahest osast: kaks tähte ISO 3166-1 riigi koodi kohta ja regiooni kood. Ehk väärtus peab olea midagi järgmist: COUNTRY_CODE-REGION_CODE. Täielikuks regioonide koodide loeteluks kliki regiooni koodi otsimise lingile." NR_ASSIGN_COUNTRIES="Riik" NR_ASSIGN_COUNTRIES_DESC2="Kasutaja, kes füüsiliselt asub selles riigis" NR_ASSIGN_COUNTRIES_DESC="Vali riike millega siduda" NR_ASSIGN_CONTINENTS="Kontinent" NR_ASSIGN_CONTINENTS_DESC="Vali kontinendid millega siduda" NR_ASSIGN_CONTINENTS_DESC2="Kasutaja, kes füüsiliselt asub sellel kontinendil" NR_ICONTACT_ACCOUNTID_ERROR="iContact AccountID'd ei suutnud tuvastada" NR_TAG_CLIENTDEVICE="Külastaja seadme tüüp" NR_TAG_CLIENTOS="Külastaja operatsioonisüsteem" NR_TAG_CLIENTBROWSER="Külastaja brauser" NR_TAG_CLIENTUSERAGENT="Külastaja agendi string" NR_TAG_IP="Külastaja IP aadress" NR_TAG_URL="Lehe URL" NR_TAG_URLENCODED="Lehe URL" NR_TAG_URLPATH="Lehe kaust" NR_TAG_REFERRER="Lehele suunaja" NR_TAG_SITENAME="Lehe nimi" NR_TAG_SITEURL="Lehe URL" NR_TAG_PAGETITLE="Lehe pealkiri" NR_TAG_PAGEDESC="Lehe Meta iseloomustus" NR_TAG_PAGELANG="Lehe keelekood" NR_TAG_USERID="Kasutaja ID" NR_TAG_USERNAME="Kasutaja täis nimi" NR_TAG_USERLOGIN="Kasutaja kasutajanimi" NR_TAG_USEREMAIL="Kasutaja e-mail" NR_TAG_USERFIRSTNAME="Kasutaja eesnimi" NR_TAG_USERLASTNAME="Kasutaja perekonnnimi" NR_TAG_USERGROUPS="Kasutaja grupi ID" NR_TAG_DATE="Kuupäev" NR_TAG_TIME="Kellaaeg" NR_TAG_RANDOMID="Suvaline ID" NR_ICON="Ikoon" NR_SELECT_MODULE="Vali moodul" NR_SELECT_CONTINENT="Vali kontinent" NR_SELECT_COUNTRY="Vali riik" NR_PLUGIN="Plugin" NR_GMAP_KEY="Google Maks API võti" NR_GMAP_KEY_DESC="Tassos.gr lisad kasutavad Google Maps API võtit. Kui sa mõnes lisas ei näe Google kaarti korralikult, on asi just API võtmes." NR_GMAP_FIND_KEY="Hangi API võti" NR_ARE_YOU_SURE="Oled kindel?" NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Oled kindel, et soovid seda kustutada?" NR_CUSTOMURL="Oma URL" NR_SAMPLE="Näide" NR_DEBUG="Veatuvastus" NR_CUSTOMURL="Oma URL" NR_READMORE="Loe edasi" NR_IPADDRESS="IP aadress" NR_ASSIGN_BROWSERS="Brauser" NR_ASSIGN_BROWSERS_DESC="Vali brauser mida siduda" NR_ASSIGN_BROWSERS_DESC2="Sihi külastajaid brauseri järgi nagu Chrome, Firefox ja Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Operatsioonisüsteem" NR_ASSIGN_OS_DESC="Vali operatsioonisüsteeme mida siduda" NR_ASSIGN_OS_DESC2="Sihi kasutajaid kes kasutavad operatsioonisüsteeme nagu Windows, Linux või Mac." NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Lehe vaatamiste arv" NR_ASSIGN_PAGEVIEWS_DESC="Sihi kasutajaid kes on vaadanud teatud arv lehti" NR_ASSIGN_PAGEVIEWS_VIEWS="Lehe vaatamisi" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Sisesta ehe vaatamiste arv" NR_ASSIGN_COOKIENAME_NAME="Küpsise nimi" NR_ASSIGN_COOKIENAME_NAME_DESC="Sisesta küpsise nimi mis siduda" NR_ASSIGN_COOKIENAME_NAME_DESC2="Sihi külastajaid kes kasutavad brauseris siin määratud nimega küpsiseid" NR_FEWER_THAN="Vähem kui" NR_FEWER_THAN_OR_EQUAL_TO="Vähem või võrdne kui" NR_GREATER_THAN="Suurem kui" NR_GREATER_THAN_OR_EQUAL_TO="Suurem või võrdne kui" NR_EXACTLY="Täpselt" NR_EXISTS="Eksisteerib" NR_NOT_EXISTS="Ei eksisteeri" NR_IS_EQUAL="Võrdub" NR_DOES_NOT_EQUAL="Ei võrdu" NR_CONTAINS="Sisaldab" NR_DOES_NOT_CONTAIN="Ei sisalda" NR_STARTS_WITH="Algab" NR_DOES_NOT_START_WITH="Ei alga" NR_ENDS_WITH="Lõpeb" NR_DOES_NOT_END_WITH="Ei lõpe" NR_ASSIGN_COOKIENAME_CONTENT="Küpsise sisu" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Küpsise sisu" NR_ASSIGN_IP_ADDRESSES_DESC2="Sihi kasutajaid kes on määratud IP aadressite taga (vahemik)" NR_ASSIGN_IP_ADDRESSES_DESC="Sisesta komaga ja/või 'reavahetusklahviga' eraldatud IP aadressid ja vahemikud

Näiteks
127.0.0.1,
192.10-120.2,
168" NR_USER="Kasutaja" NR_ASSIGN_USER_SELECTION_DESC="Vali Joomla kasutaja kellega siduda" NR_ASSIGN_USER_ID="Kasutaja ID" NR_ASSIGN_USER_ID_DESC="Sihi Joomla kasutajat ID järgi" NR_ASSIGN_USER_ID_SELECTION_DESC="Sisesta komaga eraldatud Joomla kasutajate ID'd" NR_ASSIGN_COMPONENTS="Komponent" NR_ASSIGN_COMPONENTS_DESC="Vali komponendid millega siduda" NR_ASSIGN_COMPONENTS_DESC2="Sihi kasutajaid kes sirvivad määratud komponente" NR_ASSIGN_TIMERANGE="Ajavahemik" NR_ASSIGN_TIMERANGE_DESC="Sihi külastajaid serveri aja järgi" NR_START_TIME="Alguse aeg" NR_END_TIME="Lõpu aeg" NR_START_PUBLISHING_TIMERANGE_DESC="Vali avalikustamise aeg" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Vali avalikustamise lõpu aeg" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_DESC="Et hankida lehe võti, mine aadressile https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Lehe võti" NR_RECAPTCHA_SITE_KEY_DESC="Kasutatakse JavaScript failis mida kasutajad kasutavad." NR_RECAPTCHA_SECRET_KEY="Turvavõti" NR_RECAPTCHA_SECRET_KEY_DESC="Kasutatakse sinu serveri ja reCATCHA serveri vahel sutlemiseks. Hoia seeda turvaliselt peidus." NR_RECAPTCHA_SITE_KEY_ERROR="reCaptcha saidi võti puudub või on vale" NR_PREVIOUS_MONTH="Eelmine kuu" NR_NEXT_MONTH="Järgmine kuu" NR_ASSIGN_GROUP_PAGE_URL="Leht / URL" ; NR_ASSIGN_GROUP_PAGE_URL_DESC="Target visitors who are browsing specific menu items or URLs" ; NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" ; NR_ASSIGN_GROUP_USER_VISITOR="Joomla User / Visitor" ; NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" ; NR_ASSIGN_GROUP_PLATFORM="Visitor Platform" ; NR_ASSIGN_GROUP_PLATFORM_DESC="Target visitors who are using Mobile, Google Chrome, or even Windows" ; NR_ASSIGN_GROUP_GEO_DESC="Target visitors who are physically in a specific region" ; NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" ; NR_ASSIGN_GROUP_JCONTENT_DESC="Target visitors who are viewing specific Joomla articles or categories" ; NR_ASSIGN_GROUP_SYSTEM="System / Integrations" ; NR_INTEGRATIONS="Integrations" ; NR_ASSIGN_GROUP_SYSTEM_DESC="Target visitors who have interacted with specific 3rd party Joomla Extensions" ; NR_ASSIGN_GROUP_ADVANCED="Advanced visitor targeting" ; NR_ASSIGN_USERGROUP_DESC="Target specific Joomla user groups" ; NR_ASSIGN_ARTICLE_DESC="Target visitors who are viewing specific Joomla articles" ; NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target visitors who are viewing specific Joomla categories" ; NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." ; NR_ASSIGN_K2="K2" ; NR_ASSIGN_K2_DESC="Target visitors who are browsing specific K2 Items, Categories or Tags" ; NR_ASSIGN_K2_ITEMS="Item" ; NR_ASSIGN_K2_ITEMS_DESC="Target visitors who are browsing specific K2 items." ; NR_ASSIGN_K2_ITEMS_LIST_DESC="Select the K2 Items to assign to" ; NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Match on specific keywords in the item's content. Seperate by a comma or a new line." ; NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Match on the item's meta keywords. Seperate by a comma or a new line." ; NR_ASSIGN_K2_PAGETYPES_DESC="Target visitors who are browsing specific K2 page types" ; NR_ASSIGN_K2_ITEM_OPTION="Item" ; NR_ASSIGN_K2_LATEST_OPTION="Latest items from users or categories" ; NR_ASSIGN_K2_TAG_OPTION="Tag Page" ; NR_ASSIGN_K2_CATEGORY_OPTION="Category Page" ; NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Edit Form" ; NR_ASSIGN_K2_USER_PAGE_OPTION="User Page (blog)" ; NR_ASSIGN_K2_TAGS_DESC="Target visitors who are browsing K2 items with specific tags" ; NR_ASSIGN_K2_CATEGORIES_DESC="Target visitors who are browsing specific K2 categories" ; NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" ; NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" ; NR_ASSIGN_PAGE_TYPES_DESC="Select the page types to assign to" ; NR_ASSIGN_TAGS_DESC="Select the tags to assign to" ; NR_CONTENT_KEYWORDS="Content keywords" ; NR_META_KEYWORDS="Meta keywords" ; NR_TAG="Tag" ; NR_NORMAL="Normal" ; NR_COMPACT="Compact" ; NR_LIGHT="Light" ; NR_DARK="Dark" ; NR_SIZE="Size" ; NR_THEME="Theme" ; NR_SINGLE="Single" ; NR_MULTIPLE="Multiple" ; NR_RANGE="Range" NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_PLEASE_VALIDATE="Please validate" ; NR_RECAPTCHA_INVALID_SECRET_KEY="Invalid secret key" ; NR_PAGE="Page" ; NR_YOU_ARE_USING_EXTENSION="You are using %s %s" ; NR_UPDATE="Update" ; NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" ; NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." ; NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!șșBsystem/nrframework/language/fi-FI/fi-FI.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - used by Tassos.gr extensions" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ohita" NR_INCLUDE="Sisältää" NR_EXCLUDE="Sulkea" NR_SELECTION="Valinta" NR_ASSIGN_MENU_NOITEM="Ei sisällä kohdetta" NR_ASSIGN_MENU_NOITEM_DESC="Määritä myös, kun URL-osoitteeseen ei ole määritetty valikkokohtaa?" NR_ASSIGN_MENU_CHILD="Myös alakohta" NR_ASSIGN_MENU_CHILD_DESC="Määritetäänkö myös valittujen kohteiden alakohtiin?" NR_COPY_OF="Kopioitu %s" NR_ASSIGN_DATETIME_DESC="Kohdista vierailijat palvelimesi ajan perusteella" NR_DATETIME="Aika" NR_TIME="klo" NR_DATE="pvm" NR_DATETIME_DESC="Kirjoita päivämäärä, jolloin julkaistaan / julkaisu poistetaan automaattisesti" NR_START_PUBLISHING="Aloitus aika" NR_START_PUBLISHING_DESC="Anna aika kun julkaisu alkaa" NR_FINISH_PUBLISHING="Lopetus aika" NR_FINISH_PUBLISHING_DESC="Anna aika kun julkaisu päättyy" NR_DATETIME_NOTE="Päivämäärä- ja aikamääritykset käyttävät palvelimesi, ei vierailijajärjestelmän, päivämäärää ja aikaa." NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP koodi" NR_ASSIGN_PHP_DESC="Kirjoita pätkä PHP-koodia arvioitavaksi." NR_ASSIGN_PHP_DESC2="Kohdenna vierailijat arvioimaan mukautettua PHP-koodia. Koodin on palautettava arvo true tai false.

Esimerkiksi:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Sivuston aika" NR_SECONDS="Sekunnit" NR_ASSIGN_TIMEONSITE_DESC="Anna kesto sekunteina käyttäjän kokonaisaikaan (vierailun kesto), joka vietetään koko sivustollasi.

Esimerkki:
Jos haluat näyttää ruudun sen jälkeen, kun käyttäjä on viettänyt 3 minuuttia koko sivustollasi, kirjoita 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Kävijät, jotka selailevat tiettyjä URL-osoitteita" NR_ASSIGN_URLS_DESC="Kirjoita vastaavat URL-osoitteet (osa niistä).
Käytä uutta riviä jokaiselle osoitteelle." NR_ASSIGN_URLS_LIST="URL osumat" NR_ASSIGN_URLS_REGEX="Käytä säännöllistä lauseketta" NR_ASSIGN_URLS_REGEX_DESC="Valitse tämä, kun haluat käsitellä arvoa säännöllisinä lausekkeina." NR_ASSIGN_LANGS="Kieli" NR_ASSIGN_LANGS_DESC="Kävijät, jotka selailevat verkkosivustoasi tietyllä kielellä" NR_ASSIGN_LANGS_LIST_DESC="Valitse määritettävät kielet" NR_ASSIGN_DEVICES="Laite" NR_ASSIGN_DEVICES_DESC2="Vierailijat jotka käyttävät tiettyä laitetta, kuten mobiili, tabletti tai työpöytä." NR_ASSIGN_DEVICES_DESC="Valitse määritettävät laitteet." NR_ASSIGN_DEVICES_NOTE="Muista, että laitteen tunnistus ei ole aina 100% tarkka. Käyttäjät voivat määrittää selaimensa jäljittelemään muita laitteita" NR_MENU="Valikko" NR_MENU_ITEMS="Valikko nimike" NR_MENU_ITEMS_DESC="Vierailijat, jotka selailevat tiettyjä valikkonimikkeitä" NR_USERGROUP="Käyttäjäryhmä" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Käyttäjäryhmä" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Näytä tekijänoikeudet" NR_SHOW_COPYRIGHT_DESC="Jos valittu, ylimääräiset tekijänoikeustiedot näkyvät järjestelmänvalvojan näkymissä. Tassos.gr-laajennukset eivät koskaan näytä tekijänoikeustietoja tai linkkejä käyttöliittymässä." NR_WIDTH="Leveys" NR_WIDTH_DESC="Kirjoita leveys px, em tai %.
Esimerkki: 400px" NR_HEIGHT="Korkeus" NR_HEIGHT_DESC="Kirjoita korkeus px, em tai %.
Esimerkki: 400px" NR_PADDING="Täyte" NR_PADDING_DESC="Kirjoita täyte px, em tai %.
Esimerkki: 20px" NR_MARGIN="Marginaali" NR_MARGIN_DESC="CSS: n marginaaliominaisuutta käytetään luomaan tilaa laatikon ympärille ja asettamaan valkoisen tilan koko rajan ulkopuolella pikseleinä tai prosentteina.

Esimerkki 1: 25px
Esimerkki 2: 5%

Marginaalin määrittäminen kummallekin puolelle [yläosa oikea alaosa vasen]:

Vain yläpuoli: 25px 0 0 0
Vain oikea puoli: 0 25px 0 0
Vain alaosa: 0 0 25px 0
Vain vasemmalla puolella: 0 0 0 25px" NR_COLOR_HOVER="Kohdistus väri" NR_COLOR="Väri" NR_COLOR_DESC="Määritä väri HEX- tai RGBA-muodossa." NR_TEXT_COLOR="Tekstin väri" NR_BACKGROUND="Tausta" NR_BACKGROUND_COLOR="Taustaväri" NR_BACKGROUND_COLOR_DESC="Määritä taustaväri HEX- tai RGBA-muodossa. Syötä 'ei' käytöstä poistamiseksi. Absoluuttisen läpinäkyvyyden vuoksi kirjoita 'transparent'." NR_URL_SHORTENING_FAILED="Lyhennys %s kanssa %s epäonnistui %s." NR_EXPORT="Vie" NR_IMPORT="Tuo" NR_PLEASE_CHOOSE_A_VALID_FILE="Valitse kelvollinen tiedostonimi" NR_IMPORT_ITEMS="Tuotavat kohteet" NR_PUBLISH_ITEMS="Julkaistut kohteet" NR_AS_EXPORTED="On viety" NR_TITLE="Otsikko" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="AcyMailing lista" NR_ACYMAILING_LIST_DESC="Valitse määritettävät AcyMailing-luettelot." NR_ASSIGN_ACYMAILING_DESC="Vierailijat, jotka ovat tilanneet tiettyjä AcyMailing-luetteloita" NR_AKEEBASUBS="Akeeba lähetykset" NR_AKEEBASUBS_LEVELS="Tasot" NR_AKEEBASUBS_LEVELS_DESC="Valitse Akeeba lähetysten tasot, jotka haluat määrittää." NR_ASSIGN_AKEEBASUBS_DESC="Vierailijat, jotka ovat tilanneet tietyt Akeeba lähetykset" NR_MATCH="Sopivuus" NR_MATCH_DESC="Käytetty sopivuusmenetelmä arvon vertaamiseksi" NR_ASSIGN_MATCHING_METHOD="Sopivuusmenetelmä" NR_ASSIGN_MATCHING_METHOD_DESC="Should all or any assignments be matched?

All
Will be published if All of below assignments are matched.

Any
Will be published if Any (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." NR_ANY="Mikä tahansa" ; NR_ALL="All" NR_ASSIGN_REFERRER="Viittaava URL" NR_ASSIGN_REFERRER_DESC2="Kävijät, jotka tulevat sivustollesi tietystä lähteestä" NR_ASSIGN_REFERRER_DESC="Kirjoita yksi viittaava URL-osoite riviä kohti: Esimerkiksi:

google.com
facebook.com/sivu" NR_ASSIGN_REFERRER_NOTE="Muista, että URL-osoitteen määrittäminen ei ole aina 100% tarkkaa. Jotkut palvelimet voivat käyttää välityspalvelimia, jotka poistavat nämä tiedot, ja ne voidaan helposti väärentää." NR_PROFEATURE_HEADER="%s on PRO-version ominaisuus" NR_PROFEATURE_DESC="Valitettavasti %s ei ole käytettävissäsi. Päivitä PRO-versioon avataksesi kaikki nämä mahtavat ominaisuudet käyttöösi." NR_PROFEATURE_DISCOUNT="Bonus: %s ilmaisen version käyttäjät saavat 20% alennuksen normaalista hinnasta, joka otetaan automaattisesti käyttöön kassalla." NR_ONLY_AVAILABLE_IN_PRO="Saatavilla PRO-versiossa" NR_UPGRADE_TO_PRO="Päivitä PRO-versioon" NR_UPGRADE_TO_PRO_TO_UNLOCK="Päivitä Pro-versioon avataksesi" NR_UPGRADE_TO_PRO_VERSION="Mahtavaa! Vain yksi askel jäljellä. Viimeistele päivitys Pro-versioon napsauttamalla alla olevaa painiketta." NR_UNLOCK_PRO_FEATURE="Avaa Pro-ominaisuus" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="Vasemmalta oikealle" NR_RIGHT_TO_LEFT="Oikealta vasemmalle" NR_BGIMAGE="Taustakuva" NR_BGIMAGE_DESC="Aseta taustakuva" NR_BGIMAGE_FILE="Kuva" NR_BGIMAGE_FILE_DESC="Valitse tai lähetä tiedosto taustakuvaa varten." NR_BGIMAGE_REPEAT="Toista" NR_BGIMAGE_REPEAT_DESC="Taustan toista-ominaisuus määrittää, toistetaanko / miten toistetaan taustakuva. Oletuksena taustakuva toistuu sekä pystysuunnassa että vaakasuunnassa.

Toista: Taustakuva toistetaan sekä pystysuunnassa että vaakasuunnassa.

Toista x: Taustakuva toistetaan vain vaakasuunnassa

Toista y: Taustakuva toistetaan vain pystysuunnassa.

Ei toistoa: Taustakuvaa ei toisteta" NR_BGIMAGE_SIZE="Koko" NR_BGIMAGE_SIZE_DESC="Määritä taustakuvan koko.

Automaattinen: Taustakuva sisältää kuvan leveyden ja korkeuden.

Peitto: Skaalaa taustakuva niin suureksi kuin mahdollista, jotta tausta-alue on kokonaan taustakuvan peittämä. Jotkut taustakuvan osista eivät ehkä ole näkyvissä taustan sijoitusalueella

Sisältö: Skaalaa kuva suurimpaan kokoon siten, että sekä sen leveys että korkeus mahtuvat sisältöalueelle

100% 100%: Venytä taustakuva kattamaan kokonaan sisältöalueen." NR_BGIMAGE_POSITION="Asema" NR_BGIMAGE_POSITION_DESC="Taustan asema-ominaisuus asettaa taustakuvan aloitusaseman. Oletuksena taustakuva on sijoitettu vasempaan yläkulmaan. Ensimmäinen arvo on vaakasuora ja toinen arvo pystysuora.

Voit käyttää joko yhtä ennalta määritettyä arvoa tai kirjoittaa mukautetun arvon prosenttimääränä: x% y% pikseleinä xPos yPos." NR_RTL="Käytä RTL" NR_RTL_DESC="Oikealta vasemmalle -suuntainen teksti on välttämätön oikealta vasemmalle -skripteille, kuten arabia, heprea, syyria ja thaana." NR_HORIZONTAL="Vaakasuora" NR_VERTICAL="Pystysuora" NR_FORM_ORIENTATION="Lomakkeen suunta" NR_FORM_ORIENTATION_DESC="Valitse lomakkeen suunta" NR_ASSIGN_CATEGORY="Kategoriat" NR_ASSIGN_CATEGORY_DESC="Valitse määritettävät katekoriat" NR_ASSIGN_CATEGORY_CHILD="Myös alakohteet" NR_ASSIGN_CATEGORY_CHILD_DESC="Määritetäänkö myös valittujen kohteiden alakohteisiin?" NR_NEW="Uusi" NR_LIST="Lista" NR_DOCUMENTATION="Dokumentointi" NR_KNOWLEDGEBASE="Tietopankki" NR_FAQ="Ohje" NR_INFORMATION="Tiedot" NR_EXTENSION="Laajennus" NR_VERSION="Versio" NR_CHANGELOG="Muutosloki" ; NR_DOWNLOAD="Download" NR_DOWNLOAD_KEY_MISSING="Latausavain puuttuu" NR_DOWNLOAD_KEY="Latausavain" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="Jotta voit päivittää %s Joomla-päivittäjän kautta, sinun on kirjoitettava latausavaimesi Novarain Framework -laajennuksen asetuksiin." NR_DOWNLOAD_KEY_FIND="Etsi latausavain" NR_DOWNLOAD_KEY_UPDATE="Päivitä latausavain" NR_OK="OK" NR_MISSING="Puuttuu" NR_LICENSE="Lisenssi" NR_AUTHOR="Tekijä" NR_FOLLOWME="Seuraa minua" NR_FOLLOW="Seuraa %s" NR_TRANSLATE_INTEREST="Oletko kiinnostunut kääntämään %s kielellesi?" NR_TRANSIFEX_REQUEST="Lähetä minulle pyyntö Transifexiin" NR_HELP_WITH_TRANSLATIONS="Apua käännöksiin" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Kehittynyt" NR_USEGLOBAL="Käytä yleistä" NR_WEEKDAY="Viikonpäivä" NR_MONTH="Kuukausi" NR_MONDAY="maanantai" NR_TUESDAY="tiistai" NR_WEDNESDAY="keskiviikko" NR_THURSDAY="torstai" NR_FRIDAY="perjantai" NR_SATURDAY="lauantai" NR_WEEKEND="viikonloppu" NR_WEEKDAYS="viikonpäivät" NR_SUNDAY="sunnuntai" NR_JANUARY="tammikuu" NR_FEBRUARY="helmikuu" NR_MARCH="maaliskuu" NR_APRIL="huhtikuu" NR_MAY="toukokuu" NR_JUNE="kesäkuu" NR_JULY="heinäkuu" NR_AUGUST="elokuu" NR_SEPTEMBER="syyskuu" NR_OCTOBER="lokakuu" NR_NOVEMBER="marraskuu" NR_DECEMBER="joulukuu" NR_NEVER="Ei koskaan" NR_SECONDS="Sekunnit" NR_MINUTES="Minuutit" NR_HOURS="Tunnit" NR_DAYS="Päivät" NR_SESSION="Istunto" NR_EVER="Koskaan" NR_COOKIE="Eväste" NR_BOTH="Molemmat" NR_NONE="Ei mitään" ; NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Työasema" NR_MOBILES="Mobiili" NR_TABLETS="Tabletti" NR_PER_SESSION="Istuntoa kohti" NR_PER_DAY="Päivää kohti" NR_PER_WEEK="Viikkoa kohti" NR_PER_MONTH="Kuukautta kohti" NR_FOREVER="Ikuisesti" NR_FEATURE_UNDER_DEV="Tämä ominaisuus on kehitteillä" NR_LIKE_THIS_EXTENSION="Pidätkö tästä laajennuksesta?" NR_LEAVE_A_REVIEW="Jätä arvostelu JED:ssä" NR_SUPPORT="Tuki" NR_NEED_SUPPORT="Tarvitsetko tukea?" NR_DROP_EMAIL="Lähetä minulle sähköposti" NR_READ_DOCUMENTATION="Lue ohjeet" NR_COPYRIGHT="%s - Tassos.gr Kaikki oikeudet pidätetään" NR_DASHBOARD="Hallintapaneli" NR_NAME="Nimi" NR_WRONG_COORDINATES="Antamasi koordinaatit eivät kelpaa" NR_ENTER_COORDINATES="Leveysaste, Pituusaste" NR_NO_ITEMS_FOUND="Kohteita ei löytynyt" NR_ITEM_IDS="Ei kohteiden ID:tä" NR_TOGGLE="Toggle" NR_EXPAND="Laajentaa" NR_COLLAPSE="Collapse" NR_SELECTED="Valittu" NR_MAXIMIZE="Maksimoida" NR_MINIMIZE="Minimoida" NR_SELECTION="Valinta" NR_INSTALL="Asennus" NR_INSTALL_NOW="Asenna nyt" NR_INSTALLED="Asennettu" NR_COMING_SOON="Tulossa pian" NR_ROADMAP="Etenemissuunnitelmassa" NR_MEDIA_VERSIONING="Käytä mediaversioita" NR_MEDIA_VERSIONING_DESC="Valitse, jos haluat lisätä laajennusversion numeron medialle (js / css) URL-osoitteiden loppuun, jotta selaimet pakottavat lataamaan oikean tiedoston." NR_LOAD_JQUERY="Lataa jQuery" NR_LOAD_JQUERY_DESC="Valitse ladataksesi jQuery scripti. Voit poistaa tämän käytöstä, jos ilmenee ristiriitoja, kun sivupohja tai muut laajennukset lataavat oman jQuery-version." NR_SELECT_CURRENCY="Valitse valuutta" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Kampanja" NR_ASSIGN_CONVERTFORMS_DESC="Vierailijat, jotka ovat tilanneet tiettyjä Convert Forms-kampanjoita" NR_CONVERTFORMS_LIST_DESC="Valitse määritettävät Convert Forms-kampanjat." NR_LEFT="Vasen" NR_CENTER="Keskusta" NR_RIGHT="Oikea" NR_BOTTOM="Ala" NR_TOP="Ylä" NR_AUTO="Automaattinen" NR_CUSTOM="Mukautettu" NR_UPLOAD="Lataus" NR_IMAGE="Kuva" NR_INTRO_IMAGE="Johdantokuva" NR_FULL_IMAGE="Koko kuva" NR_IMAGE_SELECT="Valitse kuva" NR_IMAGE_SIZE_COVER="Peitto" NR_IMAGE_SIZE_CONTAIN="Sisältö" NR_REPEAT="Toista" NR_REPEAT_X="Toista x" NR_REPEAT_Y="Toista y" NR_REPEAT_NO="Ei toistoa" NR_FIELD_STATE_DESC="Aseta kohteen tila" NR_CREATED_DATE="Luontipäivä" NR_CREATED_DATE_DESC="Päivä, jolloin kohde luotiin" NR_MODIFIFED_DATE="Muokkauspäivä" NR_MODIFIFED_DATE_DESC="Päivä, jolloin kohdetta viimeksi muokattiin" NR_CATEGORIES="Kategoria" NR_CATEGORIES_DESC="Valitse kategoriat, jotka haluat määrittää." NR_ALSO_ON_CHILD_ITEMS="Myös alakohteet" NR_ALSO_ON_CHILD_ITEMS_DESC="Määritetäänkö myös valittujen kohteiden alakohteet?" NR_PAGE_TYPE="Sivun tyyppi" NR_PAGE_TYPES="Sivutyypit" NR_PAGE_TYPES_DESC="Valitse, mitkä sivutyypit ovat aktivoitu tehtävään." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" NR_ARTICLE_VIEW_DESC="Valitse ottaaksesi käyttöön artikkelinäkymän." NR_CATEGORY_VIEW="Kategorianäkymä" NR_CATEGORY_VIEW_DESC="Valitse ottaaksesi käyttöön kategorianäkymän." ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Artikkelit" NR_ARTICLES_DESC="Valitse artikkelit, jotka haluat käyttää." NR_ARTICLE="Artikkeli" NR_ARTICLE_AUTHORS="Tekijät" NR_ARTICLE_AUTHORS_DESC="Valitse tekijät." NR_ONLY="Vain" NR_OTHERS="Muut" NR_SMARTTAGS="Älykkäät tunnisteet" NR_SMARTTAGS_SHOW="Näytä älykkäät tunnisteet" NR_SMARTTAGS_NOTFOUND="Älykkäitä tunnisteita ei löytynyt" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Etsi älykkäitä tunnisteita" NR_CONTACT_US="Ota yhteyttä" NR_FONT_COLOR="Fontin väri" NR_FONT_SIZE="Fontin koko" NR_FONT_SIZE_DESC="Valitse fonttikoko pikseleinä" NR_TEXT="Teksti" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Ota käyttöön Output Override -toiminto" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Mahdollistaa laajennuksen renderoinnin, kun sivun asettelu (tmpl) ohitetaan. Esimerkkejä: tmpl = komponentti tai tmpl = modaali." NR_EXECUTE_ON_FORMAT_OVERRIDE="Ota käyttöön Format Override" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Mahdollistaa laajennuksen renderoinnin, kun sivumuoto ei ole muu kuin HTML. Esimerkkejä: format = raw tai format = json." NR_GEOLOCATING="Geopaikantaminen" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="Maantieteellinen sijainti ei ole aina 100%:n tarkka. Maantieteellinen sijainti perustuu vierailijan IP-osoitteeseen. Kaikki IP-osoitteet eivät ole kiinteitä tai tiedossa." NR_CITY="Kaupunki" NR_CITY_NAME="Kaupungin nimi" NR_CONDITION_CITY_DESC="Kirjoita kaupungin nimi englanniksi. Erota pilkuilla useammat kaupungit." NR_CONTINENT="Maanosa" NR_REGION="Alue" NR_CONDITION_REGION_DESC="Arvo koostuu kahdesta osasta, kaksikirjaimisesta ISO 3166-1-maakoodista ja aluekoodista. Joten arvon tulisi olla seuraavassa muodossa: COUNTRY_CODE-REGION_CODE. Katso täydellinen luettelo maakoodeista napsauttamalla Etsi aluekoodi -linkkiä." NR_ASSIGN_COUNTRIES="Valtio" NR_ASSIGN_COUNTRIES_DESC2="Vierailijat, jotka ovat fyysisesti tietyssä valtiossa" NR_ASSIGN_COUNTRIES_DESC="Valitse valtiot, jotka määritetään" NR_ASSIGN_CONTINENTS="Maanosa" NR_ASSIGN_CONTINENTS_DESC="Valitse maanosat, jotka määritetään" NR_ASSIGN_CONTINENTS_DESC2="Vierailijat, jotka ovat fyysisesti tietyssä maanosassa" NR_ICONTACT_ACCOUNTID_ERROR="IContact-tilitunnusta ei voitu noutaa" NR_TAG_CLIENTDEVICE="Vierailijan laitetyyppi" NR_TAG_CLIENTOS="Vierailijan käyttöjärjestelmä" NR_TAG_CLIENTBROWSER="Vierailijan selain" NR_TAG_CLIENTUSERAGENT="Vierailija agentti" NR_TAG_IP="Vierailijan IP-osoite" NR_TAG_URL="Sivu URL" NR_TAG_URLENCODED="Sivun koodattu URL" NR_TAG_URLPATH="Sivun polku" NR_TAG_REFERRER="Sivun viittaus" NR_TAG_SITENAME="Sivun nimi" NR_TAG_SITEURL="Sivun URL" NR_TAG_PAGETITLE="Sivun otsikko" NR_TAG_PAGEDESC="Sivun sisällönkuvaus" NR_TAG_PAGELANG="Sivun maakoodi" NR_TAG_USERID="Käyttäjän ID" NR_TAG_USERNAME="Käyttäjän koko nimi" NR_TAG_USERLOGIN="Käyttäjän kirjautuminen" NR_TAG_USEREMAIL="Käyttäjän sähköposti" NR_TAG_USERFIRSTNAME="Käyttäjän etunimi" NR_TAG_USERLASTNAME="Käyttäjän sukunimi" NR_TAG_USERGROUPS="Käyttäjän ryhmän ID" NR_TAG_DATE="Päivämäärä" NR_TAG_TIME="Aika" NR_TAG_RANDOMID="Satunnainen ID" NR_ICON="Kuvake" NR_SELECT_MODULE="Valitse Moduuli" NR_SELECT_CONTINENT="Valitse maanosa" NR_SELECT_COUNTRY="Valitse valtio" NR_PLUGIN="Liitännäinen" NR_GMAP_KEY="Google Maps API Key" NR_GMAP_KEY_DESC="Tassos.gr-laajennukset käyttävät Google Maps -sovellusliittymäavainta. Jos kohtaat ongelmia, kun Google Mapsia ei ladata, niin sinun on todennäköisesti annettava oma API-avaimesi." NR_GMAP_FIND_KEY="Hanki API key" NR_ARE_YOU_SURE="Oletko varma?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="Mukautettu URL" NR_SAMPLE="Näyte" NR_DEBUG="Debug" NR_CUSTOMURL="Mukautettu URL" NR_READMORE="Lue lisää" NR_IPADDRESS="IP osoite" NR_ASSIGN_BROWSERS="Selain" NR_ASSIGN_BROWSERS_DESC="Valitse selaimet, jotka haluat määrittää" NR_ASSIGN_BROWSERS_DESC2="Kävijät, jotka selailevat sivustoasi tietyillä selaimilla, kuten Chrome, Firefox tai Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Käyttöjärjestelmä" NR_ASSIGN_OS_DESC="Valitse määritettävät käyttöjärjestelmät" NR_ASSIGN_OS_DESC2="Vierailijat, jotka käyttävät tiettyjä käyttöjärjestelmiä, kuten Windows, Linux tai Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Sivun katselumäärä" NR_ASSIGN_PAGEVIEWS_DESC="Kävijät, jotka ovat katselleet tietyn määrän sivuja" NR_ASSIGN_PAGEVIEWS_VIEWS="Sivunäytöt" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Kirjoita sivun näyttökertojen lukumäärä" NR_ASSIGN_COOKIENAME_NAME="Evästeen nimi" NR_ASSIGN_COOKIENAME_NAME_DESC="Kirjoita evästeen nimi, jonka haluat määrittää" NR_ASSIGN_COOKIENAME_NAME_DESC2="Kävijät, joiden selaimeen on tallennettu tiettyjä evästeitä" NR_FEWER_THAN="Vähemmän kuin" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="Suurempi kuin" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Tarkalleen" NR_EXISTS="Olemassa" ; NR_NOT_EXISTS="Does not exists" NR_IS_EQUAL="Vastaa" ; NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Sisältää" ; NR_DOES_NOT_CONTAIN="Does not contain" NR_STARTS_WITH="Alkaa" ; NR_DOES_NOT_START_WITH="Does not start with" NR_ENDS_WITH="Loppuu" ; NR_DOES_NOT_END_WITH="Does not end with" NR_ASSIGN_COOKIENAME_CONTENT="Evästeen sisältö" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Evästeen sisältö" NR_ASSIGN_IP_ADDRESSES_DESC2="Käyttäjät, jotka ovat tietyn IP-osoitteen takana (alue)" NR_ASSIGN_IP_ADDRESSES_DESC="Kirjoita luettelo pilkuilla ja / tai 'syötä' erotetut IP-osoitteet ja alueet

Esimerkki:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="Käyttäjä ID" NR_ASSIGN_USER_ID_DESC="Joomla käyttäjän ID-tunnus" NR_ASSIGN_USER_ID_SELECTION_DESC="Käytä pilkkua erotellaksesi Joomla käyttäjien ID:t" NR_ASSIGN_COMPONENTS="Komponentti" NR_ASSIGN_COMPONENTS_DESC="Valitse komponentit, jotka määritetään" NR_ASSIGN_COMPONENTS_DESC2="Vierailijat, jotka selailevat tiettyjä komponentteja" NR_ASSIGN_TIMERANGE="Aikahaarukka" NR_ASSIGN_TIMERANGE_DESC="Vierailijat palvelimesi ajan perusteella" NR_START_TIME="Aloitusaika" NR_END_TIME="Lopetusaika" NR_START_PUBLISHING_TIMERANGE_DESC="Anna julkaisun aloittamisaika" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Anna julkaisun lopettamisaika" NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Site Key" NR_RECAPTCHA_SITE_KEY_DESC="Käytetään JavaScript-koodissa, jota tarjotaan käyttäjille." NR_RECAPTCHA_SECRET_KEY="Secret Key" NR_RECAPTCHA_SECRET_KEY_DESC="Käytetään palvelimen ja reCAPTCHA-palvelimen välisessä viestinnässä. Pidä avain salassa." NR_RECAPTCHA_SITE_KEY_ERROR="ReCaptcha-sivuston avain puuttuu tai on väärä" NR_PREVIOUS_MONTH="Edellinen kuukausi" NR_NEXT_MONTH="Seuraava kuukausi" NR_ASSIGN_GROUP_PAGE_URL="Sivu / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Kävijät, jotka selailevat tiettyjä valikkonimikkeitä tai URL-osoitteita" NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" NR_ASSIGN_GROUP_USER_VISITOR="Joomla käyttäjä / Vierailija" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Rekisteröidyt käyttäjät tai vierailijat, jotka ovat katselleet tietyn määrän sivuja" NR_ASSIGN_GROUP_PLATFORM="Vierailijan alusta" NR_ASSIGN_GROUP_PLATFORM_DESC="Kävijät, jotka käyttävät mobiililaitetta, Google Chromea tai Windowsia" NR_ASSIGN_GROUP_GEO_DESC="Vierailijat, jotka ovat fyysisesti tietyllä alueella" NR_ASSIGN_GROUP_JCONTENT="Joomla! Sisältö" NR_ASSIGN_GROUP_JCONTENT_DESC="Kävijät, jotka katsovat tiettyjä Joomla-artikkeleita tai kategorioita" NR_ASSIGN_GROUP_SYSTEM="Järjestelmä / integraatiot" ; NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Vierailijat, jotka ovat käyttäneet tiettyjä Joomla-laajennuksia" NR_ASSIGN_GROUP_ADVANCED="Edistyneet vierailijakohdistukset" NR_ASSIGN_USERGROUP_DESC="Tietyt Joomlan käyttäjäryhmät" NR_ASSIGN_ARTICLE_DESC="Vierailijat, jotka katsovat tiettyjä Joomla-artikkeleita" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Vierailijat, jotka katsovat tiettyjä Joomla kategorioita" NR_EXTENSION_REQUIRED="%s komponentti vaatii %s aajennuksen ottamisen käyttöön, jotta se toimii oikein." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Kävijät, jotka selailevat tiettyjä K2-kohteita, luokkia tai tunnisteita" NR_ASSIGN_K2_ITEMS="Kohde" NR_ASSIGN_K2_ITEMS_DESC="Kävijät, jotka selailevat tiettyjä K2-kohteita." NR_ASSIGN_K2_ITEMS_LIST_DESC="Valitse määritettävät K2-kohteet" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Yhdistä tiettyihin avainsanoihin kohteen sisällössä. Erota pilkulla tai uudella rivillä." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Yhdistä kohteen meta-avainsanoihin. Erota pilkulla tai uudella rivillä." NR_ASSIGN_K2_PAGETYPES_DESC="Kävijät, jotka selailevat tiettyjä K2-sivutyyppejä" NR_ASSIGN_K2_ITEM_OPTION="Kohde" NR_ASSIGN_K2_LATEST_OPTION="Uusimmat kohteet käyttäjiltä tai kategorioilta" NR_ASSIGN_K2_TAG_OPTION="Tag-sivu" NR_ASSIGN_K2_CATEGORY_OPTION="Kategoria sivu" NR_ASSIGN_K2_ITEM_FORM_OPTION="Kohteen muokkauslomake" NR_ASSIGN_K2_USER_PAGE_OPTION="Käyttäjän sivu (blog)" NR_ASSIGN_K2_TAGS_DESC="Kävijät, jotka selaavat K2-kohteita erityisillä tunnisteilla" NR_ASSIGN_K2_CATEGORIES_DESC="Kävijät, jotka selailevat tiettyjä K2-kategorioita" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Kategoriat" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Kohteet" NR_ASSIGN_PAGE_TYPES_DESC="Valitse määritettävät sivutyypit" NR_ASSIGN_TAGS_DESC="Valitse tunnisteet, jotka haluat määrittää" NR_CONTENT_KEYWORDS="Sisällön avainsanat" NR_META_KEYWORDS="Meta avainsanat" NR_TAG="Tag" NR_NORMAL="Normaali" NR_COMPACT="Tiivis" NR_LIGHT="Vaalea" NR_DARK="Tumma" NR_SIZE="Koko" NR_THEME="Teema" NR_SINGLE="Yksittäinen" NR_MULTIPLE="Moninkertainen" NR_RANGE="Alue" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Vahvista" NR_RECAPTCHA_INVALID_SECRET_KEY="Virheellinen secret key" NR_PAGE="Sivu" NR_YOU_ARE_USING_EXTENSION="Käytät %s %s" NR_UPDATE="Päivitys" NR_SHOW_UPDATE_NOTIFICATION="Näytä päivitysilmoitus" NR_SHOW_UPDATE_NOTIFICATION_DESC="Jos valittu, päivitysilmoitus näkyy pääkomponenttinäkymässä, kun laajennukselle on uusi versio." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s saatavilla" NR_ERROR_EMAIL_IS_DISABLED="Sähköpostin lähetys on poistettu käytöstä. Sähköposteja ei voitu lähettää." NR_ASSIGN_ITEMS="Kohde" NR_COUNTRY_AF="Afganistan" NR_COUNTRY_AX="Ahvenanmaa" NR_COUNTRY_AL="Albania" NR_COUNTRY_DZ="Algeria" NR_COUNTRY_AS="Amerikan Samoa" NR_COUNTRY_AD="Andorra" NR_COUNTRY_AO="Angola" NR_COUNTRY_AI="Anguilla" NR_COUNTRY_AQ="Etelämanner" NR_COUNTRY_AG="Antigua ja Barbuda" NR_COUNTRY_AR="Argentiina" NR_COUNTRY_AM="Armenia" NR_COUNTRY_AW="Aruba" NR_COUNTRY_AU="Australia" NR_COUNTRY_AT="Itävalta" NR_COUNTRY_AZ="Azerbaidžan" NR_COUNTRY_BS="Bahamasaaret" NR_COUNTRY_BH="Bahrain" NR_COUNTRY_BD="Bangladesh" NR_COUNTRY_BB="Barbados" NR_COUNTRY_BY="Valko-Venäjä" NR_COUNTRY_BE="Belgia" NR_COUNTRY_BZ="Belize" NR_COUNTRY_BJ="Benin" NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" NR_COUNTRY_BT="Bhutan" NR_COUNTRY_BO="Bolivia" NR_COUNTRY_BA="Bosnia ja Hertsegovina" NR_COUNTRY_BW="Botswana" NR_COUNTRY_BV="Bouvet’nsaari" NR_COUNTRY_BR="Brasilia" NR_COUNTRY_IO="Brittiläinen Intian valtameren alue" NR_COUNTRY_BN="Brunei" NR_COUNTRY_BG="Bulgaria" NR_COUNTRY_BF="Burkina Faso" NR_COUNTRY_BI="Burundi" NR_COUNTRY_KH="Kambodža" NR_COUNTRY_CM="Kamerun" NR_COUNTRY_CA="Kanada" NR_COUNTRY_CV="Kap Verde" NR_COUNTRY_KY="Caymansaaret" NR_COUNTRY_CF="Keski-Afrikan tasavalta" NR_COUNTRY_TD="Tsad" NR_COUNTRY_CL="Chile" NR_COUNTRY_CN="Kiina" NR_COUNTRY_CX="Joulusaari" NR_COUNTRY_CC="Kookossaaret" NR_COUNTRY_CO="Kolumbia" NR_COUNTRY_KM="Komorit" NR_COUNTRY_CG="Kongo" NR_COUNTRY_CD="Kongon demokraattinen tasavalta" NR_COUNTRY_CK="Cooksaaret" NR_COUNTRY_CR="Costa Rica" NR_COUNTRY_CI="Norsunluurannikko" NR_COUNTRY_HR="Kroatia" NR_COUNTRY_CU="Kuuba" ; NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Kypros" NR_COUNTRY_CZ="Tšekki" NR_COUNTRY_DK="Tanska" NR_COUNTRY_DJ="Djibouti" NR_COUNTRY_DM="Dominica" NR_COUNTRY_DO="Dominikaaninen tasavalta" NR_COUNTRY_EC="Ecuador" NR_COUNTRY_EG="Egypti" NR_COUNTRY_SV="El Salvador" NR_COUNTRY_GQ="Päiväntasaajan Guinea" NR_COUNTRY_ER="Eritrea" NR_COUNTRY_EE="Viro" NR_COUNTRY_ET="Etiopia" NR_COUNTRY_FK="Falklandinsaaret" NR_COUNTRY_FO="Färsaaret" NR_COUNTRY_FJ="Fidzi" NR_COUNTRY_FI="Suomi" NR_COUNTRY_FR="Ranska" NR_COUNTRY_GF="Ranskan Guayana" NR_COUNTRY_PF="Ranskan Polynesia" NR_COUNTRY_TF="Ranskan eteläiset ja antarktiset alueet" NR_COUNTRY_GA="Gabon" NR_COUNTRY_GM="Gambia" NR_COUNTRY_GE="Georgia" NR_COUNTRY_DE="Saksa" NR_COUNTRY_GH="Ghana" NR_COUNTRY_GI="Gibraltar" NR_COUNTRY_GR="Kreikka" NR_COUNTRY_GL="Grönlanti" NR_COUNTRY_GD="Grenada" NR_COUNTRY_GP="Guadeloupe" NR_COUNTRY_GU="Guam" NR_COUNTRY_GT="Guatemala" NR_COUNTRY_GG="Guernsey" NR_COUNTRY_GN="Guinea" NR_COUNTRY_GW="Guinea-Bissau" NR_COUNTRY_GY="Guyana" NR_COUNTRY_HT="Haiti" NR_COUNTRY_HM="Heard ja McDonaldinsaaret" NR_COUNTRY_VA="Vatikaanivaltio" NR_COUNTRY_HN="Honduras" NR_COUNTRY_HK="Hong Kong" NR_COUNTRY_HU="Unkari" NR_COUNTRY_IS="Islanti" NR_COUNTRY_IN="Intia" NR_COUNTRY_ID="Indonesia" NR_COUNTRY_IR="Iran" NR_COUNTRY_IQ="Irak" NR_COUNTRY_IE="Irlanti" NR_COUNTRY_IM="Mansaari" NR_COUNTRY_IL="Israel" NR_COUNTRY_IT="Italia" NR_COUNTRY_JM="Jamaika" NR_COUNTRY_JP="Japani" NR_COUNTRY_JE="Jersey" NR_COUNTRY_JO="Jordania" NR_COUNTRY_KZ="Kazakstan" NR_COUNTRY_KE="Kenia" NR_COUNTRY_KI="Kiribati" NR_COUNTRY_KP="Pohjois-Korea" NR_COUNTRY_KR="Etelä-Korea" NR_COUNTRY_KW="Kuwait" NR_COUNTRY_KG="Kirgisia" NR_COUNTRY_LA="Laos" NR_COUNTRY_LV="Latvia" NR_COUNTRY_LB="Libanon" NR_COUNTRY_LS="Lesotho" NR_COUNTRY_LR="Liberia" NR_COUNTRY_LY="Libya" NR_COUNTRY_LI="Liechtenstein" NR_COUNTRY_LT="Liettua" NR_COUNTRY_LU="Luxemburg" NR_COUNTRY_MO="Macao" NR_COUNTRY_MK="Pohjois-Makedonia" NR_COUNTRY_MG="Madagaskar" NR_COUNTRY_MW="Malawi" NR_COUNTRY_MY="Malesia" NR_COUNTRY_MV="Malediivit" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Malta" NR_COUNTRY_MH="Marshallsaaret" NR_COUNTRY_MQ="Martinique" NR_COUNTRY_MR="Mauritania" NR_COUNTRY_MU="Mauritius" NR_COUNTRY_YT="Mayotte" NR_COUNTRY_MX="Meksiko" NR_COUNTRY_FM="Mikronesian liittovaltio" NR_COUNTRY_MD="Moldova" NR_COUNTRY_MC="Monaco" NR_COUNTRY_MN="Mongolia" NR_COUNTRY_ME="Montenegro" NR_COUNTRY_MS="Montserrat" NR_COUNTRY_MA="Marokko" NR_COUNTRY_MZ="Mosambik" NR_COUNTRY_MM="Myanmar" NR_COUNTRY_NA="Namibia" NR_COUNTRY_NR="Nauru" NR_COUNTRY_NM="Pohjois-Makedonia" NR_COUNTRY_NP="Nepal" NR_COUNTRY_NL="Alankomaat" NR_COUNTRY_AN="Alankomaiden Antillit" NR_COUNTRY_NC="Uusi-Kaledonia" NR_COUNTRY_NZ="Uusi-Seelanti" NR_COUNTRY_NI="Nicaragua" NR_COUNTRY_NE="Niger" NR_COUNTRY_NG="Nigeria" NR_COUNTRY_NU="Niue" NR_COUNTRY_NF="Norfolkinsaari" NR_COUNTRY_MP="Pohjois-Mariaanit" NR_COUNTRY_NO="Norja" NR_COUNTRY_OM="Oman" NR_COUNTRY_PK="Pakistan" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Palestiina" NR_COUNTRY_PA="Panama" NR_COUNTRY_PG="Papua-Uusi-Guinea" NR_COUNTRY_PY="Paraguay" NR_COUNTRY_PE="Peru" NR_COUNTRY_PH="Filippiinit" NR_COUNTRY_PN="Pitcairnsaaret" NR_COUNTRY_PL="Puola" NR_COUNTRY_PT="Portugali" NR_COUNTRY_PR="Puerto Rico" NR_COUNTRY_QA="Qatar" NR_COUNTRY_RE="Reunion" NR_COUNTRY_RO="Romania" NR_COUNTRY_RU="Venäjä" NR_COUNTRY_RW="Ruanda" NR_COUNTRY_SH="Saint Helena" NR_COUNTRY_KN="Saint Kitts ja Nevis" NR_COUNTRY_LC="Saint Lucia" NR_COUNTRY_PM="Saint-Pierre ja Miquelon" NR_COUNTRY_VC="Saint Vincent ja Grenadiinit" NR_COUNTRY_WS="Samoa" NR_COUNTRY_SM="San Marino" NR_COUNTRY_ST="São Tomé ja Príncipe" NR_COUNTRY_SA="Saudi-Arabia" NR_COUNTRY_SN="Senegal" NR_COUNTRY_RS="Serbia" NR_COUNTRY_SC="Seychellit" NR_COUNTRY_SL="Sierra Leone" NR_COUNTRY_SG="Singapore" NR_COUNTRY_SK="Slovakia" NR_COUNTRY_SI="Slovenia" NR_COUNTRY_SB="Salomonsaaret" NR_COUNTRY_SO="Somalia" NR_COUNTRY_ZA="Etelä-Afrikka" NR_COUNTRY_GS="Etelä-Georgia ja Eteläiset Sandwichsaaret" NR_COUNTRY_ES="Espanja" NR_COUNTRY_LK="Sri Lanka" NR_COUNTRY_SD="Sudan" NR_COUNTRY_SS="Etelä-Sudan" NR_COUNTRY_SR="Surinam" NR_COUNTRY_SJ="Huippuvuoret" NR_COUNTRY_SZ="Swasimaa" NR_COUNTRY_SE="Ruotsi" NR_COUNTRY_CH="Sveitsi" NR_COUNTRY_SY="Syyria" NR_COUNTRY_TW="Taiwan" NR_COUNTRY_TJ="Tadžikistan" NR_COUNTRY_TZ="Tansania" NR_COUNTRY_TH="Thaimaa" NR_COUNTRY_TL="Timor-Leste" NR_COUNTRY_TG="Togo" NR_COUNTRY_TK="Tokelau" NR_COUNTRY_TO="Tonga" NR_COUNTRY_TT="Trinidad ja Tobago" NR_COUNTRY_TN="Tunisia" NR_COUNTRY_TR="Turkki" NR_COUNTRY_TM="Turkmenistan" NR_COUNTRY_TC="Turks- ja Caicossaaret" NR_COUNTRY_TV="Tuvalu" NR_COUNTRY_UG="Uganda" NR_COUNTRY_UA="Ukraina" NR_COUNTRY_AE="Arabiemiirikunnat" NR_COUNTRY_GB="Yhdistynyt kuningaskunta" NR_COUNTRY_US="Yhdysvallat" NR_COUNTRY_UM="Yhdysvaltain erillissaaret" NR_COUNTRY_UY="Uruguay" NR_COUNTRY_UZ="Uzbekistan" NR_COUNTRY_VU="Vanuatu" NR_COUNTRY_VE="Venezuela" NR_COUNTRY_VN="Vietnam" NR_COUNTRY_VG="Brittiläiset Neitsytsaaret" NR_COUNTRY_VI="Yhdysvaltain Neitsytsaaret" NR_COUNTRY_WF="Wallis ja Futuna" NR_COUNTRY_EH="Länsi-Sahara" NR_COUNTRY_YE="Jemen" NR_COUNTRY_ZM="Sambia" NR_COUNTRY_ZW="Zimbabwe" NR_CONTINENT_AF="Afrikka" NR_CONTINENT_AS="Aasia" NR_CONTINENT_EU="Eurooppa" NR_CONTINENT_NA="Pohjois-Ameriikka" NR_CONTINENT_SA="Etelä-Ameriikka" NR_CONTINENT_OC="Oseania" NR_CONTINENT_AN="Antarktis" NR_FRONTEND="Front-end" NR_BACKEND="Back-end" NR_EMBED="Upotus" NR_RATE="Arvostele %s" NR_REPORT_ISSUE="Ilmoita ongelma" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!,ʗʗBsystem/nrframework/language/en-GB/en-GB.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - used by Tassos.gr extensions" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignore" NR_INCLUDE="Include" NR_EXCLUDE="Exclude" NR_SELECTION="Selection" NR_ASSIGN_MENU_NOITEM="Include no Itemid" NR_ASSIGN_MENU_NOITEM_DESC="Also assign when no menu Itemid is set in URL?" NR_ASSIGN_MENU_CHILD="Also on child items" NR_ASSIGN_MENU_CHILD_DESC="Also assign to child items of the selected items?" NR_COPY_OF="Copy of %s" NR_ASSIGN_DATETIME_DESC="Target visitors based on your server's datetime" NR_DATETIME="Datetime" NR_TIME="Time" NR_DATE="Date" NR_DATETIME_DESC="Enter the datetime to auto publish/unpublish" NR_START_PUBLISHING="Start Datetime" NR_START_PUBLISHING_DESC="Enter the date to start publishing" NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="Enter the date to end publishing" NR_DATETIME_NOTE="The date and time assignments use the date/time of your servers, not that of the visitors system." NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP Code" NR_ASSIGN_PHP_DESC="Enter a piece of PHP code to evaluate." NR_ASSIGN_PHP_DESC2="Target visitors evaluating custom PHP code. The code must return the value true or false.

For instance:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Time on Site" NR_SECONDS="Seconds" NR_ASSIGN_TIMEONSITE_DESC="Enter a duration in seconds to compare with the user's total time (Visit duration) spent on your entire site .

Example:
If you want to display a box after the user has spent 3 minutes on your the entire site, enter 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Target visitors who are browsing specific URLs" NR_ASSIGN_URLS_DESC="Enter (part of) the URLs to match.
Use a new line for each different match." NR_ASSIGN_URLS_LIST="URL Matches" NR_ASSIGN_URLS_REGEX="Use Regular Expression" NR_ASSIGN_URLS_REGEX_DESC="Select to treat the value as regular expressions." NR_ASSIGN_LANGS="Language" NR_ASSIGN_LANGS_DESC="Target visitors who are browsing your website in specific language" NR_ASSIGN_LANGS_LIST_DESC="Select the Languages to assign to" NR_ASSIGN_DEVICES="Device" NR_ASSIGN_DEVICES_DESC2="Target visitors using specific device such as Mobile, Tablet or Desktop." NR_ASSIGN_DEVICES_DESC="Select the devices to assign to." NR_ASSIGN_DEVICES_NOTE="Keep in mind that device detection is not always 100% accurate. Users can setup their browser to mimic other devices" NR_MENU="Menu" NR_MENU_ITEMS="Menu Item" NR_MENU_ITEMS_DESC="Target visitors who are browsing specific menu items" NR_USERGROUP="User Group" NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="User Group" NR_USERACCESSLEVEL="User Access Level" NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Show Copyright" NR_SHOW_COPYRIGHT_DESC="If selected, extra copyright info will be displayed in the admin views. Tassos.gr extensions never show copyright info or backlinks on the frontend." NR_WIDTH="Width" NR_WIDTH_DESC="Enter width in px, em or %

Example: 400px" NR_HEIGHT="Height" NR_HEIGHT_DESC="Enter height in px, em or %

Example: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Enter padding in px, em or %

Example: 20px" NR_MARGIN="Margin" NR_MARGIN_DESC="The CSS margin propertiy is used to generate space around the box and set the size of the white space outside the border in pixels or in %.

Example 1: 25px
Example 2: 5%

Specifying the margin for each side [top right bottom left]:

Top side only: 25px 0 0 0
Right side only: 0 25px 0 0
Bottom side only: 0 0 25px 0
Left side only: 0 0 0 25px" NR_COLOR_HOVER="Hover Color" NR_COLOR="Color" NR_COLOR_DESC="Define a color in HEX or RGBA format." NR_TEXT_COLOR="Text Color" NR_BACKGROUND="Background" NR_BACKGROUND_COLOR="Background Color" NR_BACKGROUND_COLOR_DESC="Define a background color in HEX or RGBA format. To disable enter 'none'. For absolute transparency enter 'transparent'." NR_URL_SHORTENING_FAILED="Shortening %s with %s failed. %s." NR_EXPORT="Export" NR_IMPORT="Import" NR_PLEASE_CHOOSE_A_VALID_FILE="Please choose a valid filename" NR_IMPORT_ITEMS="Import Items" NR_PUBLISH_ITEMS="Publish items" NR_AS_EXPORTED="As exported" NR_TITLE="Title" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="AcyMailing List" NR_ACYMAILING_LIST_DESC="Select AcyMailing lists to assign to." NR_ASSIGN_ACYMAILING_DESC="Target visitors who have subscribed to specific AcyMailing lists" NR_AKEEBASUBS="Akeeba Subscriptions" NR_AKEEBASUBS_LEVELS="Levels" NR_AKEEBASUBS_LEVELS_DESC="Select Akeeba Subscription levels to assign to." NR_ASSIGN_AKEEBASUBS_DESC="Target visitors who have subscribed to specific Akeeba Subscriptions" NR_MATCH="Match" NR_MATCH_DESC="The used matching method to compare the value" NR_ASSIGN_MATCHING_METHOD="Matching Method" NR_ASSIGN_MATCHING_METHOD_DESC="Should all or any assignments be matched?

All
Will be published if All of below assignments are matched.

Any
Will be published if Any (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." NR_ANY="Any" NR_ALL="All" NR_ASSIGN_REFERRER="Referrer URL" NR_ASSIGN_REFERRER_DESC2="Target visitors who land on your site from a specific traffic source" NR_ASSIGN_REFERRER_DESC="Enter one Referrer URL per line: Eg:

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Keep in mind that URL Referrer discovery is not always 100% accurate. Some servers may use proxies that strip this information out and it can be easily forged." NR_PROFEATURE_HEADER="%s is a PRO Feature" NR_PROFEATURE_DESC="We're sorry, %s is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features." NR_PROFEATURE_DISCOUNT="Bonus: %s free users get 20% off regular price, automatically applied at checkout." NR_ONLY_AVAILABLE_IN_PRO="Only available in PRO version" NR_UPGRADE_TO_PRO="Upgrade to Pro" NR_UPGRADE_TO_PRO_TO_UNLOCK="Upgrade to Pro version to unlock" NR_UPGRADE_TO_PRO_VERSION="Awesome! Only one step left. Click on the button below to complete the upgrade to the Pro version." NR_UNLOCK_PRO_FEATURE="Unlock Pro Feature" NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="Left to Right" NR_RIGHT_TO_LEFT="Right to Left" NR_BGIMAGE="Background Image" NR_BGIMAGE_DESC="Sets a background image" NR_BGIMAGE_FILE="Image" NR_BGIMAGE_FILE_DESC="Select or a upload a file for the background-image." NR_BGIMAGE_REPEAT="Repeat" NR_BGIMAGE_REPEAT_DESC="The background-repeat property sets if/how a background image will be repeated. By default, a background-image is repeated both vertically and horizontally.

Repeat: The background image will be repeated both vertically and horizontally.

Repeat-x: The background image will be repeated only horizontally

Repeat-y: The background image will be repeated only vertically

No-repeat: The background-image will not be repeated" NR_BGIMAGE_SIZE="Size" NR_BGIMAGE_SIZE_DESC="Specify the size of a background image.

Auto:The background-image contains its width and height

Cover: Scale the background image to be as large as possible so that the background area is completely covered by the background image. Some parts of the background image may not be in view within the background positioning area

Contain: Scale the image to the largest size such that both its width and its height can fit inside the content area

100% 100%: Stretch the background image to completely cover the content area." NR_BGIMAGE_POSITION="Position" NR_BGIMAGE_POSITION_DESC="The background-position property sets the starting position of a background image. By default, a background-image is placed at the top-left corner. The first value is the horizontal position and the second value is the vertical.

You can use either one of the predefined values, or enter a custom value in percentage: x% y% or in pixel xPos yPos." NR_RTL="Enable RTL" NR_RTL_DESC="The right-to-left text direction is essential for right-to-left scripts such as Arabic, Hebrew, Syriac, and Thaana." NR_HORIZONTAL="Horizontal" NR_VERTICAL="Vertical" NR_FORM_ORIENTATION="Form Orientation" NR_FORM_ORIENTATION_DESC="Select the form orientation" NR_ASSIGN_CATEGORY="Categories" NR_ASSIGN_CATEGORY_DESC="Select the categories to assign to" NR_ASSIGN_CATEGORY_CHILD="Also on child items" NR_ASSIGN_CATEGORY_CHILD_DESC="Also assign to child items of the selected items?" NR_NEW="New" NR_LIST="List" NR_DOCUMENTATION="Documentation" NR_KNOWLEDGEBASE="Knowledgebase" NR_FAQ="FAQ" NR_INFORMATION="Information" NR_EXTENSION="Extension" NR_VERSION="Version" NR_CHANGELOG="Changelog" NR_DOWNLOAD="Download" NR_DOWNLOAD_KEY_MISSING="Download Key is missing" NR_DOWNLOAD_KEY="Download Key" NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="To be able to update %s via the Joomla updater, you will need enter your Download Key in the settings of the Novarain Framework Plugin" NR_DOWNLOAD_KEY_FIND="Find Download Key" NR_DOWNLOAD_KEY_UPDATE="Update Download Key" NR_OK="OK" NR_MISSING="Missing" NR_LICENSE="License" NR_AUTHOR="Author" NR_FOLLOWME="Follow me" NR_FOLLOW="Follow %s" NR_TRANSLATE_INTEREST="Would you be interested in helping out with translating %s into your Language?" NR_TRANSIFEX_REQUEST="Send me a request on Transifex" NR_HELP_WITH_TRANSLATIONS="Help with translations" NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Advanced" NR_USEGLOBAL="Use Global" NR_WEEKDAY="Day of Week" NR_MONTH="Month" NR_MONDAY="Monday" NR_TUESDAY="Tuesday" NR_WEDNESDAY="Wednesday" NR_THURSDAY="Thursday" NR_FRIDAY="Friday" NR_SATURDAY="Saturday" NR_WEEKEND="Weekend" NR_WEEKDAYS="Weekdays" NR_SUNDAY="Sunday" NR_JANUARY="January" NR_FEBRUARY="February" NR_MARCH="March" NR_APRIL="April" NR_MAY="May" NR_JUNE="June" NR_JULY="July" NR_AUGUST="August" NR_SEPTEMBER="September" NR_OCTOBER="October" NR_NOVEMBER="November" NR_DECEMBER="December" NR_NEVER="Never" NR_SECONDS="Seconds" NR_MINUTES="Minutes" NR_HOURS="Hours" NR_DAYS="Days" NR_SESSION="Session" NR_EVER="Ever" NR_COOKIE="Cookie" NR_BOTH="Both" NR_NONE="None" NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Desktop" NR_MOBILES="Mobile" NR_TABLETS="Tablet" NR_DESKTOPS_WITH_BREAKPOINT_INFO="Desktop (Device screen greater than 992px)" NR_TABLETS_WITH_BREAKPOINT_INFO="Tablet (Device screen between 576px and 992px)" NR_MOBILES_WITH_BREAKPOINT_INFO="Mobile (Device screen less than 576px)" NR_PER_SESSION="Per Session" NR_PER_DAY="Per Day" NR_PER_WEEK="Per Week" NR_PER_MONTH="Per Month" NR_FOREVER="Forever" NR_FEATURE_UNDER_DEV="This feature is under development" NR_LIKE_THIS_EXTENSION="Like this extension?" NR_LEAVE_A_REVIEW="Leave a review on JED" NR_SUPPORT="Support" NR_NEED_SUPPORT="Need support?" NR_DROP_EMAIL="Drop me an e-mail" NR_READ_DOCUMENTATION="Read the Documentation" NR_COPYRIGHT="%s - Tassos.gr All Rights Reserved" NR_DASHBOARD="Dashboard" NR_NAME="Name" NR_WRONG_COORDINATES="The coordinates you provided are not valid" NR_ENTER_COORDINATES="Latitude,Longitude" NR_NO_ITEMS_FOUND="No Items Found" NR_ITEM_IDS="No Item IDs" NR_TOGGLE="Toggle" NR_EXPAND="Expand" NR_COLLAPSE="Collapse" NR_SELECTED="Selected" NR_MAXIMIZE="Maximize" NR_MINIMIZE="Minimize" NR_SELECTION="Selection" NR_INSTALL="Install" NR_INSTALL_NOW="Install Now" NR_INSTALLED="Installed" NR_COMING_SOON="Coming soon" NR_ROADMAP="On the roadmap" NR_MEDIA_VERSIONING="Use Media Versioning" NR_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." NR_LOAD_JQUERY="Load jQuery" NR_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." NR_SELECT_CURRENCY="Select a Currency" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Campaign" NR_ASSIGN_CONVERTFORMS_DESC="Target visitors who have subscribed to specific ConvertForms campaigns" NR_CONVERTFORMS_LIST_DESC="Select ConvertForms campaigns to assign to." NR_LEFT="Left" NR_CENTER="Center" NR_RIGHT="Right" NR_BOTTOM="Bottom" NR_TOP="Top" NR_AUTO="Auto" NR_CUSTOM="Custom" NR_UPLOAD="Upload" NR_IMAGE="Image" NR_INTRO_IMAGE="Intro Image" NR_FULL_IMAGE="Full Image" NR_IMAGE_SELECT="Select Image" NR_IMAGE_SIZE_COVER="Cover" NR_IMAGE_SIZE_CONTAIN="Contain" NR_REPEAT="Repeat" NR_REPEAT_X="Repeat x" NR_REPEAT_Y="Repeat y" NR_REPEAT_NO="No repeat" NR_FIELD_STATE_DESC="Set item's state" NR_CREATED_DATE="Created Date" NR_CREATED_DATE_DESC="The date the item was created" NR_MODIFIFED_DATE="Modified Date" NR_MODIFIFED_DATE_DESC="The date that the item was last modified." NR_CATEGORIES="Category" NR_CATEGORIES_DESC="Select the categories to assign to." NR_ALSO_ON_CHILD_ITEMS="Also on child items" NR_ALSO_ON_CHILD_ITEMS_DESC="Also assign to child items of the selected items?" NR_PAGE_TYPE="Page type" NR_PAGE_TYPES="Page types" NR_PAGE_TYPES_DESC="Select on what page types the assignment should be active." NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" NR_CONTENT_VIEW_CATEGORY_LIST="Category List" NR_CONTENT_VIEW_CATEGORIES="List All Categories" NR_CONTENT_VIEW_ARCHIVED="Archived Articles" NR_CONTENT_VIEW_FEATURES="Featured Articles" NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" NR_CONTENT_VIEW_ARTICLE="Single Article" NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" NR_CATEGORY_VIEW="Category View" NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" NR_CONTENT_VIEW="Content Component View" NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Articles" NR_ARTICLES_DESC="Select the articles to assign to." NR_ARTICLE="Article" NR_ARTICLE_AUTHORS="Authors" NR_ARTICLE_AUTHORS_DESC="Select the authors to assign to." NR_ONLY="Only" NR_OTHERS="Others" NR_SMARTTAGS="Smart Tags" NR_SMARTTAGS_SHOW="Show Smart Tags" NR_SMARTTAGS_NOTFOUND="No Smart Tags found" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" NR_CONTACT_US="Contact us" NR_FONT_COLOR="Font Color" NR_FONT_SIZE="Font Size" NR_FONT_SIZE_DESC="Choose a font size in pixels" NR_TEXT="Text" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Enable on Output Override" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Enables the extension rendering when the page layout (tmpl) is overriden. Examples: tmpl=component or tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Enable on Format Override" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Enables the extension rendering when the page format is not other than HTML. Examples: format=raw or format=json." NR_GEOLOCATING="Geolocating" NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="Geolocating is not always 100% accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known." NR_CITY="City" NR_CITY_NAME="City Name" NR_CONDITION_CITY_DESC="Enter a city name in English. Enter multiple cities separated by comma." NR_CONTINENT="Continent" NR_REGION="Region" NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." NR_ASSIGN_COUNTRIES="Country" NR_ASSIGN_COUNTRIES_DESC2="Target visitors who are physically in a specific country" NR_ASSIGN_COUNTRIES_DESC="Select the countries to assign to" NR_ASSIGN_CONTINENTS="Continent" NR_ASSIGN_CONTINENTS_DESC="Select the continents to assign to" NR_ASSIGN_CONTINENTS_DESC2="Target visitors who are physically in a specific continent" NR_ICONTACT_ACCOUNTID_ERROR="The iContact AccountID could not be retrieved" NR_TAG_CLIENTDEVICE="Visitor Device Type" NR_TAG_CLIENTOS="Visitor Operating System" NR_TAG_CLIENTBROWSER="Visitor Browser" NR_TAG_CLIENTUSERAGENT="Visitor Agent String" NR_TAG_IP="Visitor IP Address" NR_TAG_URL="Page URL" NR_TAG_URLENCODED="Page URL Encoded" NR_TAG_URLPATH="Page Path" NR_TAG_REFERRER="Page Referrer" NR_TAG_SITENAME="Site Name" NR_TAG_SITEURL="Site URL" NR_TAG_PAGETITLE="Page Title" NR_TAG_PAGEDESC="Page Meta Description" NR_TAG_PAGELANG="Page Language Code" NR_TAG_USERID="User ID" NR_TAG_USERNAME="User Full Name" NR_TAG_USERLOGIN="User Login" NR_TAG_USEREMAIL="User Email" NR_TAG_USERFIRSTNAME="User First Name" NR_TAG_USERLASTNAME="User Last Name" NR_TAG_USERGROUPS="User Groups IDs" NR_TAG_DATE="Date" NR_TAG_TIME="Time" NR_TAG_RANDOMID="Random ID" NR_ICON="Icon" NR_SELECT_MODULE="Select a Module" NR_SELECT_CONTINENT="Select a Continent" NR_SELECT_COUNTRY="Select a Country" NR_PLUGIN="Plugin" NR_GMAP_KEY="Google Maps API Key" NR_GMAP_KEY_DESC="The Google Maps API Key is being used by Tassos.gr extensions. If you face any troubles with a Google Map not being loaded then you probably need to enter your own API Key." NR_GMAP_FIND_KEY="Get an API key" NR_ARE_YOU_SURE="Are you sure?" NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="Custom URL" NR_SAMPLE="Sample" NR_DEBUG="Debug" NR_CUSTOMURL="Custom URL" NR_READMORE="Read More" NR_IPADDRESS="IP Address" NR_ASSIGN_BROWSERS="Browser" NR_ASSIGN_BROWSERS_DESC="Select the browsers to assign to" NR_ASSIGN_BROWSERS_DESC2="Target visitors who are browsing your site with specific browsers such as Chrome, Firefox or Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Operating System" NR_ASSIGN_OS_DESC="Select the operating systems to assign to" NR_ASSIGN_OS_DESC2="Target visitors who are using specific operating systems such as Windows, Linux or Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Number of Pageviews" NR_ASSIGN_PAGEVIEWS_DESC="Target visitors who have viewed certain number of pages" NR_ASSIGN_PAGEVIEWS_VIEWS="Pageviews" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Enter the number of page views" NR_ASSIGN_COOKIENAME_NAME="Cookie Name" NR_ASSIGN_COOKIENAME_NAME_DESC="Enter the name of the cookie to assign to" NR_ASSIGN_COOKIENAME_NAME_DESC2="Target visitors who have specific cookies stored in their browser" NR_FEWER_THAN="Fewer than" NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="Greater than" NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Exactly" NR_EXISTS="Exists" NR_NOT_EXISTS="Does not exists" NR_IS_EQUAL="Equals" NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Contains" NR_DOES_NOT_CONTAIN="Does not contain" NR_STARTS_WITH="Starts with" NR_DOES_NOT_START_WITH="Does not start with" NR_ENDS_WITH="Ends with" NR_DOES_NOT_END_WITH="Does not end with" NR_ASSIGN_COOKIENAME_CONTENT="Cookie Content" NR_ASSIGN_COOKIENAME_CONTENT_DESC="The cookie's content" NR_ASSIGN_IP_ADDRESSES_DESC2="Target visitors who are behind a specific IP address (range)" NR_ASSIGN_IP_ADDRESSES_DESC="Enter a list of comma and/or 'enter' separated ip addresses and ranges

Example:
127.0.0.1,
192.10-120.2,
168" NR_USER="User" NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="User ID" NR_ASSIGN_USER_ID_DESC="Target specific Joomla Users by their IDs" NR_ASSIGN_USER_ID_SELECTION_DESC="Enter comma separated Joomla user IDs" NR_ASSIGN_COMPONENTS="Component" NR_ASSIGN_COMPONENTS_DESC="Select the components to assign to" NR_ASSIGN_COMPONENTS_DESC2="Target visitors who are browsing specific components" NR_ASSIGN_TIMERANGE="Time Range" NR_ASSIGN_TIMERANGE_DESC="Target visitors based on your server's time" NR_START_TIME="Start Time" NR_END_TIME="End Time" NR_START_PUBLISHING_TIMERANGE_DESC="Enter the time to start publishing" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Enter the time to end publishing" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Site Key" NR_RECAPTCHA_SITE_KEY_DESC="Used in the JavaScript code that is served to your users." NR_RECAPTCHA_SECRET_KEY="Secret Key" NR_RECAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret." NR_RECAPTCHA_SITE_KEY_ERROR="The reCaptcha Site Key is either missing or invalid" NR_PREVIOUS_MONTH="Previous Month" NR_NEXT_MONTH="Next Month" NR_ASSIGN_GROUP_PAGE_URL="Page / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Target visitors who are browsing specific menu items or URLs" NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" NR_ASSIGN_GROUP_USER_VISITOR="Joomla User / Visitor" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" NR_ASSIGN_GROUP_PLATFORM="Visitor Platform" NR_ASSIGN_GROUP_PLATFORM_DESC="Target visitors who are using Mobile, Google Chrome, or even Windows" NR_ASSIGN_GROUP_GEO_DESC="Target visitors who are physically in a specific region" NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" NR_ASSIGN_GROUP_JCONTENT_DESC="Target visitors who are viewing specific Joomla articles or categories" NR_ASSIGN_GROUP_SYSTEM="System / Integrations" NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Target visitors who have interacted with specific 3rd party Joomla Extensions" NR_ASSIGN_GROUP_ADVANCED="Advanced visitor targeting" NR_ASSIGN_USERGROUP_DESC="Target specific Joomla user groups" NR_ASSIGN_ARTICLE_DESC="Target visitors who are viewing specific Joomla articles" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target visitors who are viewing specific Joomla categories" NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Target visitors who are browsing specific K2 Items, Categories or Tags" NR_ASSIGN_K2_ITEMS="Item" NR_ASSIGN_K2_ITEMS_DESC="Target visitors who are browsing specific K2 items." NR_ASSIGN_K2_ITEMS_LIST_DESC="Select the K2 Items to assign to" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Match on specific keywords in the item's content. Seperate by a comma or a new line." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Match on the item's meta keywords. Seperate by a comma or a new line." NR_ASSIGN_K2_PAGETYPES_DESC="Target visitors who are browsing specific K2 page types" NR_ASSIGN_K2_ITEM_OPTION="Item" NR_ASSIGN_K2_LATEST_OPTION="Latest items from users or categories" NR_ASSIGN_K2_TAG_OPTION="Tag Page" NR_ASSIGN_K2_CATEGORY_OPTION="Category Page" NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Edit Form" NR_ASSIGN_K2_USER_PAGE_OPTION="User Page (blog)" NR_ASSIGN_K2_TAGS_DESC="Target visitors who are browsing K2 items with specific tags" NR_ASSIGN_K2_CATEGORIES_DESC="Target visitors who are browsing specific K2 categories" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" NR_ASSIGN_PAGE_TYPES_DESC="Select the page types to assign to" NR_ASSIGN_TAGS_DESC="Select the tags to assign to" NR_CONTENT_KEYWORDS="Content keywords" NR_META_KEYWORDS="Meta keywords" NR_TAG="Tag" NR_NORMAL="Normal" NR_COMPACT="Compact" NR_LIGHT="Light" NR_DARK="Dark" NR_SIZE="Size" NR_THEME="Theme" NR_SINGLE="Single" NR_MULTIPLE="Multiple" NR_RANGE="Range" NR_RECAPTCHA="ReCaptcha" NR_RECAPTCHA_PLEASE_VALIDATE="Please validate" NR_RECAPTCHA_INVALID_SECRET_KEY="Invalid secret key" NR_PAGE="Page" NR_YOU_ARE_USING_EXTENSION="You are using %s %s" NR_UPDATE="Update" NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." NR_ASSIGN_ITEMS="Item" NR_COUNTRY_AF="Afghanistan" NR_COUNTRY_AX="Aland Islands" NR_COUNTRY_AL="Albania" NR_COUNTRY_DZ="Algeria" NR_COUNTRY_AS="American Samoa" NR_COUNTRY_AD="Andorra" NR_COUNTRY_AO="Angola" NR_COUNTRY_AI="Anguilla" NR_COUNTRY_AQ="Antarctica" NR_COUNTRY_AG="Antigua and Barbuda" NR_COUNTRY_AR="Argentina" NR_COUNTRY_AM="Armenia" NR_COUNTRY_AW="Aruba" NR_COUNTRY_AU="Australia" NR_COUNTRY_AT="Austria" NR_COUNTRY_AZ="Azerbaijan" NR_COUNTRY_BS="Bahamas" NR_COUNTRY_BH="Bahrain" NR_COUNTRY_BD="Bangladesh" NR_COUNTRY_BB="Barbados" NR_COUNTRY_BY="Belarus" NR_COUNTRY_BE="Belgium" NR_COUNTRY_BZ="Belize" NR_COUNTRY_BJ="Benin" NR_COUNTRY_BM="Bermuda" NR_COUNTRY_BQ_BO="Bonaire" NR_COUNTRY_BQ_SA="Saba" NR_COUNTRY_BQ_SE="Sint Eustatius" NR_COUNTRY_BT="Bhutan" NR_COUNTRY_BO="Bolivia" NR_COUNTRY_BA="Bosnia and Herzegovina" NR_COUNTRY_BW="Botswana" NR_COUNTRY_BV="Bouvet Island" NR_COUNTRY_BR="Brazil" NR_COUNTRY_IO="British Indian Ocean Territory" NR_COUNTRY_BN="Brunei Darussalam" NR_COUNTRY_BG="Bulgaria" NR_COUNTRY_BF="Burkina Faso" NR_COUNTRY_BI="Burundi" NR_COUNTRY_KH="Cambodia" NR_COUNTRY_CM="Cameroon" NR_COUNTRY_CA="Canada" NR_COUNTRY_CV="Cape Verde" NR_COUNTRY_KY="Cayman Islands" NR_COUNTRY_CF="Central African Republic" NR_COUNTRY_TD="Chad" NR_COUNTRY_CL="Chile" NR_COUNTRY_CN="China" NR_COUNTRY_CX="Christmas Island" NR_COUNTRY_CC="Cocos (Keeling) Islands" NR_COUNTRY_CO="Colombia" NR_COUNTRY_KM="Comoros" NR_COUNTRY_CG="Congo" NR_COUNTRY_CD="Congo, The Democratic Republic of the" NR_COUNTRY_CK="Cook Islands" NR_COUNTRY_CR="Costa Rica" NR_COUNTRY_CI="Cote d'Ivoire" NR_COUNTRY_HR="Croatia" NR_COUNTRY_CU="Cuba" NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Cyprus" NR_COUNTRY_CZ="Czech Republic" NR_COUNTRY_DK="Denmark" NR_COUNTRY_DJ="Djibouti" NR_COUNTRY_DM="Dominica" NR_COUNTRY_DO="Dominican Republic" NR_COUNTRY_EC="Ecuador" NR_COUNTRY_EG="Egypt" NR_COUNTRY_SV="El Salvador" NR_COUNTRY_GQ="Equatorial Guinea" NR_COUNTRY_ER="Eritrea" NR_COUNTRY_EE="Estonia" NR_COUNTRY_ET="Ethiopia" NR_COUNTRY_FK="Falkland Islands (Malvinas)" NR_COUNTRY_FO="Faroe Islands" NR_COUNTRY_FJ="Fiji" NR_COUNTRY_FI="Finland" NR_COUNTRY_FR="France" NR_COUNTRY_GF="French Guiana" NR_COUNTRY_PF="French Polynesia" NR_COUNTRY_TF="French Southern Territories" NR_COUNTRY_GA="Gabon" NR_COUNTRY_GM="Gambia" NR_COUNTRY_GE="Georgia" NR_COUNTRY_DE="Germany" NR_COUNTRY_GH="Ghana" NR_COUNTRY_GI="Gibraltar" NR_COUNTRY_GR="Greece" NR_COUNTRY_GL="Greenland" NR_COUNTRY_GD="Grenada" NR_COUNTRY_GP="Guadeloupe" NR_COUNTRY_GU="Guam" NR_COUNTRY_GT="Guatemala" NR_COUNTRY_GG="Guernsey" NR_COUNTRY_GN="Guinea" NR_COUNTRY_GW="Guinea-Bissau" NR_COUNTRY_GY="Guyana" NR_COUNTRY_HT="Haiti" NR_COUNTRY_HM="Heard Island and McDonald Islands" NR_COUNTRY_VA="Holy See (Vatican City State)" NR_COUNTRY_HN="Honduras" NR_COUNTRY_HK="Hong Kong" NR_COUNTRY_HU="Hungary" NR_COUNTRY_IS="Iceland" NR_COUNTRY_IN="India" NR_COUNTRY_ID="Indonesia" NR_COUNTRY_IR="Iran, Islamic Republic of" NR_COUNTRY_IQ="Iraq" NR_COUNTRY_IE="Ireland" NR_COUNTRY_IM="Isle of Man" NR_COUNTRY_IL="Israel" NR_COUNTRY_IT="Italy" NR_COUNTRY_JM="Jamaica" NR_COUNTRY_JP="Japan" NR_COUNTRY_JE="Jersey" NR_COUNTRY_JO="Jordan" NR_COUNTRY_KZ="Kazakhstan" NR_COUNTRY_KE="Kenya" NR_COUNTRY_KI="Kiribati" NR_COUNTRY_KP="Korea, Democratic People's Republic of" NR_COUNTRY_KR="Korea, Republic of" NR_COUNTRY_KW="Kuwait" NR_COUNTRY_KG="Kyrgyzstan" NR_COUNTRY_LA="Lao People's Democratic Republic" NR_COUNTRY_LV="Latvia" NR_COUNTRY_LB="Lebanon" NR_COUNTRY_LS="Lesotho" NR_COUNTRY_LR="Liberia" NR_COUNTRY_LY="Libyan Arab Jamahiriya" NR_COUNTRY_LI="Liechtenstein" NR_COUNTRY_LT="Lithuania" NR_COUNTRY_LU="Luxembourg" NR_COUNTRY_MO="Macao" NR_COUNTRY_MK="Macedonia" NR_COUNTRY_MG="Madagascar" NR_COUNTRY_MW="Malawi" NR_COUNTRY_MY="Malaysia" NR_COUNTRY_MV="Maldives" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Malta" NR_COUNTRY_MH="Marshall Islands" NR_COUNTRY_MQ="Martinique" NR_COUNTRY_MR="Mauritania" NR_COUNTRY_MU="Mauritius" NR_COUNTRY_YT="Mayotte" NR_COUNTRY_MX="Mexico" NR_COUNTRY_FM="Micronesia, Federated States of" NR_COUNTRY_MD="Moldova, Republic of" NR_COUNTRY_MC="Monaco" NR_COUNTRY_MN="Mongolia" NR_COUNTRY_ME="Montenegro" NR_COUNTRY_MS="Montserrat" NR_COUNTRY_MA="Morocco" NR_COUNTRY_MZ="Mozambique" NR_COUNTRY_MM="Myanmar" NR_COUNTRY_NA="Namibia" NR_COUNTRY_NR="Nauru" NR_COUNTRY_NM="North Macedonia" NR_COUNTRY_NP="Nepal" NR_COUNTRY_NL="Netherlands" NR_COUNTRY_AN="Netherlands Antilles" NR_COUNTRY_NC="New Caledonia" NR_COUNTRY_NZ="New Zealand" NR_COUNTRY_NI="Nicaragua" NR_COUNTRY_NE="Niger" NR_COUNTRY_NG="Nigeria" NR_COUNTRY_NU="Niue" NR_COUNTRY_NF="Norfolk Island" NR_COUNTRY_MP="Northern Mariana Islands" NR_COUNTRY_NO="Norway" NR_COUNTRY_OM="Oman" NR_COUNTRY_PK="Pakistan" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Palestinian Territory" NR_COUNTRY_PA="Panama" NR_COUNTRY_PG="Papua New Guinea" NR_COUNTRY_PY="Paraguay" NR_COUNTRY_PE="Peru" NR_COUNTRY_PH="Philippines" NR_COUNTRY_PN="Pitcairn" NR_COUNTRY_PL="Poland" NR_COUNTRY_PT="Portugal" NR_COUNTRY_PR="Puerto Rico" NR_COUNTRY_QA="Qatar" NR_COUNTRY_RE="Reunion" NR_COUNTRY_RO="Romania" NR_COUNTRY_RU="Russian Federation" NR_COUNTRY_RW="Rwanda" NR_COUNTRY_SH="Saint Helena" NR_COUNTRY_KN="Saint Kitts and Nevis" NR_COUNTRY_LC="Saint Lucia" NR_COUNTRY_PM="Saint Pierre and Miquelon" NR_COUNTRY_VC="Saint Vincent and the Grenadines" NR_COUNTRY_WS="Samoa" NR_COUNTRY_SM="San Marino" NR_COUNTRY_ST="Sao Tome and Principe" NR_COUNTRY_SA="Saudi Arabia" NR_COUNTRY_SN="Senegal" NR_COUNTRY_RS="Serbia" NR_COUNTRY_SC="Seychelles" NR_COUNTRY_SL="Sierra Leone" NR_COUNTRY_SG="Singapore" NR_COUNTRY_SK="Slovakia" NR_COUNTRY_SI="Slovenia" NR_COUNTRY_SB="Solomon Islands" NR_COUNTRY_SO="Somalia" NR_COUNTRY_ZA="South Africa" NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" NR_COUNTRY_ES="Spain" NR_COUNTRY_LK="Sri Lanka" NR_COUNTRY_SD="Sudan" NR_COUNTRY_SS="South Sudan" NR_COUNTRY_SR="Suriname" NR_COUNTRY_SJ="Svalbard and Jan Mayen" NR_COUNTRY_SZ="Swaziland" NR_COUNTRY_SE="Sweden" NR_COUNTRY_CH="Switzerland" NR_COUNTRY_SY="Syrian Arab Republic" NR_COUNTRY_TW="Taiwan" NR_COUNTRY_TJ="Tajikistan" NR_COUNTRY_TZ="Tanzania, United Republic of" NR_COUNTRY_TH="Thailand" NR_COUNTRY_TL="Timor-Leste" NR_COUNTRY_TG="Togo" NR_COUNTRY_TK="Tokelau" NR_COUNTRY_TO="Tonga" NR_COUNTRY_TT="Trinidad and Tobago" NR_COUNTRY_TN="Tunisia" NR_COUNTRY_TR="Turkey" NR_COUNTRY_TM="Turkmenistan" NR_COUNTRY_TC="Turks and Caicos Islands" NR_COUNTRY_TV="Tuvalu" NR_COUNTRY_UG="Uganda" NR_COUNTRY_UA="Ukraine" NR_COUNTRY_AE="United Arab Emirates" NR_COUNTRY_GB="United Kingdom" NR_COUNTRY_US="United States" NR_COUNTRY_UM="United States Minor Outlying Islands" NR_COUNTRY_UY="Uruguay" NR_COUNTRY_UZ="Uzbekistan" NR_COUNTRY_VU="Vanuatu" NR_COUNTRY_VE="Venezuela" NR_COUNTRY_VN="Vietnam" NR_COUNTRY_VG="Virgin Islands, British" NR_COUNTRY_VI="Virgin Islands, U.S." NR_COUNTRY_WF="Wallis and Futuna" NR_COUNTRY_EH="Western Sahara" NR_COUNTRY_YE="Yemen" NR_COUNTRY_ZM="Zambia" NR_COUNTRY_ZW="Zimbabwe" NR_CONTINENT_AF="Africa" NR_CONTINENT_AS="Asia" NR_CONTINENT_EU="Europe" NR_CONTINENT_NA="North America" NR_CONTINENT_SA="South America" NR_CONTINENT_OC="Oceania" NR_CONTINENT_AN="Antarctica" NR_FRONTEND="Front-end" NR_BACKEND="Back-end" NR_EMBED="Embed" NR_RATE="Rate %s" NR_REPORT_ISSUE="Report an issue" NR_RESPONSIVE_CONTROL_TITLE="Set value per device" NR_TAG_PAGEGENERATOR="Page Generator" NR_TAG_PAGELANGURL="Page Language URL" NR_TAG_PAGEKEYWORDS="Page Keywords" NR_TAG_SITEEMAIL="Site Email" NR_TAG_DAY="Day" NR_TAG_MONTH="Month" NR_TAG_YEAR="Year" NR_TAG_USERREGISTERDATE="Register Date" NR_TAG_PAGEBROWSERTITLE="Browser Title" NR_TAG_EBID="Box ID" NR_TAG_EBTITLE="Box Title" NR_TAG_QUERYSTRINGOPTION="Query String : Option" NR_TAG_QUERYSTRINGVIEW="Query String : View" NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" NR_TAG_QUERYSTRINGTMPL="Query String : Template" NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" NR_CANNOT_MOVE_FILE="Can't move file: %s" NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" NR_OSM_COORDINATES_LABEL="Coordinates" NR_OSM_ADDRESS_DESC="Enter an address or coordinates to search" NR_CLEAR="Clear" NR_OSM_CLEAR_BUTTON_TITLE="Clears the map" NR_OSM_TOOLTIP_LABEL="Tooltip Label" NR_OSM_TOOLTIP_LABEL_HINT="Set tooltip label" NR_START_OVER="Start over" NR_TRY_AGAIN="Try again" NR_ERROR="Error" NR_CANCEL="Cancel" NR_PLEASE_WAIT="Please wait" NR_STAR="star%s" NR_HCAPTCHA="hCaptcha" NR_TYPE="Type" NR_CHECKBOX="Checkbox" NR_INVISIBLE="Invisible" NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." NR_GENERAL="General" NR_GALLERY_MANAGER_BROWSE="Browse" NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" NR_GALLERY_MANAGER_CAPTION_HINT="Enter a caption" NR_GALLERY_MANAGER_REACHED_FILES_LIMIT="You have reached your uploaded files limit." NR_GALLERY_MANAGER_FIELD_ID_ERROR="Cannot handle request, invalid field." NR_GALLERY_MANAGER_INVALID_FIELD_DATA="Cannot handle request, invalid field data." NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" NR_GALLERY_MANAGER_IN_QUEUE="In Queue" NR_GALLERY_MANAGER_UPLOADING="Uploading..." NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" NR_GALLERY_MANAGER_REGENERATE_THUMBNAILS="Regenerate thumbnails" NR_GALLERY_MANAGER_CONFIRM_REGENERATE_THUMBNAILS="Are you sure you want to regenerate the thumbnails?" NR_GALLERY_MANAGER_THUMBS_REGENERATED="Thumbnails regenerated!" NR_TECHNOLOGY="Technology" NR_ENGAGEBOX_SELECT_BOX="Select boxes" NR_CONTENT_ARTICLE="Content Article" NR_CONTENT_CATEGORY="Content Category" NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" NR_K2_ITEM="K2 - Item" NR_K2_CATEGORY="K2 - Category" NR_K2_TAG="K2 - Tag" NR_K2_PAGE_TYPE="K2 - Page Type" NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" NR_CB_SELECT_CONDITION="Select Condition" NR_CB_ADD_CONDITION_GROUP="New Condition Set" NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." NR_CB_TRASH_CONDITION="Trash Condition" NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" NR_CB_ADD_CONDITION="Add Condition" NR_CB_SHOW_WHEN="Display when" NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" NR_IS="Is" NR_IS_NOT="Is not" NR_IS_EMPTY="Is empty" NR_IS_NOT_EMPTY="Is not empty" NR_IS_BETWEEN="Is between" NR_IS_NOT_BETWEEN="Is not between" NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." NR_GEO_MAINTENANCE="Geolocation Database Maintenance" NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." NR_EDIT="Edit" NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s"System - Tassos.gr GeoIP Plugin"%s to be able to use the geolocation services." NR_INVALID_IMAGE_PATH="Invalid image path: %s" NR_UPLOAD_SETTINGS="Upload Settings" NR_SELECTED_ITEMS="Selected items" NR_CLEAR_SELECTED_ITEMS="Clear selected items" NR_ENTER_VALUE="Enter value" NR_SELECT_OPTION="Select Option" NR_CONTINUE="Continue" NR_TRASH="Trash"PK![[„Fsystem/nrframework/language/en-GB/en-GB.plg_system_nrframework.sys.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - used by Tassos.gr extensions" NOVARAIN_FRAMEWORK="Novarain Framework"PK!:fῠBsystem/nrframework/language/pt-PT/pt-PT.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Sistema - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - usado pelas extensões Tassos.gr" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignorar" NR_INCLUDE="Incluir" NR_EXCLUDE="Excluir" NR_SELECTION="Seleção" NR_ASSIGN_MENU_NOITEM="Incluir Sem Itemid" NR_ASSIGN_MENU_NOITEM_DESC="Também atribuir quando nenhum Itemid do menu for definido na URL?" NR_ASSIGN_MENU_CHILD="Também em items dependentes" NR_ASSIGN_MENU_CHILD_DESC="Atribuir também itens dependentes de itens selecionados?" NR_COPY_OF="Copiar de %s" NR_ASSIGN_DATETIME_DESC="Segmentar visitantes com base na data e hora do seu servidor" NR_DATETIME="Data/Hora" NR_TIME="Tempo" NR_DATE="Data" NR_DATETIME_DESC="Digite a data e hora para publicar/despublicar." NR_START_PUBLISHING="Iniciar data e hora" NR_START_PUBLISHING_DESC="Digite a data para iniciar a publicação." ; NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="Digite a data para finalizar a publicação." NR_DATETIME_NOTE="As atribuições de data e hora usa a data/hora de seus servidores, não do sistema dos visitantes." ; NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP Code" NR_ASSIGN_PHP_DESC="Digite um pedaço de código PHP para avaliar." NR_ASSIGN_PHP_DESC2="Segmentar visitantes avaliando o código PHP personalizado. o código deve retornar o valor true ou false.

Por exemplo:
Retorna ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Tempo no site" NR_SECONDS="Segundos" NR_ASSIGN_TIMEONSITE_DESC="Digite uma duração em segundos para comparar com a hora total do utilizador (duração da visita) gasto em todo o seu site.

Exemplo:
Se você deseja exibir uma caixa após o utilizador tiver gasto 3 minutos no seu site inteiro, digite 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Segmentar visitantes que estão a navegar em URLs específicos" NR_ASSIGN_URLS_DESC="Digite (parte da) a URLs para corresponder.
Use uma nova linha para cada correspondência diferente." NR_ASSIGN_URLS_LIST="Correspondência de URL" NR_ASSIGN_URLS_REGEX="Use a Expressão Regular" NR_ASSIGN_URLS_REGEX_DESC="Selecione para tratar o valor como expressões regulares." NR_ASSIGN_LANGS="Língua" NR_ASSIGN_LANGS_DESC="Segmente os visitantes que estão navegando em seu website em um idioma específico" NR_ASSIGN_LANGS_LIST_DESC="Selecione o Idioma para atribuir." NR_ASSIGN_DEVICES="Dispositivo" NR_ASSIGN_DEVICES_DESC2="Segmentar visitantes usando um dispositivo específico, como Mobile, Tablet or Desktop." NR_ASSIGN_DEVICES_DESC="Selecione os dispositivos para atribuir." NR_ASSIGN_DEVICES_NOTE="Tenha em mente que a detecção de dispositivos nem sempre é 100% precisa. Os usuários podem configurar seu navegador para imitar outros dispositivos." ; NR_MENU="Menu" NR_MENU_ITEMS="Item do Menu" NR_MENU_ITEMS_DESC="Segmentar visitantes que estão a navegar em itens de menu específicos" ; NR_USERGROUP="User Group" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Grupo de Utilizadores" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Exibir Copyright" NR_SHOW_COPYRIGHT_DESC="Se selecionado, informações extras sobre direitos autorais serão exibidas nas visualizações do admin. As extensões Tassos.gr nunca exibe as informações de copyright ou links de retorno no frontend." NR_WIDTH="Largura" NR_WIDTH_DESC="Digite a largura em px, em ou %

Exemplo: 400px" NR_HEIGHT="Altura" NR_HEIGHT_DESC="Digite a altura em px, em or %

Exemplo: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Digite o padding em px, em ou %

Exemplo: 20px" NR_MARGIN="Margem" NR_MARGIN_DESC="A propriedade de margem CSS é usada para gerar espaço ao redor da caixa e definir o tamanho do espaço em branco fora da borda em pixels ou em %.

Exemplo 1: 25px
Exemplo 2: 5%

Especificando a margem para cada lado [parte superior direita inferior esquerda]:

Apenas Lado Superior: 25px 0 0 0
Apenas Lado Direito: 0 25px 0 0
Apenas Lado inferior: 0 0 25px 0
A+enas Lado Esquerdo: 0 0 0 25px" NR_COLOR_HOVER="Cor do Hover (rato em cima)" NR_COLOR="Cor" NR_COLOR_DESC="Defina uma cor no formato HEX ou RGBA." NR_TEXT_COLOR="Cor do Texto" NR_BACKGROUND="Fundo" NR_BACKGROUND_COLOR="Cor de Fundo" NR_BACKGROUND_COLOR_DESC="Defina uma cor de fundo em formato HEX ou RGBA. Para desativar digite 'none'. Para transper~encia absoluta digite 'transparent'." NR_URL_SHORTENING_FAILED="Shortening %s com %s falhou. %s." NR_EXPORT="Exportar" NR_IMPORT="Importar" NR_PLEASE_CHOOSE_A_VALID_FILE="Por favor, escolha um nome de arquivo válido." NR_IMPORT_ITEMS="Importar Itens" NR_PUBLISH_ITEMS="Publicar Itens" NR_AS_EXPORTED="Como exportado" NR_TITLE="Titulo" NR_ACYMAILING="AcyMailing" ; NR_ACYMAILING_LIST="AcyMailing List" NR_ACYMAILING_LIST_DESC="Selecione as listas de AcyMailing a atribuir." NR_ASSIGN_ACYMAILING_DESC="Segmentar visitantes que se inscreveram em listas específicas do AcyMailing" NR_AKEEBASUBS="Akeeba Subscriptions" NR_AKEEBASUBS_LEVELS="Níveis" NR_AKEEBASUBS_LEVELS_DESC="Selecione niveis da Subscrição do Akeeba a atribuir." NR_ASSIGN_AKEEBASUBS_DESC="Segmentar visitantes inscritos em Assinaturas Akeeba específicas" NR_MATCH="Corresponder-Combinar" NR_MATCH_DESC="o usado método de comparação para comparar o valor" NR_ASSIGN_MATCHING_METHOD="Método de Correspondência" NR_ASSIGN_MATCHING_METHOD_DESC="Todas as atribuições devem ser correspondidas?

Todas
será publicada se Todas as atribuições abaixo são correspondentes.

Qualquer
será publicada se Qualquer (uma ou mais) das atribuições abaixo são correspondentes.
Grupos de atribuição onde 'Ignorar' está selecionado será ignorado." NR_ANY="Qualquer" ; NR_ALL="All" NR_ASSIGN_REFERRER="URL do referenciador" NR_ASSIGN_REFERRER_DESC2="Segmentar visitantes que chegam ao seu site de uma fonte de tráfego específica" NR_ASSIGN_REFERRER_DESC="Insira um URL de referenciador por linha: Eg:

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Tenha em mente que a descoberta do referenciador de URL nem sempre é 100% precisa. Alguns servidores podem usar proxies que retiram essas informações e podem ser facilmente falsificadas." ; NR_PROFEATURE_HEADER="%s is a PRO Feature" ; NR_PROFEATURE_DESC="We're sorry, %s is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features." ; NR_PROFEATURE_DISCOUNT="Bonus: %s free users get 20% off regular price, automatically applied at checkout." NR_ONLY_AVAILABLE_IN_PRO="Apenas disponível na versão PRO" NR_UPGRADE_TO_PRO="Atualizar para Pro" NR_UPGRADE_TO_PRO_TO_UNLOCK="Atualizar para versão Pro para desbloquear" ; NR_UPGRADE_TO_PRO_VERSION="Awesome! Only one step left. Click on the button below to complete the upgrade to the Pro version." ; NR_UNLOCK_PRO_FEATURE="Unlock Pro Feature" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="Esquerda para Direita" NR_RIGHT_TO_LEFT="Direita para Esquerda" NR_BGIMAGE="Imagem de Fundo" NR_BGIMAGE_DESC="Defina a imagem de fundo." NR_BGIMAGE_FILE="Imagem" NR_BGIMAGE_FILE_DESC="Selecione ou carregue um arquivo para o background-image." NR_BGIMAGE_REPEAT="Repetir" NR_BGIMAGE_REPEAT_DESC="A propriedade background-repeat define se/como uma imagem de fundo será repetida. Por padrão, uma background-image é repetida vertical e horizontalmente.

Repeat: A imagem de fundo será repetida tanto na vertical como na horizontal.

Repeat-x: A imagem de fundo será repetida apenas horizontalmente

Repeat-y: A imagem de fundo será repetida apenas verticalmente

No-repeat: A imagem de fundo não será repetida." NR_BGIMAGE_SIZE="Tamanho" NR_BGIMAGE_SIZE_DESC="Especifique o tamanho de uma imagem de fundo.

Auto: A background-image contém a sua largura e altura

Cover: Dimensiona a imagem de fundo para ser o maior possível para que a área de fundo seja completamente coberta pela imagem de fundo. Algumas partes da imagem de fundo podem não estar visíveis dentro da área de posicionamento de fundo

Contain: Dimensiona a imagem para o tamanho maior, de forma que a largura e a altura possam se ajustar dentro da área de conteúdo

100% 100%: Estique a imagem de plano de fundo para cobrir completamente a área de conteúdo." NR_BGIMAGE_POSITION="Posição" NR_BGIMAGE_POSITION_DESC="A propriedade background-position define a posição inicial de uma imagem de fundo. Por padrão, uma background-image é colocada no canto superior esquerdo. O primeiro valor é a posição horizontal e o segundo valor é a posição vertical.

Você pode usar um dos valores predefinidos ou inserir um valor personalizado em porcentagem: x% y% ou em pixel xPos yPos." NR_RTL="Ativar RTL" NR_RTL_DESC="A direção do texto da direita para a esquerda é essencial para scripts da direita para a esquerda, como Árabe, Hebraico, Siríaco e Thaana." NR_HORIZONTAL="Horizontal" NR_VERTICAL="Vertical" NR_FORM_ORIENTATION="Orientação do Formulário" NR_FORM_ORIENTATION_DESC="Selecione a orientação do formulário." NR_ASSIGN_CATEGORY="Categorias" NR_ASSIGN_CATEGORY_DESC="Selecione as categorias para atribuir." NR_ASSIGN_CATEGORY_CHILD="Também em Itens Filhos" NR_ASSIGN_CATEGORY_CHILD_DESC="Também atribuir para itens filhos dos itens selecionados?" NR_NEW="Novo" NR_LIST="Lista" NR_DOCUMENTATION="Documentação" NR_KNOWLEDGEBASE="Base de Conhecimento" NR_FAQ="FAQ" NR_INFORMATION="Informação" NR_EXTENSION="Extensão" NR_VERSION="Versão" NR_CHANGELOG="Changelog" ; NR_DOWNLOAD="Download" ; NR_DOWNLOAD_KEY_MISSING="Download Key is missing" NR_DOWNLOAD_KEY="Chave de Download" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="Para ser capaz de atualizar %s via o atualizador do Joomla, você precisará digitar sua Chave de Download nas configurações do Plugin Novarain Framework." NR_DOWNLOAD_KEY_FIND="Encontrar a Chave de Download" NR_DOWNLOAD_KEY_UPDATE="Atualizar Chave de Download" NR_OK="OK" NR_MISSING="Faltando" NR_LICENSE="Licença" NR_AUTHOR="Autor" NR_FOLLOWME="Siga-me" NR_FOLLOW="Siga %s" NR_TRANSLATE_INTEREST="Você estaria interessado em ajudar com a tradução do %s para o seu Idioma?" NR_TRANSIFEX_REQUEST="Envie-me um pedido no Transifex" NR_HELP_WITH_TRANSLATIONS="Ajuda com Traduções" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Avançado" NR_USEGLOBAL="Usar Global" ; NR_WEEKDAY="Day of Week" ; NR_MONTH="Month" ; NR_MONDAY="Monday" ; NR_TUESDAY="Tuesday" ; NR_WEDNESDAY="Wednesday" ; NR_THURSDAY="Thursday" ; NR_FRIDAY="Friday" ; NR_SATURDAY="Saturday" ; NR_WEEKEND="Weekend" ; NR_WEEKDAYS="Weekdays" ; NR_SUNDAY="Sunday" ; NR_JANUARY="January" ; NR_FEBRUARY="February" ; NR_MARCH="March" ; NR_APRIL="April" ; NR_MAY="May" ; NR_JUNE="June" ; NR_JULY="July" ; NR_AUGUST="August" ; NR_SEPTEMBER="September" ; NR_OCTOBER="October" ; NR_NOVEMBER="November" ; NR_DECEMBER="December" NR_NEVER="Nunca" NR_SECONDS="Segundos" NR_MINUTES="Minutos" NR_HOURS="Horas" NR_DAYS="Dias" NR_SESSION="Sessão" NR_EVER="Sempre" NR_COOKIE="Cookie" NR_BOTH="Ambos" NR_NONE="Nenhum" ; NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Desktop" NR_MOBILES="Mobile" NR_TABLETS="Tablet" NR_PER_SESSION="Por Sessão" NR_PER_DAY="Por Dia" NR_PER_WEEK="Por Semana" NR_PER_MONTH="Por Mês" NR_FOREVER="Para Sempre" NR_FEATURE_UNDER_DEV="Este recurso está em desenvolvimento" NR_LIKE_THIS_EXTENSION="Curtir esta extensão?" NR_LEAVE_A_REVIEW="Deixe um comentário no JED" ; NR_SUPPORT="Support" NR_NEED_SUPPORT="Precisa de suporte?" NR_DROP_EMAIL="Me envie um e-mail" NR_READ_DOCUMENTATION="Ler a Documentação" NR_COPYRIGHT="%s - Tassos.gr Todos os Direitos Reservados" NR_DASHBOARD="Painel" NR_NAME="Nome" NR_WRONG_COORDINATES="As coordenadas que você forneceu não são válidas!" NR_ENTER_COORDINATES="Latitude, Longitude" NR_NO_ITEMS_FOUND="Nenhum Item Foi Encontrado!" NR_ITEM_IDS="Nenhum IDs de Item" NR_TOGGLE="Alternar" NR_EXPAND="Expandir" NR_COLLAPSE="Recolher" NR_SELECTED="Selecionado" NR_MAXIMIZE="Maximizar" NR_MINIMIZE="Minimizar" NR_SELECTION="Seleção" NR_INSTALL="Instalar" NR_INSTALL_NOW="Instalar Agora" NR_INSTALLED="Instalado" NR_COMING_SOON="Em breve" ; NR_ROADMAP="On the roadmap" NR_MEDIA_VERSIONING="Usar Versão de Mídia" NR_MEDIA_VERSIONING_DESC="Selecione para adicionar o número da versão da extensão ao final da urls de mídia (js/css), para fazer os navegadores forçar o carregamento do arquivo correto." NR_LOAD_JQUERY="Carregar jQuery" NR_LOAD_JQUERY_DESC="Selecione para carregar o script do core do jQuery. Você pode desativar isso se você tiver conflitos se seu template ou outras extensões carregarem sua própria versão do jQuery." NR_SELECT_CURRENCY="Selecionar a Moeda" ; NR_CONVERTFORMS="Convert Forms" ; NR_CONVERTFORMS_LIST="Campaign" NR_ASSIGN_CONVERTFORMS_DESC="Segmentar visitantes que se inscreveram em campanhas específicas do ConvertForms" NR_CONVERTFORMS_LIST_DESC="Selecione campanhas ConvertForms para atribuir a." NR_LEFT="Esquerda" NR_CENTER="Centro" NR_RIGHT="Direita" NR_BOTTOM="Rodapé" NR_TOP="Topo" NR_AUTO="Auto" NR_CUSTOM="Personalizar" NR_UPLOAD="Carregar" NR_IMAGE="Imagem" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" NR_IMAGE_SELECT="Selecionar Imagem" NR_IMAGE_SIZE_COVER="Capa" NR_IMAGE_SIZE_CONTAIN="Contém" NR_REPEAT="Repetir" NR_REPEAT_X="Repetir x" NR_REPEAT_Y="Repetir y" NR_REPEAT_NO="Não repetir" NR_FIELD_STATE_DESC="Defina o estado do item." NR_CREATED_DATE="Data de Criação" NR_CREATED_DATE_DESC="A data em que o item foi criado." NR_MODIFIFED_DATE="Data de Modificação" NR_MODIFIFED_DATE_DESC="A data que o item foi modificado pela última vez." NR_CATEGORIES="Categorias" NR_CATEGORIES_DESC="Selecione as categorias para o trabalho." NR_ALSO_ON_CHILD_ITEMS="Também nos itens do tema pendente" NR_ALSO_ON_CHILD_ITEMS_DESC="Também atribuir os itens selecionados aos itens pendentes?" NR_PAGE_TYPE="Tipo de Página" NR_PAGE_TYPES="Tipos de páginas" NR_PAGE_TYPES_DESC="Selecione quais os tipos de páginas que serão ativados no trabalho." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" ; NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" ; NR_CATEGORY_VIEW="Category View" ; NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Artigos" NR_ARTICLES_DESC="Selecione os artigos designados" NR_ARTICLE="Artigo" NR_ARTICLE_AUTHORS="Autor" NR_ARTICLE_AUTHORS_DESC="Escolha o autor designado" NR_ONLY="Somente" NR_OTHERS="outros" NR_SMARTTAGS="Smart Tags" NR_SMARTTAGS_SHOW="Mostrar Smart Tags" ; NR_SMARTTAGS_NOTFOUND="No Smart Tags found" ; NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" NR_CONTACT_US="Entre em contato conosco." NR_FONT_COLOR="Seleção de cor" NR_FONT_SIZE="Seleção do tamanho da fonte" NR_FONT_SIZE_DESC="Escolha o tamanho da fonte em Pixel" NR_TEXT="Texto" NR_URL="Endereço da Web" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Ativar na saída Override" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Permite o processamento de extensão quando o layout da página (tmpl) éoverriden. Exemplos: tmpl=component or tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Ativar na Substituição de Formato" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Permite renderização de extensão quando o formato de página não é diferente de HTML. Exemplos: format=raw or format=json." NR_GEOLOCATING="Geolocalização" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="A localização geográfica nem sempre é 100% precisa. o geolocalização é baseada no endereço IP do visitante. Nem todos os endereços IP são fixos ou conhecidos." ; NR_CITY="City" ; NR_CITY_NAME="City Name" ; NR_CONDITION_CITY_DESC="Enter a city name in English. Enter multiple cities separated by comma." ; NR_CONTINENT="Continent" ; NR_REGION="Region" ; NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." NR_ASSIGN_COUNTRIES="País" NR_ASSIGN_COUNTRIES_DESC2="Segmentar visitantes que estão fisicamente num país específico" NR_ASSIGN_COUNTRIES_DESC="Selecione os paíse a atribuir" NR_ASSIGN_CONTINENTS="Continente" NR_ASSIGN_CONTINENTS_DESC="Selecione os continentes a atribuir" NR_ASSIGN_CONTINENTS_DESC2="Segmentar visitantes que estão fisicamente num continente específico" NR_ICONTACT_ACCOUNTID_ERROR="O iContact AccountID não pôde ser recuperado" ; NR_TAG_CLIENTDEVICE="Visitor Device Type" ; NR_TAG_CLIENTOS="Visitor Operating System" ; NR_TAG_CLIENTBROWSER="Visitor Browser" ; NR_TAG_CLIENTUSERAGENT="Visitor Agent String" ; NR_TAG_IP="Visitor IP Address" ; NR_TAG_URL="Page URL" ; NR_TAG_URLENCODED="Page URL Encoded" ; NR_TAG_URLPATH="Page Path" ; NR_TAG_REFERRER="Page Referrer" ; NR_TAG_SITENAME="Site Name" ; NR_TAG_SITEURL="Site URL" ; NR_TAG_PAGETITLE="Page Title" ; NR_TAG_PAGEDESC="Page Meta Description" ; NR_TAG_PAGELANG="Page Language Code" NR_TAG_USERID="ID do Utilizador" NR_TAG_USERNAME="Nome Completo do Utilizador" NR_TAG_USERLOGIN="Login do Utilizador" NR_TAG_USEREMAIL="Email do Utilizador" NR_TAG_USERFIRSTNAME="Primeiro Nome do utilizador" NR_TAG_USERLASTNAME="Ultimo Nome do utilizador" ; NR_TAG_USERGROUPS="User Groups IDs" ; NR_TAG_DATE="Date" ; NR_TAG_TIME="Time" ; NR_TAG_RANDOMID="Random ID" NR_ICON="Icon\"NR_SELECT_MODULE=\"Selecione o Modulo" ; NR_SELECT_MODULE="Select a Module" NR_SELECT_CONTINENT="Selecione o Continente" NR_SELECT_COUNTRY="Selecione o País" NR_PLUGIN="Plugin" NR_GMAP_KEY="Google Maps API Key" NR_GMAP_KEY_DESC="A chave API do Google Maps está a ser usada pelas extensões Tassos.gr. Se enfrentar algum problema com o Google Map não sendo carregado, provavelmente precisará inserir sua própria chave de API." NR_GMAP_FIND_KEY="Obter uma chave de API" NR_ARE_YOU_SURE="Tem a certeza?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="URL Personalizado" NR_SAMPLE="Exemplo" NR_DEBUG="Depurar" NR_CUSTOMURL="URL Personalizado" NR_READMORE="Ler Mais" NR_IPADDRESS="https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Chave do Site" NR_RECAPTCHA_SITE_KEY_DESC="Usado no código JavaScript que é servido para seus usuários." NR_RECAPTCHA_SECRET_KEY="Chave secreta" NR_RECAPTCHA_SECRET_KEY_DESC="Usado em comunicação entre o servidor e o servidor reCAPTCHA. Certifique-se de manter isso em segredo." NR_RECAPTCHA_SITE_KEY_ERROR="o reCaptcha Chave do Site está ausente ou é inválida" NR_PREVIOUS_MONTH="Mês Anterior" NR_NEXT_MONTH="Próximo Mês" NR_ASSIGN_GROUP_PAGE_URL="Page / Endereço URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Segmentar visitantes que estão navegando por itens de menu ou URLs específicos" NR_ASSIGN_GROUP_DATETIME_DESC="Aciona uma caixa com base na data e hora do seu servidor" NR_ASSIGN_GROUP_USER_VISITOR="Utilizador Joomla / Visitante" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Segmente usuários registrados ou visitantes que visualizaram um determinado número de páginas" NR_ASSIGN_GROUP_PLATFORM="Plataforma do Visitante" NR_ASSIGN_GROUP_PLATFORM_DESC="Segmente os visitantes que estão usando o telemóvel, o Google Chrome ou até o Windows" NR_ASSIGN_GROUP_GEO_DESC="Segmentar visitantes que estão fisicamente em uma região específica" NR_ASSIGN_GROUP_JCONTENT="Conteúdo de Joomla!" NR_ASSIGN_GROUP_JCONTENT_DESC="Segmentar visitantes que estão visualizando artigos ou categorias específicas do Joomla" NR_ASSIGN_GROUP_SYSTEM="Sistema / Integrações" ; NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Segmentar visitantes que interagiram com extensões Específicas do Joomla 3rd party" NR_ASSIGN_GROUP_ADVANCED="Segmentação avançada por visitante" NR_ASSIGN_USERGROUP_DESC="Segmentar grupos de usuários específicos do Joomla" NR_ASSIGN_ARTICLE_DESC="Segmentar visitantes que estão visualizando artigos específicos do Joomla" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Segmentar visitantes que estão visualizando categorias específicos do Joomla" ; NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Segmentar visitantes que estão s navegar por itens, categorias ou tags específicos do K2" NR_ASSIGN_K2_ITEMS="Item" NR_ASSIGN_K2_ITEMS_DESC="Segmente os visitantes que navegam em itens específicos do K2." NR_ASSIGN_K2_ITEMS_LIST_DESC="Selecione o items do K2 a atribuir" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Corresponder palavras-chave específicas no conteúdo do item. Separado por uma vírgula ou por uma nova linha." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Corresponder palavras-chave meta de um item. Separado por uma vírgula ou uma nova linha." NR_ASSIGN_K2_PAGETYPES_DESC="Segmentar visitantes que estão navegando por tipos de página específicos do K2" NR_ASSIGN_K2_ITEM_OPTION="Item" NR_ASSIGN_K2_LATEST_OPTION="Últimos itens de utilizadores ou categorias" NR_ASSIGN_K2_TAG_OPTION="Tag Page" NR_ASSIGN_K2_CATEGORY_OPTION="Categoria da Página" NR_ASSIGN_K2_ITEM_FORM_OPTION="Formulário de edição de item" NR_ASSIGN_K2_USER_PAGE_OPTION="Página de utilizador(blog)" NR_ASSIGN_K2_TAGS_DESC="Segmentar visitantes que estão a navegar em itens do K2 com tags específicas" NR_ASSIGN_K2_CATEGORIES_DESC="Segmentar visitantes que estão a navegar em categorias específicas do K2" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categorias" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Artigos" NR_ASSIGN_PAGE_TYPES_DESC="Selecione os tipos de página para atribuir a" NR_ASSIGN_TAGS_DESC="Selecione as tags para atribuir a" NR_CONTENT_KEYWORDS="Palavras-chave de conteúdo" NR_META_KEYWORDS="Meta palavras-chave" NR_TAG="Tag" NR_NORMAL="Normal" NR_COMPACT="Compacto" NR_LIGHT="Claro" NR_DARK="Escuro" NR_SIZE="Tamanho" NR_THEME="Tema" NR_SINGLE="Simples" NR_MULTIPLE="Múltiplo" NR_RANGE="Alcance" NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_PLEASE_VALIDATE="Please validate" ; NR_RECAPTCHA_INVALID_SECRET_KEY="Invalid secret key" ; NR_PAGE="Page" ; NR_YOU_ARE_USING_EXTENSION="You are using %s %s" ; NR_UPDATE="Update" ; NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" ; NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." ; NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!7=9Bsystem/nrframework/language/sv-SE/sv-SE.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - används av Tassos.gr tillägg" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignorera" NR_INCLUDE="Inkludera" NR_EXCLUDE="Exkludera" NR_SELECTION="Urval" NR_ASSIGN_MENU_NOITEM="Inkludera inga itemID" NR_ASSIGN_MENU_NOITEM_DESC="Tilldela även när inget meny ItemID finns i URLen?" NR_ASSIGN_MENU_CHILD="Även på underliggande objekt" NR_ASSIGN_MENU_CHILD_DESC="Tilldela även underliggande objekt till de valda objekten?" NR_COPY_OF="Kopia av %s" NR_ASSIGN_DATETIME_DESC="Rikta till besökare baserat på din servers datum/tid" NR_DATETIME="Datum/Tid" NR_TIME="Tid" NR_DATE="Datum" NR_DATETIME_DESC="Ange datum/tid att auto publicera/avpublicera." NR_START_PUBLISHING="Start Datum/Tid" NR_START_PUBLISHING_DESC="Ange datum att starta publicering." NR_FINISH_PUBLISHING="Slut Datum/Tid" NR_FINISH_PUBLISHING_DESC="Ange datum att avsluta publicering." NR_DATETIME_NOTE="Tilldelning för datum och tid använder DIN SERVERS datum/tid, inte besökarnas system." NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP-kod" NR_ASSIGN_PHP_DESC="Ange PHP-kod att utvärdera." NR_ASSIGN_PHP_DESC2="Rikta till besökare genom att utvärdera anpassad PHP-kod. Koden måste returnera värdet true eller false.

Till exempel:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Tid på webbplatsen" NR_SECONDS="Sekunder" NR_ASSIGN_TIMEONSITE_DESC="Ange varaktighet i sekunder för att jämföra med användarens totala tid (besökslängd) på hela din webbplats .

Example:
Om du vill visa en ruta efter att användaren har vistats 3 minuter på hela webbplatsen, ange 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Rikta till besökare som surfar på specifika URLer." NR_ASSIGN_URLS_DESC="Ange (del av) URLer som ska matchas. Använd en ny rad för varje annan matchning." NR_ASSIGN_URLS_LIST="URL matchning" NR_ASSIGN_URLS_REGEX="Använd Regular Expressions" NR_ASSIGN_URLS_REGEX_DESC="Välj för att behandla värdet som regular expressions." NR_ASSIGN_LANGS="Språk" NR_ASSIGN_LANGS_DESC="Rikta till besökare som surfar på din webbplats med ett specifikt språk" NR_ASSIGN_LANGS_LIST_DESC="Välj de språk du vill tilldela" NR_ASSIGN_DEVICES="Enhet" NR_ASSIGN_DEVICES_DESC2="Rikta till besökare med en specifik enhet som mobil, surfplatta eller stationär dator." NR_ASSIGN_DEVICES_DESC="Välj de enheter du vill tilldela." NR_ASSIGN_DEVICES_NOTE="Tänk på att enhetsdetektering inte alltid är 100% korrekt. Användare kan ställa in sin webbläsare att efterlikna andra enheter" NR_MENU="Meny" NR_MENU_ITEMS="Menyobjekt" NR_MENU_ITEMS_DESC="Rikta till besökare som surfar till specifika menyalternativ" NR_USERGROUP="Användargrupp" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Användargrupp" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Visa Copyright" NR_SHOW_COPYRIGHT_DESC="Om valt, kommer extra copyrightinformation att visas i administratörsvyerna. Tassos.gr-tillägg visar aldrig copyrightinformation eller bakåtlänkar i frontend." NR_WIDTH="Bredd" NR_WIDTH_DESC="Ange bredd i px, em eller%

Exempel: 400px" NR_HEIGHT="Höjd" NR_HEIGHT_DESC="Ange höjd i px, em eller%

Exempel: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Ange padding i px, em eller%

Exempel: 20px" NR_MARGIN="Marginal" NR_MARGIN_DESC="CSS-marginal används för att skapa utrymme runt rutan och ställa in storleken på det vita utrymmet utanför ramen i pixlar eller i%.

Exempel 1: 25px
Exempel 2: 5%

Ange marginalen för varje sida [övre höger nedre vänster]:

Bara översidan: 25px 0 0 0
Bara höger sida: 0 25px 0 0
Bara nedre sidan: 0 0 25px 0
Bara vänster sida: 0 0 0 25px" NR_COLOR_HOVER="Hoverfärg" NR_COLOR="Färg" NR_COLOR_DESC="Definiera en färg i HEX- eller RGBA-format." NR_TEXT_COLOR="Textfärg" NR_BACKGROUND="Bakgrund" NR_BACKGROUND_COLOR="Bakgrundsfärg" NR_BACKGROUND_COLOR_DESC="Definiera en bakgrundsfärg i HEX- eller RGBA-format. För att inaktivera, ange 'none'. För absolut transparens anger du 'transparent'." NR_URL_SHORTENING_FAILED="Förkortning av %s med %s misslyckades. %s." NR_EXPORT="Exportera" NR_IMPORT="Importera" NR_PLEASE_CHOOSE_A_VALID_FILE="Välj ett giltigt filnamn." NR_IMPORT_ITEMS="Importera objekt" NR_PUBLISH_ITEMS="Publicera objekt" NR_AS_EXPORTED="Som exporterat" NR_TITLE="Titel" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="AcyMailing lista" NR_ACYMAILING_LIST_DESC="Välj AcyMailing listor att tilldelas.." NR_ASSIGN_ACYMAILING_DESC="Rikta till besökare som har prenumererat på specifika AcyMailing-listor." NR_AKEEBASUBS="Akeeba prenumerationer" NR_AKEEBASUBS_LEVELS="Nivåer" NR_AKEEBASUBS_LEVELS_DESC="Välj Akeeba-prenumerationsnivåer som du vill tilldela." NR_ASSIGN_AKEEBASUBS_DESC="Rikta till besökare som har prenumererat på specifika Akeeba-prenumerationsplaner" NR_MATCH="Matchning" NR_MATCH_DESC="Den använda matchningsmetoden för att jämföra värdet" NR_ASSIGN_MATCHING_METHOD="Matchningsmetod" NR_ASSIGN_MATCHING_METHOD_DESC="Ska alla eller några uppgifter matchas?

All
Kommer att publiceras om Alla nedanstående uppgifter matchar.

Någon
Kommer att publiceras om Någon (en eller fler) av nedanstående uppgifter matchar.
Uppgiftsgrupper där \"Ignorera\" är valt kommer att ignoreras." NR_ANY="Någon" ; NR_ALL="All" NR_ASSIGN_REFERRER="Hänvisande URL" NR_ASSIGN_REFERRER_DESC2="Rikta till besökare som kommer till din webbplats från en specifik trafikkälla" NR_ASSIGN_REFERRER_DESC="Ange en Hänvisande URL per rad: T.ex.

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Tänk på att URL-hänvisningsupptäckt inte alltid är 100% korrekt. Vissa servrar kan använda proxyservrar som tar bort denna information och den kan lätt förfalskas." NR_PROFEATURE_HEADER="%s är en PRO-funktion" NR_PROFEATURE_DESC="Tyvärr, %s är inte tillgänglig i din prenumerationsplan. Uppgradera till PRO-planen för att låsa upp alla dessa fantastiska funktioner." NR_PROFEATURE_DISCOUNT="Bonus: %s gratis-användare får 20% rabatt på ordinarie pris, tillämpas automatiskt i kassan." NR_ONLY_AVAILABLE_IN_PRO="Endast tillgänglig i PRO-versionen" NR_UPGRADE_TO_PRO="Uppgradera till PRO" NR_UPGRADE_TO_PRO_TO_UNLOCK="Uppgradera till Pro-versionen för att låsa upp den" NR_UPGRADE_TO_PRO_VERSION="Fantastiskt! Bara ett steg kvar. Klicka på knappen nedan för att slutföra uppgraderingen till Pro-versionen." NR_UNLOCK_PRO_FEATURE="Lås upp Pro-funktioner" NR_USING_THE_FREE_VERSION="Du använder GRATIS versionen av Convert Forms. Köp PRO-versionen för full funktionalitet." NR_LEFT_TO_RIGHT="Vänster till höger" NR_RIGHT_TO_LEFT="Höger till vänster" NR_BGIMAGE="Bakgrundsbild" NR_BGIMAGE_DESC="Ställer in en bakgrundsbild." NR_BGIMAGE_FILE="Bild" NR_BGIMAGE_FILE_DESC="Välj eller ladda upp en fil för bakgrundsbild." NR_BGIMAGE_REPEAT="Upprepa" NR_BGIMAGE_REPEAT_DESC="Egenskapen bakgrundsupprepning anger om / hur en bakgrundsbild ska upprepas. Som standard upprepas en bakgrundsbild både vertikalt och horisontellt.

Upprepa: Bakgrundsbilden upprepas både vertikalt och horisontellt.

Upprepa-x: Bakgrundsbilden upprepas endast horisontellt

Upprepa-y: Bakgrundsbilden upprepas endast vertikalt

Ingen upprepning: Bakgrundsbilden upprepas inte" NR_BGIMAGE_SIZE="Storlek" NR_BGIMAGE_SIZE_DESC="Ange bakgrundsbildens storlek.

Auto: Bakgrundsbilden innehåller dess bredd och höjd

Omslag: Skala bakgrundsbilden så stor som möjligt så att bakgrundsområdet täcks helt av bakgrundsbilden. Vissa delar av bakgrundsbilden kanske inte syns inom bakgrundsområdetVissa delar av bakgrundsbilden kanske inte syns inom bakgrundsområdet

Innehålll: Skala bilden till den största storleken så att både dess bredd och höjd kan passa in i innehållsområdet

100% 100%: Sträck ut bakgrundsbilden för att helt täcka innehållsområdet." NR_BGIMAGE_POSITION="Position" NR_BGIMAGE_POSITION_DESC="Egenskapen bakgrundsposition ställer in startpositionen för en bakgrundsbild. Som standard placeras en bakgrundsbild längst upp till vänster. Det första värdet är det horisontella läget och det andra värdet är det vertikala.

Du kan använda något av de fördefinierade värdena eller ange ett anpassat värde i procent: x% y% eller i pixel xPos yPos." NR_RTL="Aktivera RTL" NR_RTL_DESC="Textriktningen från höger till vänster är viktig för skrft från höger till vänster som arabiska, hebreiska, syriska och taana." NR_HORIZONTAL="Horisontell" NR_VERTICAL="Vertikal" NR_FORM_ORIENTATION="Formulär riktning" NR_FORM_ORIENTATION_DESC="Välj formulärets riktning." NR_ASSIGN_CATEGORY="Kategorier" NR_ASSIGN_CATEGORY_DESC="Välj kategorier att tilldela." NR_ASSIGN_CATEGORY_CHILD="Även underliggande objekt" NR_ASSIGN_CATEGORY_CHILD_DESC="Tilldela även underliggande objekt till de valda objekten?" NR_NEW="Ny" NR_LIST="Lista" NR_DOCUMENTATION="Dokumentation" NR_KNOWLEDGEBASE="Knowledgebase" NR_FAQ="FAQ" NR_INFORMATION="Information" NR_EXTENSION="Tillägg" NR_VERSION="Version" NR_CHANGELOG="Ändringslogg" NR_DOWNLOAD="Ladda ner" NR_DOWNLOAD_KEY_MISSING="Nedladdningsnyckel saknas" NR_DOWNLOAD_KEY="Nedladdningsnyckel" NR_DOWNLOAD_KEY_DESC="För att hitta din nedladdningsnyckel loggar du in på ditt konto på Tassos.gr och går till Downloads section.

Obs! Om du ställer in nedladdningsnyckeln här uppgraderas inte gratisversioner till Pro-versioner. För att låsa upp Pro-funktioner måste du också installera Pro-versionen över gratisversionen." NR_DOWNLOAD_KEY_HOW="För att kunna uppdatera %s via Joomla uppdatering, måste du ange din uppdateringsnyckel i Novarain Framework Plugins inställningar." NR_DOWNLOAD_KEY_FIND="Hitta nedladdningsnyckel" NR_DOWNLOAD_KEY_UPDATE="Uppdatera nedladdningsnyckel" NR_OK="Ok" NR_MISSING="Saknas" NR_LICENSE="Licens" NR_AUTHOR="Författare" NR_FOLLOWME="Följ mig" NR_FOLLOW="Följ" NR_TRANSLATE_INTEREST="Skulle du vara intresserad av att hjälpa till med översättningen av %s till ditt språk?" NR_TRANSIFEX_REQUEST="Skicka mig en förfrågan på Transifex" NR_HELP_WITH_TRANSLATIONS="Hjälp till med översättningar" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Avancerat" NR_USEGLOBAL="Använd Global" NR_WEEKDAY="Veckodag" NR_MONTH="Månad" NR_MONDAY="Måndag" NR_TUESDAY="Tisdag" NR_WEDNESDAY="Onsdag" NR_THURSDAY="Torsdag" NR_FRIDAY="Fredag" NR_SATURDAY="Lördag" NR_WEEKEND="Helg" NR_WEEKDAYS="Veckodagar" NR_SUNDAY="Söndag" NR_JANUARY="Januari" NR_FEBRUARY="Februari" NR_MARCH="Mars" NR_APRIL="April" NR_MAY="Maj" NR_JUNE="Juni" NR_JULY="Juli" NR_AUGUST="Augusti" NR_SEPTEMBER="September" NR_OCTOBER="Oktober" NR_NOVEMBER="November" NR_DECEMBER="December" NR_NEVER="Aldrig" NR_SECONDS="Sekunder" NR_MINUTES="Minuter" NR_HOURS="Timmar" NR_DAYS="Dagar" NR_SESSION="Session" NR_EVER="Välj de kategorier du vill tilldela." NR_COOKIE="Cookie" NR_BOTH="Båda" NR_NONE="Ingen" ; NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Dator" NR_MOBILES="Mobil" NR_TABLETS="Läsplatta" NR_PER_SESSION="Per Session" NR_PER_DAY="Per dag" NR_PER_WEEK="Per vecka" NR_PER_MONTH="Per månad" NR_FOREVER="Evig" NR_FEATURE_UNDER_DEV="Denna funktion är under utveckling." NR_LIKE_THIS_EXTENSION="Gillar du det här tillägget?" NR_LEAVE_A_REVIEW="Skriv en recension på JED" NR_SUPPORT="Support" NR_NEED_SUPPORT="Behöver du support?" NR_DROP_EMAIL="Skicka ett mail till mig" NR_READ_DOCUMENTATION="Läs dokumentationen" NR_COPYRIGHT="%s - Tassos.gr All Rights Reserved" NR_DASHBOARD="Kontrollpanel" NR_NAME="Namn" NR_WRONG_COORDINATES="koordinater du angav är ogiltiga." NR_ENTER_COORDINATES="Latitude,Longitud" NR_NO_ITEMS_FOUND="Hittade inga objekt" NR_ITEM_IDS="Det finns inga objekt-IDn" NR_TOGGLE="Växla" NR_EXPAND="Expandera" NR_COLLAPSE="Kollapsa" NR_SELECTED="Vald" NR_MAXIMIZE="Maximera" NR_MINIMIZE="Minimera" NR_SELECTION="Urval" NR_INSTALL="Installera" NR_INSTALL_NOW="Installera nu" NR_INSTALLED="Installerad" NR_COMING_SOON="Kommer snart" NR_ROADMAP="I utvecklingsplanen" NR_MEDIA_VERSIONING="Använd Media versionshantering" NR_MEDIA_VERSIONING_DESC="Välj för att lägga till tilläggets versionsnummer i slutet av media (js / css) -webbadresser, för att få webbläsare att tvinga in rätt fil." NR_LOAD_JQUERY="Ladda jQuery" NR_LOAD_JQUERY_DESC="Välj för att ladda kärnans jQuery script. Du kan inaktivera detta om du upplever konflikter om din mall eller andra tillägg laddar sin egen version av jQuery." NR_SELECT_CURRENCY="Välj en valuta" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Kampanj" NR_ASSIGN_CONVERTFORMS_DESC="Rikta till besökare som har prenumererat på specifika ConvertForms-kampanjer." NR_CONVERTFORMS_LIST_DESC="Välj ConvertForms-kampanjer att tilldela." NR_LEFT="Vänster" NR_CENTER="Centrera" NR_RIGHT="Höger" NR_BOTTOM="Nederkant" NR_TOP="Överkant" NR_AUTO="Auto" NR_CUSTOM="Anpassad" NR_UPLOAD="Ladda upp" NR_IMAGE="Bild" NR_INTRO_IMAGE="Ingressbild" NR_FULL_IMAGE="Fullstor bild" NR_IMAGE_SELECT="Välj bild" NR_IMAGE_SIZE_COVER="Omslag" NR_IMAGE_SIZE_CONTAIN="Innehåll" NR_REPEAT="Upprepa" NR_REPEAT_X="Upprepa-x" NR_REPEAT_Y="Upprepa-y" NR_REPEAT_NO="Ingen upprepning" NR_FIELD_STATE_DESC="Ange objektets status" NR_CREATED_DATE="Skapad datum" NR_CREATED_DATE_DESC="Datumet då objektet skapades." NR_MODIFIFED_DATE="Ändrad datum" NR_MODIFIFED_DATE_DESC="Datumet då objektet senast ändrades." NR_CATEGORIES="Kategori" NR_CATEGORIES_DESC="Välj de kategorier du vill tilldela." NR_ALSO_ON_CHILD_ITEMS="Även underliggande objekt" NR_ALSO_ON_CHILD_ITEMS_DESC="Tilldela även underliggande objekt till de valda objekten?" NR_PAGE_TYPE="Sidtyp" NR_PAGE_TYPES="Sidtyper" NR_PAGE_TYPES_DESC="Välj på vilka sidtyper tilldelningen ska vara aktiv." NR_CONTENT_VIEW_CATEGORY_BLOG="Kategori - Blogglayout" NR_CONTENT_VIEW_CATEGORY_LIST="Kategori - Listlayout" NR_CONTENT_VIEW_CATEGORIES="Lista Alla kategorier" NR_CONTENT_VIEW_ARCHIVED="Arkiverade artiklar" NR_CONTENT_VIEW_FEATURES="Utvalda artiklar" NR_CONTENT_VIEW_CREATE_ARTICLE="Skapa artikel" NR_CONTENT_VIEW_ARTICLE="En artikel" NR_ARTICLE_VIEW_DESC="Aktivera för att ta hänsyn till artikelvyn" NR_CATEGORY_VIEW="Kategorivy" NR_CATEGORY_VIEW_DESC="Aktivera för att ta hänsyn till kategorivyn" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Artiklar" NR_ARTICLES_DESC="Välj artiklar att tilldela." NR_ARTICLE="Artikel" NR_ARTICLE_AUTHORS="Författare" NR_ARTICLE_AUTHORS_DESC="Välj de författare du vill tilldela." NR_ONLY="Bara" NR_OTHERS="Andra" NR_SMARTTAGS="Smarta taggar" NR_SMARTTAGS_SHOW="Visa Smarta taggar" NR_SMARTTAGS_NOTFOUND="Hittade inga Smarta taggar" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Sök efter Smarta taggar" NR_CONTACT_US="Kontakta oss" NR_FONT_COLOR="Teckenfärg" NR_FONT_SIZE="Teckenstorlek" NR_FONT_SIZE_DESC="Välj teckenstorlek i pixlar" NR_TEXT="Text" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Aktivera vid åsidosättning av utdata" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Aktiverar tilläggsrendering när sidlayouten (tmpl) åsidosätts. Exempel: tmpl=component eller tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Aktivera vid åsidosättning av format" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Aktiverar tilläggs rendering när sidformatet inte är annat än HTML. Examples: format=raw or format=json." NR_GEOLOCATING="Geolokalisering" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="Geolokalisering är inte alltid 100% korrekt. Geolokaliseringen baseras på besökarens IP-adress. Det är inte alla IP-adresser är fasta eller kända." NR_CITY="Ort" NR_CITY_NAME="Ortens namn" NR_CONDITION_CITY_DESC="Ange ett stadsnamn på engelska. Ange flera städer åtskilda med komma." NR_CONTINENT="Kontinent" NR_REGION="Region" NR_CONDITION_REGION_DESC="Värdet består av två delar, den tvåbokstavs ISO 3166-1 landskoden och regionskoden. Så värdet bör vara i följande form: COUNTRY_CODE-REGION_CODE. Klicka på länken Hitta en regionkod för en fullständig lista med regionkoder." NR_ASSIGN_COUNTRIES="Land" NR_ASSIGN_COUNTRIES_DESC2="Rikta till besökare som fysiskt befinner sig i ett visst land." NR_ASSIGN_COUNTRIES_DESC="Välj länder du vill tilldela" NR_ASSIGN_CONTINENTS="Kontinent" NR_ASSIGN_CONTINENTS_DESC="Välj de kontinenter du vill tilldela." NR_ASSIGN_CONTINENTS_DESC2="Rikta till besökare som fysiskt befinner sig i en viss kontinent" NR_ICONTACT_ACCOUNTID_ERROR="Det gick inte att hämta iContact AccountID" NR_TAG_CLIENTDEVICE="Besökarens enhetstyp" NR_TAG_CLIENTOS="Besökarens operativsystem" NR_TAG_CLIENTBROWSER="Besökarens webbläsare" NR_TAG_CLIENTUSERAGENT="Besökarens agentsträng" NR_TAG_IP="Besökarens IP-adress" NR_TAG_URL="Sidans URL" NR_TAG_URLENCODED="Sidans URL kodad" NR_TAG_URLPATH="Sidans sökväg" NR_TAG_REFERRER="Sidhänvisare" NR_TAG_SITENAME="Webbplatsens namn" NR_TAG_SITEURL="Webbplatsens URL" NR_TAG_PAGETITLE="Sidans titel" NR_TAG_PAGEDESC="Sidans metabeskrivning" NR_TAG_PAGELANG="Sidans språk" NR_TAG_USERID="Användar-ID" NR_TAG_USERNAME="Namn" NR_TAG_USERLOGIN="Användarnamn" NR_TAG_USEREMAIL="E-post" NR_TAG_USERFIRSTNAME="Förnamn" NR_TAG_USERLASTNAME="Efternamn" NR_TAG_USERGROUPS="Användargrupper IDn" NR_TAG_DATE="Datum" NR_TAG_TIME="Tid" NR_TAG_RANDOMID="Slumpmässigt ID" NR_ICON="Ikon" NR_SELECT_MODULE="Välj en modul" NR_SELECT_CONTINENT="Välj en kontinent" NR_SELECT_COUNTRY="Välj ett land" NR_PLUGIN="Plugin" NR_GMAP_KEY="Google Maps API-nyckel" NR_GMAP_KEY_DESC="Google Maps API-nyckel används av Tassos.gr-tillägg. Om du får problem med att en Google Map inte laddas måste du antagligen ange en egen API-nyckel." NR_GMAP_FIND_KEY="Skaffa en API-nyckel" NR_ARE_YOU_SURE="Är du säker?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="Anpassad URL" NR_SAMPLE="Exempel" NR_DEBUG="Felsök" NR_CUSTOMURL="Anpassad URL" NR_READMORE="Läs mer" NR_IPADDRESS="IP-adress" NR_ASSIGN_BROWSERS="Webbläsare" NR_ASSIGN_BROWSERS_DESC="Välj de webbläsare du vill tilldela" NR_ASSIGN_BROWSERS_DESC2="Rikta till besökare som surfar på din webbplats med specifika webbläsare, som Chrome, Firefox eller Internet Explorer." NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Operativsystem" NR_ASSIGN_OS_DESC="Välj de operativsystem du vill tilldela." NR_ASSIGN_OS_DESC2="Rikta till besökare som använder specifika operativsystem som Windows, Linux eller Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Antal sidvisningar" NR_ASSIGN_PAGEVIEWS_DESC="Rikta till besökare som har visat ett visst antal sidor" NR_ASSIGN_PAGEVIEWS_VIEWS="Sidvisningar" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Ange antalet sidvisningar" NR_ASSIGN_COOKIENAME_NAME="Cookie namn" NR_ASSIGN_COOKIENAME_NAME_DESC="Ange namnet på cookien du vill tilldela" NR_ASSIGN_COOKIENAME_NAME_DESC2="Rikta till besökare som har specifika cookies lagrade i sin webbläsare" NR_FEWER_THAN="Mindre än" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="Större än" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Exakt" NR_EXISTS="Finns" ; NR_NOT_EXISTS="Does not exists" NR_IS_EQUAL="Lika med" ; NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Innehåller" ; NR_DOES_NOT_CONTAIN="Does not contain" NR_STARTS_WITH="Börjar med" ; NR_DOES_NOT_START_WITH="Does not start with" NR_ENDS_WITH="Slutar med" ; NR_DOES_NOT_END_WITH="Does not end with" NR_ASSIGN_COOKIENAME_CONTENT="Cookie innehåll" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Cookiens innehåll" NR_ASSIGN_IP_ADDRESSES_DESC2="Rikta besökare som befinner sig bakom en specifik IP-adress (intervall)" NR_ASSIGN_IP_ADDRESSES_DESC="Ange en lista med komma och/eller 'enter' separerad IP-adressee och intervall

Exempel:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="Användar-ID" NR_ASSIGN_USER_ID_DESC="Rikta till specifika Joomla-användare efter deras ID" NR_ASSIGN_USER_ID_SELECTION_DESC="Ange kommaseparerade Joomla användar-IDn" NR_ASSIGN_COMPONENTS="Komponent" NR_ASSIGN_COMPONENTS_DESC="Välj de komponenter du vill tilldela." NR_ASSIGN_COMPONENTS_DESC2="Rikta till besökare som surfar till specifika komponenter" NR_ASSIGN_TIMERANGE="Tidsintervall" NR_ASSIGN_TIMERANGE_DESC="Rikta till besökare baserat på din servers tid" NR_START_TIME="Starttid" NR_END_TIME="Sluttid" NR_START_PUBLISHING_TIMERANGE_DESC="Ange tid att starta publicering" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Ange tid att avsluta publicering" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_DESC="För att få en webbplatsnyckel och en hemlig nyckel för din domän, gå till https://www.google.com/recaptcha" NR_RECAPTCHA_SITE_KEY="Webbplatsnyckel" NR_RECAPTCHA_SITE_KEY_DESC="Används i JavaScript-koden som presenteras för dina användare." NR_RECAPTCHA_SECRET_KEY="Hemlig nyckel" NR_RECAPTCHA_SECRET_KEY_DESC="Används i kommunikationen mellan din server och reCAPTCHA-servern. Se till att hålla det hemligt." NR_RECAPTCHA_SITE_KEY_ERROR="Webbplatsnyckeln för reCaptcha saknas eller är ogiltig" NR_PREVIOUS_MONTH="Förra månaden" NR_NEXT_MONTH="Nästa månad" NR_ASSIGN_GROUP_PAGE_URL="Sidans URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Rikta till besökare som surfar till specifika menyalternativ eller URLer" NR_ASSIGN_GROUP_DATETIME_DESC="Trigga en ruta baserat på din servers datum och tid" NR_ASSIGN_GROUP_USER_VISITOR="Joomla användare / besökare" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Rikta till registrerade användare eller besökare som har tittat på ett visst antal sidor" NR_ASSIGN_GROUP_PLATFORM="Besökares plattform" NR_ASSIGN_GROUP_PLATFORM_DESC="Rikta till besökare som använder mobil, Google Chrome eller Windows." NR_ASSIGN_GROUP_GEO_DESC="Rikta till besökare som fysiskt befinner sig i en viss region." NR_ASSIGN_GROUP_JCONTENT="Joomla! innehåll" NR_ASSIGN_GROUP_JCONTENT_DESC="Rikta till besökare som tittar på specifika Joomla-artiklar eller kategorier." NR_ASSIGN_GROUP_SYSTEM="System / Integration" ; NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Rikta till besökare som interagerat med specifika Joomla-tillägg från tredje part." NR_ASSIGN_GROUP_ADVANCED="Avancerad inriktning till besökare" NR_ASSIGN_USERGROUP_DESC="Rikta till specifika Joomla användargrupper" NR_ASSIGN_ARTICLE_DESC="Rikta till besökare som tittar på specifika Joomla-artiklar." NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Rikta till besökare som tittar på specifika Joomla kategorier" NR_EXTENSION_REQUIRED="%s komponenten kräver att %s plugin är aktiverad iför att fungera korrekt." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Rikta till besökare som surfar till specifika K2-artiklar, kategorier eller taggar." NR_ASSIGN_K2_ITEMS="Objekt" NR_ASSIGN_K2_ITEMS_DESC="Rikta till besökare som surfar till specifika K2-objekt." NR_ASSIGN_K2_ITEMS_LIST_DESC="Välj de K2-objekt du vill tilldela" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Matcha specifika nyckelord i objektens innehåll. Separera med komma eller ny rad." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Matcha med objektets metanyckelord. Separera med ett komma eller ny rad." NR_ASSIGN_K2_PAGETYPES_DESC="Rikta till besökare som surfar till specifika K2-sidtyper" NR_ASSIGN_K2_ITEM_OPTION="Objekt" NR_ASSIGN_K2_LATEST_OPTION="Senaste objekten från användare eller kategorier" NR_ASSIGN_K2_TAG_OPTION="Taggsida" NR_ASSIGN_K2_CATEGORY_OPTION="Kategorisida" NR_ASSIGN_K2_ITEM_FORM_OPTION="Objekt redigeringsformulär" NR_ASSIGN_K2_USER_PAGE_OPTION="Användarsida (blogg)" NR_ASSIGN_K2_TAGS_DESC="Rikta till besökare som surfar på K2-objekt med specifika taggar" NR_ASSIGN_K2_CATEGORIES_DESC="Rikta till besökare som surfar till specifika K2-kategorier." NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Kategorier" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Objekt" NR_ASSIGN_PAGE_TYPES_DESC="Välj sidtyper som du vill tilldela" NR_ASSIGN_TAGS_DESC="Välj taggarna du vill tilldela" NR_CONTENT_KEYWORDS="Innehåll nyckelord" NR_META_KEYWORDS="Meta nyckelord" NR_TAG="Tagg" NR_NORMAL="Normal" NR_COMPACT="Kompakt" NR_LIGHT="Ljus" NR_DARK="Mörk" NR_SIZE="Storlek" NR_THEME="Tema" NR_SINGLE="Enstaka" NR_MULTIPLE="Flera" NR_RANGE="Intervall" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Bekräfta" NR_RECAPTCHA_INVALID_SECRET_KEY="Ogiltig hemlig nyckel" NR_PAGE="Sida" NR_YOU_ARE_USING_EXTENSION="Du använder%s%s" NR_UPDATE="Uppdatera" NR_SHOW_UPDATE_NOTIFICATION="Visa meddelande om uppdatering" NR_SHOW_UPDATE_NOTIFICATION_DESC="Om vald, visas en uppdateringsnotis i huvudkomponentvyn när det finns en ny version av detta tillägg." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s är tillgänglig" NR_ERROR_EMAIL_IS_DISABLED="E-postsändning är avstängd. E-postmeddelanden kunde inte skickas." NR_ASSIGN_ITEMS="Objekt" NR_COUNTRY_AF="Afghanistan" NR_COUNTRY_AX="Åland" NR_COUNTRY_AL="Albanien" NR_COUNTRY_DZ="Algeriet" NR_COUNTRY_AS="Amerikanska Samoaöarna" NR_COUNTRY_AD="Andorra" NR_COUNTRY_AO="Angola" NR_COUNTRY_AI="Anguilla" NR_COUNTRY_AQ="Antarktis" NR_COUNTRY_AG="Antigua och Barbuda" NR_COUNTRY_AR="Argentina" NR_COUNTRY_AM="Armenien" NR_COUNTRY_AW="Aruba" NR_COUNTRY_AU="Australien" NR_COUNTRY_AT="Österrike" NR_COUNTRY_AZ="Azerbaijan" NR_COUNTRY_BS="Bahamas" NR_COUNTRY_BH="Bahrain" NR_COUNTRY_BD="Bangladesh" NR_COUNTRY_BB="Barbados" NR_COUNTRY_BY="Belarus" NR_COUNTRY_BE="Belgien" NR_COUNTRY_BZ="Belize" NR_COUNTRY_BJ="Benin" NR_COUNTRY_BM="Bermuda" NR_COUNTRY_BQ_BO="Bonaire" NR_COUNTRY_BQ_SA="Saba" NR_COUNTRY_BQ_SE="Sint Eustatius" NR_COUNTRY_BT="Bhutan" NR_COUNTRY_BO="Bolivia" NR_COUNTRY_BA="Bosnien och Hercegovina" NR_COUNTRY_BW="Botswana" NR_COUNTRY_BV="Bouvet Island" NR_COUNTRY_BR="Brasilien" NR_COUNTRY_IO="Brittiska territoriet i Indiska oceanen" NR_COUNTRY_BN="Brunei Darussalam" NR_COUNTRY_BG="Bulgarien" NR_COUNTRY_BF="Burkina Faso" NR_COUNTRY_BI="Burundi" NR_COUNTRY_KH="Kambodja" NR_COUNTRY_CM="Kamerun" NR_COUNTRY_CA="Kanada" NR_COUNTRY_CV="Cap Verde" NR_COUNTRY_KY="Caymanöarna" NR_COUNTRY_CF="Centralafrikanska republiken" NR_COUNTRY_TD="Tchad" NR_COUNTRY_CL="Chile" NR_COUNTRY_CN="Kina" NR_COUNTRY_CX="Julön" NR_COUNTRY_CC="Cocos (Keeling) öarna" NR_COUNTRY_CO="Colombia" NR_COUNTRY_KM="Komorerna" NR_COUNTRY_CG="Kongo" NR_COUNTRY_CD="Kongo, Demokratiska republiken" NR_COUNTRY_CK="Cooköarna" NR_COUNTRY_CR="Costa Rica" NR_COUNTRY_CI="Elfenbenskusten" NR_COUNTRY_HR="Kroatien" NR_COUNTRY_CU="Kuba" NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Cypern" NR_COUNTRY_CZ="Tjeckien" NR_COUNTRY_DK="Danmark" NR_COUNTRY_DJ="Djibouti" NR_COUNTRY_DM="Dominica" NR_COUNTRY_DO="Dominikanska republiken" NR_COUNTRY_EC="Ecuador" NR_COUNTRY_EG="Egypten" NR_COUNTRY_SV="El Salvador" NR_COUNTRY_GQ="Ekvatorialguinea" NR_COUNTRY_ER="Eritrea" NR_COUNTRY_EE="Estland" NR_COUNTRY_ET="Etiopien" NR_COUNTRY_FK="Falklandsöarna (Malvinas)" NR_COUNTRY_FO="Färöarna" NR_COUNTRY_FJ="Fiji" NR_COUNTRY_FI="Finland" NR_COUNTRY_FR="Frankrike" NR_COUNTRY_GF="Franska Guyana" NR_COUNTRY_PF="Franska Polynesien" NR_COUNTRY_TF="Franska södra territorierna" NR_COUNTRY_GA="Gabon" NR_COUNTRY_GM="Gambia" NR_COUNTRY_GE="Georgien" NR_COUNTRY_DE="Tyskland" NR_COUNTRY_GH="Ghana" NR_COUNTRY_GI="Gibraltar" NR_COUNTRY_GR="Grekland" NR_COUNTRY_GL="Grönland" NR_COUNTRY_GD="Grenada" NR_COUNTRY_GP="Guadeloupe" NR_COUNTRY_GU="Guam" NR_COUNTRY_GT="Guatemala" NR_COUNTRY_GG="Guernsey" NR_COUNTRY_GN="Guinea" NR_COUNTRY_GW="Guinea-Bissau" NR_COUNTRY_GY="Guyana" NR_COUNTRY_HT="Haiti" NR_COUNTRY_HM="Heard Island och McDonald Islands" NR_COUNTRY_VA="Holy See (Vatikanstaten)" NR_COUNTRY_HN="Honduras" NR_COUNTRY_HK="Hong Kong" NR_COUNTRY_HU="Ungern" NR_COUNTRY_IS="Island" NR_COUNTRY_IN="Indien" NR_COUNTRY_ID="Indonesien" NR_COUNTRY_IR="Iran, Islamiska republiken" NR_COUNTRY_IQ="Irak" NR_COUNTRY_IE="Irland" NR_COUNTRY_IM="Isle of Man" NR_COUNTRY_IL="Israel" NR_COUNTRY_IT="Italien" NR_COUNTRY_JM="Jamaica" NR_COUNTRY_JP="Japan" NR_COUNTRY_JE="Jersey" NR_COUNTRY_JO="Jordanien" NR_COUNTRY_KZ="Kazakhstan" NR_COUNTRY_KE="Kenya" NR_COUNTRY_KI="Kiribati" NR_COUNTRY_KP="Nordkorea" NR_COUNTRY_KR="Sydkorea" NR_COUNTRY_KW="Kuwait" NR_COUNTRY_KG="Kirgizistan" NR_COUNTRY_LA="Laos" NR_COUNTRY_LV="Lettland" NR_COUNTRY_LB="Libanon" NR_COUNTRY_LS="Lesotho" NR_COUNTRY_LR="Liberia" NR_COUNTRY_LY="Libyen" NR_COUNTRY_LI="Liechtenstein" NR_COUNTRY_LT="Litauen" NR_COUNTRY_LU="Luxemburg" NR_COUNTRY_MO="Macao" NR_COUNTRY_MK="Makedonien" NR_COUNTRY_MG="Madagaskar" NR_COUNTRY_MW="Malawi" NR_COUNTRY_MY="Malaysia" NR_COUNTRY_MV="Maldiverna" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Malta" NR_COUNTRY_MH="Marshallöarna" NR_COUNTRY_MQ="Martinique" NR_COUNTRY_MR="Mauretanien" NR_COUNTRY_MU="Mauritius" NR_COUNTRY_YT="Mayotte" NR_COUNTRY_MX="Mexico" NR_COUNTRY_FM="Mikronesien, federerade staterna" NR_COUNTRY_MD="Moldavien" NR_COUNTRY_MC="Monaco" NR_COUNTRY_MN="Mongoliet" NR_COUNTRY_ME="Montenegro" NR_COUNTRY_MS="Montserrat" NR_COUNTRY_MA="Marocko" NR_COUNTRY_MZ="Moçambique" NR_COUNTRY_MM="Myanmar" NR_COUNTRY_NA="Namibia" NR_COUNTRY_NR="Nauru" NR_COUNTRY_NM="Nordmakedonien" NR_COUNTRY_NP="Nepal" NR_COUNTRY_NL="Nederländerna" NR_COUNTRY_AN="Nederländska Antillerna" NR_COUNTRY_NC="Nya Kaledonien" NR_COUNTRY_NZ="Nya Zeeland" NR_COUNTRY_NI="Nicaragua" NR_COUNTRY_NE="Niger" NR_COUNTRY_NG="Nigeria" NR_COUNTRY_NU="Niue" NR_COUNTRY_NF="Norfolk Island" NR_COUNTRY_MP="Norra Marianeröarna" NR_COUNTRY_NO="Norge" NR_COUNTRY_OM="Oman" NR_COUNTRY_PK="Pakistan" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Palestinian Territory" NR_COUNTRY_PA="Panama" NR_COUNTRY_PG="Papua Nya Guinea" NR_COUNTRY_PY="Paraguay" NR_COUNTRY_PE="Peru" NR_COUNTRY_PH="Filippinerna" NR_COUNTRY_PN="Pitcairn" NR_COUNTRY_PL="Polen" NR_COUNTRY_PT="Portugal" NR_COUNTRY_PR="Puerto Rico" NR_COUNTRY_QA="Qatar" NR_COUNTRY_RE="Reunion" NR_COUNTRY_RO="Rumänien" NR_COUNTRY_RU="Ryska Federationen" NR_COUNTRY_RW="Rwanda" NR_COUNTRY_SH="Saint Helena" NR_COUNTRY_KN="Saint Kitts och Nevis" NR_COUNTRY_LC="Saint Lucia" NR_COUNTRY_PM="Saint Pierre och Miquelon" NR_COUNTRY_VC="Saint Vincent och Grenadinerna" NR_COUNTRY_WS="Samoa" NR_COUNTRY_SM="San Marino" NR_COUNTRY_ST="Sao Tome och Principe" NR_COUNTRY_SA="Saudiarabien" NR_COUNTRY_SN="Senegal" NR_COUNTRY_RS="Serbien" NR_COUNTRY_SC="Seychellerna" NR_COUNTRY_SL="Sierra Leone" NR_COUNTRY_SG="Singapore" NR_COUNTRY_SK="Slovakien" NR_COUNTRY_SI="Slovenia" NR_COUNTRY_SB="Salomonöarna" NR_COUNTRY_SO="Somalia" NR_COUNTRY_ZA="Sydafrika" NR_COUNTRY_GS="Södra Georgien och Södra Sandwichöarna" NR_COUNTRY_ES="Spanien" NR_COUNTRY_LK="Sri Lanka" NR_COUNTRY_SD="Sudan" NR_COUNTRY_SS="Södra Sudan" NR_COUNTRY_SR="Surinam" NR_COUNTRY_SJ="Svalbard och Jan Mayen" NR_COUNTRY_SZ="Swaziland" NR_COUNTRY_SE="Sverige" NR_COUNTRY_CH="Schweiz" NR_COUNTRY_SY="Syrien, Arabiska republiken" NR_COUNTRY_TW="Taiwan" NR_COUNTRY_TJ="Tadzjikistan" NR_COUNTRY_TZ="Tanzania, Förenade republiken" NR_COUNTRY_TH="Thailand" NR_COUNTRY_TL="Östtimor" NR_COUNTRY_TG="Togo" NR_COUNTRY_TK="Tokelau" NR_COUNTRY_TO="Tonga" NR_COUNTRY_TT="Trinidad och Tobago" NR_COUNTRY_TN="Tunisien" NR_COUNTRY_TR="Turkiet" NR_COUNTRY_TM="Turkmenistan" NR_COUNTRY_TC="Turks- och Caicosöarna" NR_COUNTRY_TV="Tuvalu" NR_COUNTRY_UG="Uganda" NR_COUNTRY_UA="Ukraina" NR_COUNTRY_AE="Förenade arabemiraten" NR_COUNTRY_GB="Storbritannien" NR_COUNTRY_US="USA" NR_COUNTRY_UM="Förenta staternas mindre öar i Oceanien och Västindien" NR_COUNTRY_UY="Uruguay" NR_COUNTRY_UZ="Uzbekistan" NR_COUNTRY_VU="Vanuatu" NR_COUNTRY_VE="Venezuela" NR_COUNTRY_VN="Vietnam" NR_COUNTRY_VG="Jungfruöarna, Brittiska" NR_COUNTRY_VI="Jungfruöarna, USA" NR_COUNTRY_WF="Wallis- och Futunaöarna" NR_COUNTRY_EH="Västra Sahara" NR_COUNTRY_YE="Yemen" NR_COUNTRY_ZM="Zambia" NR_COUNTRY_ZW="Zimbabwe" NR_CONTINENT_AF="Afrika" NR_CONTINENT_AS="Asien" NR_CONTINENT_EU="Europa" NR_CONTINENT_NA="Nordamerika" NR_CONTINENT_SA="Sydamerika" NR_CONTINENT_OC="Oceanien" NR_CONTINENT_AN="Antarktis" NR_FRONTEND="Frontend" NR_BACKEND="Backend" NR_EMBED="Bädda in" NR_RATE="Betyg %s" NR_REPORT_ISSUE="Rapportera ett problem" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" NR_TAG_PAGEGENERATOR="Sidgenerator" NR_TAG_PAGELANGURL="Sidans språk URL" NR_TAG_PAGEKEYWORDS="Sidans nyckelord" NR_TAG_SITEEMAIL="Webbplatsens e-post" NR_TAG_DAY="Dag" NR_TAG_MONTH="Månad" NR_TAG_YEAR="År" NR_TAG_USERREGISTERDATE="Registreringsdatum" NR_TAG_PAGEBROWSERTITLE="Webbläsarens titel" NR_TAG_EBID="Rutans ID" NR_TAG_EBTITLE="Rutans titel" NR_TAG_QUERYSTRINGOPTION="Frågesträng: Alternativ" NR_TAG_QUERYSTRINGVIEW="Frågesträng: Vy" NR_TAG_QUERYSTRINGLAYOUT="Frågesträng: Layout" NR_TAG_QUERYSTRINGTMPL="Frågesträng: Mall" NR_CANNOT_CREATE_FOLDER="Det går inte att skapa en mapp för att flytta filen. %s" NR_CANNOT_MOVE_FILE="Det går inte att flytta filen: %s" NR_UPLOAD_INVALID_FILE_TYPE="Filtypen stöds inte: %s (%s). Tillåtna filtyper är: %s" NR_UPLOAD_NO_MIME_TYPE="Det gick inte att gissa filen mime-typ: %s. Se till att PHP filinfo är aktiverat." NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Det går inte att ladda upp filen: %s" NR_START_OVER="Börja om" NR_TRY_AGAIN="Försök igen" NR_ERROR="Fel" NR_CANCEL="Avbryt" NR_PLEASE_WAIT="Vänta" NR_STAR="stjärna%s" NR_HCAPTCHA="hCaptcha" NR_TYPE="Typ" NR_CHECKBOX="Kryssruta" NR_INVISIBLE="Osynlig" NR_HCAPTCHA_DESC="För att få en webbplatsnyckel och en hemlig nyckel för din domän, gå till https://dashboard.hcaptcha.com/sites." NR_HCAPTCHA_SECRET_KEY_DESC="Används i kommunikationen mellan din server och hCAPTCHA-servern. Se till att hålla det hemligt." NR_OUTDATED_EXTENSION="Din version av %s är mer än %d dagar gammal och troligen redan inaktuell. Kontrollera om en %snyare version%s finns tillgänglig och installera den." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!.foHHBsystem/nrframework/language/nl-NL/nl-NL.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Systeem - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - gebruikt door Tassos.gr extensions" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Negeren" NR_INCLUDE="Insluiten" NR_EXCLUDE="Uitsluiten" NR_SELECTION="Selectie" NR_ASSIGN_MENU_NOITEM="Geen Itemid insluiten" NR_ASSIGN_MENU_NOITEM_DESC="Ook toewijzen indien de URL geen Itemid bevat?" NR_ASSIGN_MENU_CHILD="Ook onderliggende items" NR_ASSIGN_MENU_CHILD_DESC="Ook onderliggende items van de geselecteerde items?" NR_COPY_OF="Kopie van %s" NR_ASSIGN_DATETIME_DESC="Target bezoekers op basis van de datetime van uw server" NR_DATETIME="Datum en tijd" NR_TIME="Tijd" NR_DATE="Datum" NR_DATETIME_DESC="Vul datum en tijdstip in voor automatische publicatie/depublicatie" NR_START_PUBLISHING="Start DatumTijd" NR_START_PUBLISHING_DESC="Vul startdatum publicatie in" ; NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="Vul einddatum publicatie in" NR_DATETIME_NOTE="De datum- en tijdgegevens zijn deze van de server waarop uw website gehost wordt, niet de datum/tijd van de bezoekers van uw website." NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP Code" NR_ASSIGN_PHP_DESC="Voer een stuk van de PHP in om te evalueren" NR_ASSIGN_PHP_DESC2="Target bezoekers die aangepaste PHP-code evalueren. De code moet de waarde true of false teruggeven.

Bijvoorbeeld:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Tijd op website" NR_SECONDS="Seconden" NR_ASSIGN_TIMEONSITE_DESC="Vul de tijd in die een bezoeker op je website moet doorbrengen (Bezoekerstijd) in seconden.

Voorbeeld:
Als je een box wil tonen nadat een bezoeker 3 minuten op je website doorgebracht heeft, vul dan 180 in." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Target bezoekers die specifieke URL's bekijken" NR_ASSIGN_URLS_DESC="Vul (deel van) de URLs in dat moet overeenstemmen.
Gebruik een nieuwe regel voor elke nieuwe URL." NR_ASSIGN_URLS_LIST="URL Overeenkomsten" NR_ASSIGN_URLS_REGEX="Gebruik reguliere expressies" NR_ASSIGN_URLS_REGEX_DESC="Selecteer om de waarde te gebruiken als regular expressions." NR_ASSIGN_LANGS="Taal" NR_ASSIGN_LANGS_DESC="Target bezoekers die uw website in specifieke taal bekijken" NR_ASSIGN_LANGS_LIST_DESC="Selecteer de talen om aan toe te wijzen" NR_ASSIGN_DEVICES="Toestel" NR_ASSIGN_DEVICES_DESC2="Target bezoekers met een specifiek apparaat, zoals mobiel, tablet of desktop." NR_ASSIGN_DEVICES_DESC="Selecteer de apparaten om aan toe te wijzen." NR_ASSIGN_DEVICES_NOTE="Hou er rekening mee dat apparaat detectie niet altijd 100% accuraat is. Gebruikers kunnen hun browser configureren om andere apparaten na te bootsen" NR_MENU="Menu" NR_MENU_ITEMS="Menu Item" NR_MENU_ITEMS_DESC="Target bezoekers die specifieke menu-items bekijken" NR_USERGROUP="Gebruikers Groep" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Gebruiker Groep" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Toon Copyright" NR_SHOW_COPYRIGHT_DESC="Indien geselecteerd zal extra copyright informatie getoond worden in het beheerspanel. Novarain Extensions toont nooit copyright informatie of backlinks in de frontend." NR_WIDTH="Breedte" NR_WIDTH_DESC="Vul de breedte in px, em of % in

Voorbeeld: 400px" NR_HEIGHT="Hoogte" NR_HEIGHT_DESC="Vul de hoogte in px, em of % in

Voorbeeld: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Vul de padding in px, em of % in

Voorbeeld: 20px" NR_MARGIN="Margin" NR_MARGIN_DESC="De functie CSS-marge wordt gebruikt om ruimte rond de box te genereren en de grootte van de witte ruimte buiten de rand in pixels of in% in te stellen.

Voorbeeld 1: 25px
Voorbeeld 2: 5%

De marge voor elke zijde opgeven [rechtsboven linksonder]:

Alleen bovenzijde: 25px 0 0 0
Alleen rechterzijde: 0 25px 0 0
Alleen onderkant alleen: 0 0 25px 0
Alleen linkerzijde: 0 0 0 25px" NR_COLOR_HOVER="Hover Kleur" NR_COLOR="Kleur" NR_COLOR_DESC="Geef een kleur op in HEX of RGBA formaat." NR_TEXT_COLOR="Tekst Kleur" NR_BACKGROUND="Achtergrond" NR_BACKGROUND_COLOR="Achtergrond Kleur" NR_BACKGROUND_COLOR_DESC="Geef een kleur op in HEX of RGBA voor de achtergrond. Vul 'none' in om deze optie uit te schakelen. Vul 'transparent' in voor een volledig transparante achtergrond." NR_URL_SHORTENING_FAILED="Afkorting %s met %s niet gelukt. %s." NR_EXPORT="Exporteren" NR_IMPORT="Importeren" NR_PLEASE_CHOOSE_A_VALID_FILE="Kies een geldige bestandsnaam" NR_IMPORT_ITEMS="Importeer items" NR_PUBLISH_ITEMS="Publiceer items" NR_AS_EXPORTED="Zoals geexporteerd" NR_TITLE="Titel" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="Acymailing Lijst" NR_ACYMAILING_LIST_DESC="Selecteer AcyMailing lijst om toe te wijzen" NR_ASSIGN_ACYMAILING_DESC="Target bezoekers die geabonneerd zijn op specifieke AcyMailing-lijsten" NR_AKEEBASUBS="Akeeba Subscriptions" NR_AKEEBASUBS_LEVELS="Niveau's" NR_AKEEBASUBS_LEVELS_DESC="Selecteer Akeeba abonnement niveau om toe te wijzen." NR_ASSIGN_AKEEBASUBS_DESC="Target bezoekers die geabonneerd zijn op specifieke Akeeba-abonnementen" NR_MATCH="Overeenkomen " NR_MATCH_DESC="De gebruikte bijpassende methode om de waarde te vergelijken" NR_ASSIGN_MATCHING_METHOD="Overeenstemmingsmethode" NR_ASSIGN_MATCHING_METHOD_DESC="Moeten alle of minstens 1 toewijzing overeenstemmen?

Alle
Wordt gepubliceerd indien Alle hieronder vermelde toewijzingen overeenstemmen.

Minstens 1
Wordt gepubliceerd indien Minstens 1 (ιιn of meerdere) hieronder vermelde toewijzingen overeenstemmen.
Toewijzingingsopties waarvoor 'Negeren' is geselecteerd, worden genegeerd." NR_ANY="Minstens 1" ; NR_ALL="All" NR_ASSIGN_REFERRER="Doorverwijzings URL" NR_ASSIGN_REFERRER_DESC2="Target bezoekers die op uw site terechtkomen via een specifieke verkeersbron" NR_ASSIGN_REFERRER_DESC="Voer één verwijzende URL per regel in:

Bijvoorbeeld: google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Houd er rekening mee dat het zoeken naar URL-referrers niet altijd 100% nauwkeurig is. Sommige servers kunnen proxies gebruiken die deze informatie verwijderen en deze kan gemakkelijk worden vervalst." NR_PROFEATURE_HEADER="%sis een PRO-functie" NR_PROFEATURE_DESC="Het spijt ons, %shet is niet beschikbaar in uw abonnement. Voer een upgrade uit naar het PRO-plan om al deze geweldige functies te ontgrendelen." NR_PROFEATURE_DISCOUNT="Bonus: %sgratis gebruikers krijgen 20% korting op de normale prijs, automatisch toegepast bij het afrekenen." NR_ONLY_AVAILABLE_IN_PRO="Enkel beschikbaar in PRO versie" NR_UPGRADE_TO_PRO="Upgraden naar PRO" NR_UPGRADE_TO_PRO_TO_UNLOCK="Upgrade naar Pro versie om toegang te verkrijgen" NR_UPGRADE_TO_PRO_VERSION="Geweldig! Nog maar één stap over. Klik op de onderstaande knop om de upgrade naar de Pro-versie te voltooien." NR_UNLOCK_PRO_FEATURE="Ontgrendel de Pro-functie" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="Links naar Rechts" NR_RIGHT_TO_LEFT="Rechts naar Links" NR_BGIMAGE="Achtergrond Afbeelding" NR_BGIMAGE_DESC="Stelt een achtergrond afbeelding in" NR_BGIMAGE_FILE="Afbeelding" NR_BGIMAGE_FILE_DESC="Selecteer of upload een bestand als achtergrond afbeelding" NR_BGIMAGE_REPEAT="Herhalen" NR_BGIMAGE_REPEAT_DESC="De background-repeat eigenschap zorgt ervoor of en op welke wijze een achtergrond-afbeelding wordt herhaald. Standaard wordt een achtergrond-afbeelding zowel horizontaal als verticaal herhaald.

Repeat: De achtergrond-afbeelding wordt zowel horizontaal als verticaal herhaald.

Repeat-x: De achtergrond-afbeelding wordt enkel horizontaal herhaald.

Repeat-y: De achtergrond-afbeelding wordt enkel verticaal herhaald.

No-repeat: De achtergrond-afbeelding wordt niet herhaald." NR_BGIMAGE_SIZE="Afmetingen" NR_BGIMAGE_SIZE_DESC="Geef de afmetingen van een achtergrond-afbeelding op.

Auto: De achtergrond-afbeelding behoudt zijn originele breedte en hoogte.

Cover: De afmetingen van de achtergrond-afbeelding worden zo aangepast dat deze de achtergrond volledige bedekt. Hierdoor kunnen sommige delen van de achtergrond-afbeelding onzichtbaar (weggesneden) worden.

Contain: De achtergrond-afbeelding wordt zo groot mogelijk weergegeven binnen de achtergrond. Mogelijks wordt de achtergrond in dit geval niet volledig bedekt.

100% 100%: De achtergrond-afbeelding wordt over de volledige achtergrond uitgerekt. Mogelijks wordt de achtergrond-afbeelding in dit geval vervormd weergegeven." NR_BGIMAGE_POSITION="Positie" NR_BGIMAGE_POSITION_DESC="De background-position eigenschap geeft de beginpositie van een achtergrond-afbeelding aan. Standaard wordt een achtergrond-afbeelding in de top-left hoek geplaatst. De eerste waarde is de horizontale en de tweede waarde is de verticale positie.

Je kan ofwel één van de vooringestelde waarden invullen, ofwel een aangepaste waarde in percent: x% y% of in pixel xPos yPos." NR_RTL="RTL activeren" NR_RTL_DESC="De rechts-naar-links tekstrichting is essentieel voor rechts-naar-links geschriften zoals Arabisch, Syrisch en Thanaa." NR_HORIZONTAL="Horizontaal" NR_VERTICAL="Verticaal" NR_FORM_ORIENTATION="Formulier orientatie" NR_FORM_ORIENTATION_DESC="Kies de orientatie van het formulier" NR_ASSIGN_CATEGORY="Categorieen" NR_ASSIGN_CATEGORY_DESC="Kies de categorieen om aan toe te wijzen" NR_ASSIGN_CATEGORY_CHILD="Ook aan child items" NR_ASSIGN_CATEGORY_CHILD_DESC="Ook toewijzen aan child items van de geselecteerde items?" NR_NEW="Nieuw" NR_LIST="Lijst" NR_DOCUMENTATION="Documentatie" NR_KNOWLEDGEBASE="Kennisbank" NR_FAQ="FAQ" NR_INFORMATION="Informatie" NR_EXTENSION="Extensie" NR_VERSION="Versie" NR_CHANGELOG="Wijzigingen" ; NR_DOWNLOAD="Download" ; NR_DOWNLOAD_KEY_MISSING="Download Key is missing" NR_DOWNLOAD_KEY="Download Sleutel" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="Wil je %s updaten door middel van de Joomla update functie, dan moet je je Download Sleutel invullen in de Novarain Framework Plugin instellingen." NR_DOWNLOAD_KEY_FIND="Vind je Download Sleutel" NR_DOWNLOAD_KEY_UPDATE="Update je Download Sleutel" NR_OK="OK" NR_MISSING="Ontbrekend" NR_LICENSE="Licensie" NR_AUTHOR="Auteur" NR_FOLLOWME="Volg mij" NR_FOLLOW="Volg %s" NR_TRANSLATE_INTEREST="Heb je interesse om te helpen bij de vertaling van %s in je eigen Taal?" NR_TRANSIFEX_REQUEST="Stuur me een verzoek op Transifex" NR_HELP_WITH_TRANSLATIONS="Help met vertalingen" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Gevorderd" NR_USEGLOBAL="Gebruik Standaard" NR_WEEKDAY="Dag van de Week" NR_MONTH="Maand" NR_MONDAY="Maandag" NR_TUESDAY="Dinsdag" NR_WEDNESDAY="Woensdag" NR_THURSDAY="Donderdag" NR_FRIDAY="Vrijdag" NR_SATURDAY="Zaterdag" NR_WEEKEND="Weekend" NR_WEEKDAYS="Werkdagen" NR_SUNDAY="Zondag" NR_JANUARY="Januari" NR_FEBRUARY="Februari" NR_MARCH="Maart" NR_APRIL="April" NR_MAY="Mei" NR_JUNE="Juni" NR_JULY="Juli" NR_AUGUST="Augustus" NR_SEPTEMBER="September" NR_OCTOBER="Oktober" NR_NOVEMBER="November" NR_DECEMBER="December" NR_NEVER="Nooit" NR_SECONDS="Seconden" NR_MINUTES="Minuten" NR_HOURS="Uren" NR_DAYS="Dagen" NR_SESSION="Sessie" NR_EVER="Altijd" NR_COOKIE="Cookie" NR_BOTH="Beide" NR_NONE="Geen" ; NR_NONE_SELECTED="None Selected" NR_DESKTOPS="Desktop" NR_MOBILES="Mobiel" NR_TABLETS="Tablet" NR_PER_SESSION="Per Sessie" NR_PER_DAY="Per Dag" NR_PER_WEEK="Per Week" NR_PER_MONTH="Per Maand" NR_FOREVER="Altijd" NR_FEATURE_UNDER_DEV="Deze functie is in ontwikkeling" NR_LIKE_THIS_EXTENSION="Vind je deze extensie leuk?" NR_LEAVE_A_REVIEW="Schrijf een beoordeling op JED" NR_SUPPORT="Support" NR_NEED_SUPPORT="Support nodig?" NR_DROP_EMAIL="Stuur me een e-mailbericht" NR_READ_DOCUMENTATION="Lees de documentatie" NR_COPYRIGHT="%s - Tassos.gr Alle Rechten Voorbehouden" NR_DASHBOARD="Dashboard" NR_NAME="Naam" NR_WRONG_COORDINATES="De coördinaten die je opgaf zijn ongeldig" NR_ENTER_COORDINATES="Breedtegraad,Lengtegraad" NR_NO_ITEMS_FOUND="Geen Items gevonden" NR_ITEM_IDS="Geen item IDs" NR_TOGGLE="Wisselen" NR_EXPAND="Openklappen" NR_COLLAPSE="Dichtklappen" NR_SELECTED="Gekozen" NR_MAXIMIZE="Maximaliseren" NR_MINIMIZE="Minimaliseren" NR_SELECTION="Selectie" NR_INSTALL="Installeren" NR_INSTALL_NOW="Installeer Nu" NR_INSTALLED="Geïnstalleerd" NR_COMING_SOON="Binnenkort beschikbaar" NR_ROADMAP="Op de wegenkaart" NR_MEDIA_VERSIONING="Gebruik Media Versiebeheer" NR_MEDIA_VERSIONING_DESC="Selecteer om het extensie versie nummer toe te voegen op het einde van de media (js/css) urls, om zo browsers te forceren het correcte bestand te laden." NR_LOAD_JQUERY="jQuery laden" NR_LOAD_JQUERY_DESC="Selecteer om het basis jQuery bestand te laden. Je kan dit uitschakelen als je conflicten ervaart indien je template of andere extensies hun eigen jQuery versie laden." NR_SELECT_CURRENCY="Kies een Munteenheid" NR_CONVERTFORMS="Converteer Formulieren" NR_CONVERTFORMS_LIST="Campagnes" NR_ASSIGN_CONVERTFORMS_DESC="Target bezoekers die zich hebben geabonneerd op specifieke ConvertForms-campagnes" NR_CONVERTFORMS_LIST_DESC="Selecteer ConvertForms-campagnes waaraan u wilt toewijzen." NR_LEFT="Left" NR_CENTER="Center" NR_RIGHT="Right" NR_BOTTOM="Bottom" NR_TOP="Top" NR_AUTO="Auto" NR_CUSTOM="Aangepast" NR_UPLOAD="Upload" NR_IMAGE="Afbeelding" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" NR_IMAGE_SELECT="Selecteer Afbeelding" NR_IMAGE_SIZE_COVER="Cover" NR_IMAGE_SIZE_CONTAIN="Contain" NR_REPEAT="Repeat" NR_REPEAT_X="Repeat x" NR_REPEAT_Y="Repeat y" NR_REPEAT_NO="No repeat" NR_FIELD_STATE_DESC="Status van het item instellen" NR_CREATED_DATE="Aanmaak datum" NR_CREATED_DATE_DESC="Datum waarop het item werd gemaakt" NR_MODIFIFED_DATE="Datum wijziging" NR_MODIFIFED_DATE_DESC="Datum waarop het item voor het laatst werd gewijzigd." NR_CATEGORIES="Categorie" NR_CATEGORIES_DESC="Selecteer de categorieën om aan toe te wijzen." NR_ALSO_ON_CHILD_ITEMS="Ook aan ondergeschikte items" NR_ALSO_ON_CHILD_ITEMS_DESC="Ook toewijzen aan ondergeschikte elementen van de geselecteerde items?" NR_PAGE_TYPE="Pagina Type" NR_PAGE_TYPES="Pagina types" NR_PAGE_TYPES_DESC="Selecteer op welke pagina types de toewijzing actief moet zijn." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" NR_ARTICLE_VIEW_DESC="Schakel in om rekening te houden met de artikelweergave" NR_CATEGORY_VIEW="Categorie weergave" NR_CATEGORY_VIEW_DESC="Schakel in om rekening te houden met de categorieweergave" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Artikelen" NR_ARTICLES_DESC="Selecteer de artikelen om aan toe te wijzen." NR_ARTICLE="Artikel" NR_ARTICLE_AUTHORS="Auteurs" NR_ARTICLE_AUTHORS_DESC="Selecteer de auteurs om aan toe te wijzen." NR_ONLY="Uitsluitend" NR_OTHERS="Andere" NR_SMARTTAGS="Smart Tags" NR_SMARTTAGS_SHOW="Toon Smart Tags" NR_SMARTTAGS_NOTFOUND="Geen Smart Tags gevonden" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Zoeken op Smart Tags" NR_CONTACT_US="Contacteer ons" NR_FONT_COLOR="Tekst Kleur" NR_FONT_SIZE="Tekengrootte" NR_FONT_SIZE_DESC="Kies een tekengrootte in pixels" NR_TEXT="Tekst" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Inschakelen op Output OVerschrijven" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Schakelt het renderen van de extensie in wanneer de paginalay-out (tmpl) wordt overschreven. Voorbeelden: tmpl=component of tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Inschakelen bij Format Override" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Schakelt het renderen van de extensie in wanneer het paginaformaat niet anders is dan HTML. Voorbeelden: format=raw of format=json." NR_GEOLOCATING="Geolocatie" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="Geolocatie is niet altijd 100% nauwkeurig. De geolocatie is gebaseerd op het IP-adres van de bezoeker. Niet alle IP-adressen zijn vast of bekend." NR_CITY="Plaats" NR_CITY_NAME="Plaatsnaam" NR_CONDITION_CITY_DESC="Voer een plaatsnaam in het Engels in. Voer meerdere steden in, gescheiden door een komma." NR_CONTINENT="Continent" NR_REGION="Regio" NR_CONDITION_REGION_DESC="De waarde bestaat uit twee delen, de tweeletterige ISO 3166-1 landcode en de regiocode. De waarde moet dus de volgende vorm hebben: COUNTRY_CODE-REGION_CODE. Voor een volledige lijst van regiocodes klikt u op de koppeling Een regiocode zoeken." NR_ASSIGN_COUNTRIES="Land" NR_ASSIGN_COUNTRIES_DESC2="Target bezoekers die fysiek in een bepaald land zijn" NR_ASSIGN_COUNTRIES_DESC="Selecteer de landen waaraan u wilt toewijzen" NR_ASSIGN_CONTINENTS="Continent" NR_ASSIGN_CONTINENTS_DESC="Selecteer de continenten waaraan u wilt toewijzen" NR_ASSIGN_CONTINENTS_DESC2="Target bezoekers die fysiek in een bepaald continent zijn" NR_ICONTACT_ACCOUNTID_ERROR="Het iContact-account-ID kon niet worden opgehaald" NR_TAG_CLIENTDEVICE="Bezoeker Toestel Type" NR_TAG_CLIENTOS="Bezoeker OS" NR_TAG_CLIENTBROWSER="Bezoeker Browser" NR_TAG_CLIENTUSERAGENT="Bezoeker Agent String" NR_TAG_IP="Bezoeker IP Adres" NR_TAG_URL="Pagina URL" NR_TAG_URLENCODED="Pagina URL Encoded" NR_TAG_URLPATH="Pagina Pad" NR_TAG_REFERRER="Pagina Doorverwijzing" NR_TAG_SITENAME="Site Naam" NR_TAG_SITEURL="Site URL" NR_TAG_PAGETITLE="Pagina Titel" NR_TAG_PAGEDESC="Pagina Meta Omschrijving" NR_TAG_PAGELANG="Pagina Taal Code" NR_TAG_USERID="Gebruiker ID" NR_TAG_USERNAME="Gebruiker Volledige Naam" NR_TAG_USERLOGIN="Gebruiker Login" NR_TAG_USEREMAIL="Gebruiker E-mail" NR_TAG_USERFIRSTNAME="Gebruiker Voornaam" NR_TAG_USERLASTNAME="Gebruiker Achternaam" NR_TAG_USERGROUPS="Gebruiker Groeps ID" NR_TAG_DATE="Datum" NR_TAG_TIME="Tijd" NR_TAG_RANDOMID="Willekeurige ID" NR_ICON="Pictogram" NR_SELECT_MODULE="Selecteer een Module" NR_SELECT_CONTINENT="Selecteer een Continent" NR_SELECT_COUNTRY="Selecteer een Land" NR_PLUGIN="Plugin" NR_GMAP_KEY="Google Maps API Key" NR_GMAP_KEY_DESC="De Google Maps API Key wordt gebruikt door Tassos.gr-extensies. Als u problemen ondervindt met het niet laden van een Google Map, moet u waarschijnlijk uw eigen API Key invoeren." NR_GMAP_FIND_KEY="Krijg een API Key" NR_ARE_YOU_SURE="Weet je het zeker?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="Aangepaste URL" NR_SAMPLE="Voorbeeld" NR_DEBUG="Debuggen" NR_CUSTOMURL="Aangepaste URL" NR_READMORE="Lees Meer" NR_IPADDRESS="IP Adres" NR_ASSIGN_BROWSERS="Browser" NR_ASSIGN_BROWSERS_DESC="Selecteer de browser om aan te wijzen" NR_ASSIGN_BROWSERS_DESC2="Target bezoekers die op uw site browsen met specifieke browsers zoals Chrome, Firefox of Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="OS - Besturingssyteem" NR_ASSIGN_OS_DESC="Selecteer de besturingssystemen die u wilt toewijzen" NR_ASSIGN_OS_DESC2="Target bezoekers die specifieke besturingssystemen gebruiken, zoals Windows, Linux of Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Aantal Paginaweergaves" NR_ASSIGN_PAGEVIEWS_DESC="Target bezoekers die een bepaald aantal pagina's hebben bekeken" NR_ASSIGN_PAGEVIEWS_VIEWS="Paginaweergaves" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Voer aantal paginaweergaves in" NR_ASSIGN_COOKIENAME_NAME="Cookie Naam" NR_ASSIGN_COOKIENAME_NAME_DESC="Voer de naam in van de cookie die u wilt toewijzen" NR_ASSIGN_COOKIENAME_NAME_DESC2="Target bezoekers die specifieke cookies hebben opgeslagen in hun browser" NR_FEWER_THAN="Minder dan" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="Groter dan" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Exact" NR_EXISTS="Bestaat" ; NR_NOT_EXISTS="Does not exists" NR_IS_EQUAL="Vergelijkbaar" ; NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Bevat" ; NR_DOES_NOT_CONTAIN="Does not contain" NR_STARTS_WITH="Start met" ; NR_DOES_NOT_START_WITH="Does not start with" NR_ENDS_WITH="Eindigt met" ; NR_DOES_NOT_END_WITH="Does not end with" NR_ASSIGN_COOKIENAME_CONTENT="Cookie Inhoud" NR_ASSIGN_COOKIENAME_CONTENT_DESC="De inhoud van de cookie" NR_ASSIGN_IP_ADDRESSES_DESC2="Target bezoekers die achter een specifiek IP-adres staan (bereik)" NR_ASSIGN_IP_ADDRESSES_DESC="Voer een lijst in van komma's en / of 'enter' gescheiden ip-adressen en bereiken

Voorbeeld:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="Gebruiker ID" NR_ASSIGN_USER_ID_DESC="Target specifieke Joomla-gebruikers op basis van hun ID's" NR_ASSIGN_USER_ID_SELECTION_DESC="Voer door komma's gescheiden Joomla-gebruikers-ID's in" NR_ASSIGN_COMPONENTS="Component" NR_ASSIGN_COMPONENTS_DESC="Selecteer de componenten waaraan u wilt toewijzen" NR_ASSIGN_COMPONENTS_DESC2="Target bezoekers die specifieke componenten doorzoeken" NR_ASSIGN_TIMERANGE="Tijdsbestek" NR_ASSIGN_TIMERANGE_DESC="Target bezoekers op basis van de tijd van uw server" NR_START_TIME="Starttijd" NR_END_TIME="Eindtijd" NR_START_PUBLISHING_TIMERANGE_DESC="Voer de tijd in om te beginnen met publiceren" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Voer de tijd in om het publiceren te beëindigen" NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Site Sleutel" NR_RECAPTCHA_SITE_KEY_DESC="Gebruikt in de JavaScript-code die wordt aangeboden aan uw gebruikers." NR_RECAPTCHA_SECRET_KEY="Geheime Sleutel" NR_RECAPTCHA_SECRET_KEY_DESC="Gebruikt in de communicatie tussen uw server en de reCAPTCHA-server. Zorg dat je het geheim houdt." NR_RECAPTCHA_SITE_KEY_ERROR="De reCaptcha-sitesleutel ontbreekt of is ongeldig" NR_PREVIOUS_MONTH="Afgelopen Maand" NR_NEXT_MONTH="Volgende Maand" NR_ASSIGN_GROUP_PAGE_URL="Painga /URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Target bezoekers die browsen op specifieke menu-items of URL's" NR_ASSIGN_GROUP_DATETIME_DESC="Activeer een box op basis van de datum en tijd van uw server" NR_ASSIGN_GROUP_USER_VISITOR="Joomla Gebuiker / Bezoeker" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" NR_ASSIGN_GROUP_PLATFORM="Bezoekersplatform" NR_ASSIGN_GROUP_PLATFORM_DESC="Target bezoekers die Mobile, Google Chrome of zelfs Windows gebruiken" NR_ASSIGN_GROUP_GEO_DESC="Target bezoekers die fysiek in een specifieke regio zijn" NR_ASSIGN_GROUP_JCONTENT="Joomla! Inhoud" NR_ASSIGN_GROUP_JCONTENT_DESC="Target bezoekers die specifieke Joomla-artikelen of -categorieën bekijken" NR_ASSIGN_GROUP_SYSTEM="Systeem / Integraties" ; NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Target bezoekers die interactie hebben gehad met specifieke externe Joomla-extensies" NR_ASSIGN_GROUP_ADVANCED="Geavanceerde doelgerichtheid van bezoekers" NR_ASSIGN_USERGROUP_DESC="Target specifieke Joomla gebruikersgroepen" NR_ASSIGN_ARTICLE_DESC="Target bezoekers die specifieke Joomla-artikelen bekijken" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target bezoekers die specifieke Joomla-categorieën bekijken" NR_EXTENSION_REQUIRED="%scomponent vereist%s plugin om ingeschakeld te worden om goed te kunnen functioneren." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Target bezoekers die specifieke K2-items, categorieën of tags doorzoeken" NR_ASSIGN_K2_ITEMS="Item" NR_ASSIGN_K2_ITEMS_DESC="Target bezoekers die specifieke K2-items bekijken." NR_ASSIGN_K2_ITEMS_LIST_DESC="Selecteer de K2-items waaraan u wilt toewijzen" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Overeenkomen met specifieke zoekwoorden in de inhoud van het item. Gescheiden door een komma of een nieuwe regel." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Overeenkomen met de meta-trefwoorden van het item. Gescheiden door een komma of een nieuwe regel." NR_ASSIGN_K2_PAGETYPES_DESC="Target bezoekers die specifieke K2-paginatypen doorbladeren" NR_ASSIGN_K2_ITEM_OPTION="Item" NR_ASSIGN_K2_LATEST_OPTION="Laatste items van gebruikers of categorieën" NR_ASSIGN_K2_TAG_OPTION="Tag Pagina" NR_ASSIGN_K2_CATEGORY_OPTION="Categorie Pagina" NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Bewerk Formulier" NR_ASSIGN_K2_USER_PAGE_OPTION="Gebruikers Pagina (blog)" NR_ASSIGN_K2_TAGS_DESC="Target bezoekers die K2-items bekijken met specifieke tags" NR_ASSIGN_K2_CATEGORIES_DESC="Target bezoekers die in specifieke K2-categorieën browsen" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categorieën" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" NR_ASSIGN_PAGE_TYPES_DESC="Selecteer de paginatypes waaraan u wilt toewijzen" NR_ASSIGN_TAGS_DESC="Selecteer de labels die u wilt toewijzen" NR_CONTENT_KEYWORDS="Inhoudszoekwoorden" NR_META_KEYWORDS="Meta-trefwoorden" NR_TAG="Tag" NR_NORMAL="Normaal" NR_COMPACT="Compact" NR_LIGHT="Licht" NR_DARK="Donker" NR_SIZE="Grootte" NR_THEME="Thema" NR_SINGLE="Enkele" NR_MULTIPLE="Meerdere" NR_RANGE="Bereik" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Aub Controleren" NR_RECAPTCHA_INVALID_SECRET_KEY="Ongeldige Geheime Sleutel" NR_PAGE="Pagina" NR_YOU_ARE_USING_EXTENSION="U gebruikt %s%s" NR_UPDATE="Bijwerken" NR_SHOW_UPDATE_NOTIFICATION="Toon updatemelding" NR_SHOW_UPDATE_NOTIFICATION_DESC="Indien geselecteerd, wordt een updatemelding weergegeven in de hoofdcomponentweergave wanneer er een nieuwe versie voor deze extensie is." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%sis beschikbaar" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK! ouLLBsystem/nrframework/language/uk-UA/uk-UA.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Фреймворк 'Novarain Framework' використовується розширеннями, що випускаються веб-сайтом Tassos.gr" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ігнорувати" NR_INCLUDE="Включити" NR_EXCLUDE="Виключити" NR_SELECTION="Вибір" NR_ASSIGN_MENU_NOITEM="Не включати ID номер" NR_ASSIGN_MENU_NOITEM_DESC="Призначити також коли в URL посиланням відсутня ID номер меню?" NR_ASSIGN_MENU_CHILD="Також для дочірніх елементів" NR_ASSIGN_MENU_CHILD_DESC="Призначити також для дочірніх елементів вибраних елементів?" NR_COPY_OF="Копія %s" NR_ASSIGN_DATETIME_DESC="Визначити відвідувачів на основі часу вашого сервера" NR_DATETIME="Дата" NR_TIME="Час" NR_DATE="Дата" NR_DATETIME_DESC="Введіть дату автоматичної публікації / автоматичного зняття з публікації" NR_START_PUBLISHING="Дата та час початку" NR_START_PUBLISHING_DESC="Введіть дату початку публікації" NR_FINISH_PUBLISHING="Час закінчення" NR_FINISH_PUBLISHING_DESC="Введіть дату зняття з публікації" NR_DATETIME_NOTE="Дата і час використовують дані вашого сервера, а не ваших користувачів." NR_ASSIGN_PHP="ПХП" NR_PHPCODE="Код ПХП" NR_ASSIGN_PHP_DESC="Введіть фрагмент коду PHP для оцінки." NR_ASSIGN_PHP_DESC2="Показати відвідувачів на базі користувацького PHP-коду. Код повинен повернути значення true або false.

Наприклад:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Час на сайті" NR_SECONDS="Секунди" NR_ASSIGN_TIMEONSITE_DESC="Введіть час в секундах, щоб порівняти загальний час користувача (Час відвідування) витраченого на весь сайт.

Приклад:
Якщо ви хочете відобразити вікно після того, як користувач витратив 3 хвилини на вашому сайті, введіть 180. " NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Показати відвідувачів, які переглядають конкретні URL-адреси" NR_ASSIGN_URLS_DESC="Введіть URL (або його частина) для порівняння.
Використовуйте новий рядок для кожного окремого елемента." NR_ASSIGN_URLS_LIST="URL збіги" NR_ASSIGN_URLS_REGEX="Використовувати регулярне вираження" NR_ASSIGN_URLS_REGEX_DESC="Виберіть значення, як регулярний вираз." NR_ASSIGN_LANGS="Мова" NR_ASSIGN_LANGS_DESC="Показати відвідувачів, які переглядають ваш веб-сайт певною мовою" NR_ASSIGN_LANGS_LIST_DESC="Виберіть мови" NR_ASSIGN_DEVICES="Пристрої" NR_ASSIGN_DEVICES_DESC2="Показати відвідувачів, які переглядають ваш веб-сайт на конкретному пристрої" NR_ASSIGN_DEVICES_DESC="Виберіть пристрої" NR_ASSIGN_DEVICES_NOTE="Майте на увазі, що виявлення пристроїв не завжди на 100% точний. Користувачі можуть налаштувати їх браузер, щоб імітувати інші пристрої." NR_MENU="Меню" NR_MENU_ITEMS="Пункт меню" NR_MENU_ITEMS_DESC="Показати відвідувачів, які переглядають конкретні пункти меню" NR_USERGROUP="Группа користувачів" NR_ACCESSLEVEL="Рівень доступу группи користувачів" NR_ACCESSLEVEL_DESC="Призначте групи користувачів.

Примітка: Якщо хочете зробити публічним встановіть параметр Ігнорувати і не встановлюйте Public." NR_SHOW_COPYRIGHT="Показати копірайт" NR_SHOW_COPYRIGHT_DESC="Якщо вкл, додаткова інформація авторських прав буде відображатися в уявленнях адміністратора. Розширення Tassos.gr ніколи не відображають авторські права або зворотні посилання на сайті." NR_WIDTH="Ширина" NR_WIDTH_DESC="Вкажіть ширину в px, em або %

Приклад: 400px" NR_HEIGHT="Висота" NR_HEIGHT_DESC="Вкажіть висоту в px, em або %

Приклад: 400px" NR_PADDING="Відступ" NR_PADDING_DESC="Вкажіть відступ в px, em або %

Приклад: 20px" NR_MARGIN="Відступ" NR_MARGIN_DESC="Властивість поля CSS використовується для генерування простору навколо поля та встановлення розміру пробілу поза межами кордону в пікселях або в %.

Example 1: 25px
Example 2: 5%

Specifying the margin for each side [top right bottom left]:

Top side only: 25px 0 0 0
Right side only: 0 25px 0 0
Bottom side only: 0 0 25px 0
Left side only: 0 0 0 25px" NR_COLOR_HOVER="Колір при наведенні курсору" NR_COLOR="Колір" NR_COLOR_DESC="Введіть колір в форматах HEX або RGBA" NR_TEXT_COLOR="Колір тексту" NR_BACKGROUND="Фон" NR_BACKGROUND_COLOR="Колір фону" NR_BACKGROUND_COLOR_DESC="Вкажіть колір фону в форматах HEX або RGBA. Щоб відключити вкажіть"_QQ_" _QQ_ "_QQ_"Ні"_QQ_" _QQ_ "_QQ_". Для абсолютної прозорості введіть"_QQ_" _QQ_ "_QQ_"прозоро"_QQ_" _QQ_ "_QQ_"." NR_URL_SHORTENING_FAILED="Не вдалося скоротити %s з %s.%s." NR_EXPORT="Експорт" NR_IMPORT="Імпорт" NR_PLEASE_CHOOSE_A_VALID_FILE="Будь ласка, виберіть коректне ім'я файлу" NR_IMPORT_ITEMS="Імпорт елементів" NR_PUBLISH_ITEMS="Публікація елементів" NR_AS_EXPORTED="Як експортовано" NR_TITLE="Назва" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="Лист AcyMailing" NR_ACYMAILING_LIST_DESC="Вибрати списки AcyMailing, які слід призначити." NR_ASSIGN_ACYMAILING_DESC="Показати відвідувачів, які підписалися на відповідні листи АcyMailing" NR_AKEEBASUBS="Підписка Akeeba" NR_AKEEBASUBS_LEVELS="Рівні" NR_AKEEBASUBS_LEVELS_DESC="Вибрати рівні підписки які слід призначити" NR_ASSIGN_AKEEBASUBS_DESC="Показати відвідувачів, які підписалися на відповідні рівні підписки Akeeba Subscriptions" NR_MATCH="Порівняти" NR_MATCH_DESC="Використовуваний метод зіставлення для порівняння значення" NR_ASSIGN_MATCHING_METHOD="Метод збігу" NR_ASSIGN_MATCHING_METHOD_DESC="Чи повинні всі призначення збігатися ??

Все
Буде опубліковано якщо всі призначення нижче збігаються.
< br /> Будь-який
буде опубліковано якщо будь- (одне або більше) з призначень нижче збігаються.
Призначені групи 'Ignore' будуть проігноровані. " NR_ANY="Будь" NR_ASSIGN_REFERRER="URL-адреса пересилання" NR_ASSIGN_REFERRER_DESC2="Націлити відвідувачів, які приземляються на ваш сайт із певного джерела трафіку" NR_ASSIGN_REFERRER_DESC="Введіть одну URL-адресу переліку на рядок: Наприклад:

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Майте на увазі, що виявлення URL-адреса не завжди є 100% точним. Деякі сервери можуть використовувати проксі-сервери, які знімають цю інформацію, і її можна легко підробляти."_QQ_"NR_PROFEATURE_HEADER="_QQ_"%s is a PRO Feature" NR_PROFEATURE_HEADER="%sце PRO функція" NR_PROFEATURE_DESC="Вибачте, це %s недоступно в вашій версії. Будь ласка змініть вашу підписку на ПРО щоби розблокувати ці дивовижні функції" NR_PROFEATURE_DISCOUNT="Бонус: %s користувачы отримують 20% знижки автоматично при оплаті." NR_ONLY_AVAILABLE_IN_PRO="Доступно тільки у версії PRO" NR_UPGRADE_TO_PRO="Оновити до PRO" NR_UPGRADE_TO_PRO_TO_UNLOCK="Оновитися до версії Pro" NR_UPGRADE_TO_PRO_VERSION="Дивовижно! Залишився лише один крок Натисніть кнопку нижче, щоб завершити оновлення до версії Pro." NR_UNLOCK_PRO_FEATURE="Розблокувати функції ПРО" NR_USING_THE_FREE_VERSION="Ви використовуєте БЕЗКОШТОВУ версію Convert Forms. Придбайте PRO версію для повного функціоналу " NR_LEFT_TO_RIGHT="Зліва направо" NR_RIGHT_TO_LEFT="Справа наліво" NR_BGIMAGE="Зображення фону" NR_BGIMAGE_DESC="Встановити зображення фону" NR_BGIMAGE_FILE="Зображення" NR_BGIMAGE_FILE_DESC="Виберіть або завантажте файл, в якості фону." NR_BGIMAGE_REPEAT="Повтор" NR_BGIMAGE_REPEAT_DESC="Повтор фону встановлює, режим, в якому фотов зображення буде повторюватися. За замовчуванням, фонове зображення повторюється як по вертикалі, так і по горизонталі.

Повтор: Фонове зображення повторюється як по вертикалі, так і по горизонталі .

Повтор-x: Фонове зображення повторюється по горизонталі

Повтор-y: Фонове зображення повторюється по вертикалі

Ні-повтору: Повтор зображення відключений. " NR_BGIMAGE_SIZE="Розмір" NR_BGIMAGE_SIZE_DESC="Вкажіть розмір фонового зображення.

Авто: Фонове зображення містить власні ширину і висоту

Обкладинка: Масштабує фонове зображення на максимальний розмір, щоб покрити фонове простір

Контейнер: масштабує зображення таким чином, що його ширина і висота його може поміститися усередині області вмісту

100% 100%: Розтягує фонове зображення, щоб повністю покрити область контенту. " NR_BGIMAGE_POSITION="Позиція" NR_BGIMAGE_POSITION_DESC="Властивість background-position задає початкове положення зображення. За умолачнію розміщується зверху-ліворуч. Перше значення для горизонтального позиціонування, друге для вертикального

Ви можете використовувати одне із зумовлених значень, або введіть значення у відсотках: x% y% або в пікселях xPos yPos. " NR_RTL="Включити RTL" NR_RTL_DESC="Напрямок тексту справа наліво має важливе значення для таких мов як арабська, іврит, сирійський і тд." NR_HORIZONTAL="Горизонтально" NR_VERTICAL="Вертикально" NR_FORM_ORIENTATION="Орієнтація форми" NR_FORM_ORIENTATION_DESC="Виберіть орієнтацію форми" NR_ASSIGN_CATEGORY="Категорії" NR_ASSIGN_CATEGORY_DESC="Виберіть категорії" NR_ASSIGN_CATEGORY_CHILD="Також для дочірніх елементів" NR_ASSIGN_CATEGORY_CHILD_DESC="Також призначити виділені елементи до дочірнім?" NR_NEW="Новий" NR_LIST="Список" NR_DOCUMENTATION="Документація" NR_KNOWLEDGEBASE="База знань" NR_FAQ="FAQ" NR_INFORMATION="Інформація" NR_EXTENSION="Розширення" NR_VERSION="Версія" NR_CHANGELOG="Що нового" ; NR_DOWNLOAD="Download" NR_DOWNLOAD_KEY_MISSING="Ключ для завантаження відсутній" NR_DOWNLOAD_KEY="Ключ" NR_DOWNLOAD_KEY_DESC="Щоб знайти ключ завантаження, увійдіть у свій обліковий запис на Tassos.gr і перейдіть до розділу Завантаження.

Примітка: Встановивши тут ключ завантаження, не оновлюються безкоштовні версії до версій Pro. Щоб розблокувати функції Pro, вам також потрібно встановити версію Pro над безкоштовною версією." NR_DOWNLOAD_KEY_HOW="Для того, щоб компонент оновлювався разом з Joomla updater, потрібно ввести Ключ в налаштуваннях Novarain Framework Plugin." NR_DOWNLOAD_KEY_FIND="Знайти ключ" NR_DOWNLOAD_KEY_UPDATE="Оновити ключ" NR_OK="Ок" NR_MISSING="Не знайдено" NR_LICENSE="Ліцензія" NR_AUTHOR="Автор" NR_FOLLOWME="Підписатися" NR_FOLLOW="Підписатися на %s" NR_TRANSLATE_INTEREST="Чи зацікавлені в допомозі з перекладом %s на свою мову?" NR_TRANSIFEX_REQUEST="Надішліть мені запит на Transifex" NR_HELP_WITH_TRANSLATIONS="Допомога з перекладами" NR_PUBLISHING_ASSIGNMENTS="Прив'язка публікації" NR_ADVANCED="Розширені" NR_USEGLOBAL="За замовчуванням" NR_WEEKDAY="День тижня" NR_MONTH="Місяць" NR_MONDAY="Понеділок" NR_TUESDAY="Вівторок" NR_WEDNESDAY="Середа" NR_THURSDAY="Четвер" NR_FRIDAY="П'ятниця" NR_SATURDAY="Субота" NR_WEEKEND="Вихідні дні" NR_WEEKDAYS="Будні" NR_SUNDAY="Неділя" NR_JANUARY="Січень" NR_FEBRUARY="Лютий" NR_MARCH="Березень" NR_APRIL="Квітень" NR_MAY="Травень" NR_JUNE="Червень" NR_JULY="Липень" NR_AUGUST="Серпень" NR_SEPTEMBER="Вересень" NR_OCTOBER="Жовтень" NR_NOVEMBER="Листопад" NR_DECEMBER="Грудень" NR_NEVER="Ніколи" NR_SECONDS="Секунди" NR_MINUTES="Хвилин" NR_HOURS="Часів" NR_DAYS="Днів" NR_SESSION="Сесія" NR_EVER="Коли-небудь" NR_COOKIE="Кукі" NR_BOTH="Обидва" NR_NONE="Ні" NR_DESKTOPS="Настільний компьютер" NR_MOBILES="Мобільний пристрій" NR_TABLETS="Таблет" NR_PER_SESSION="Раз в сесію" NR_PER_DAY="Кожен день" NR_PER_WEEK="Раз на тиждень" NR_PER_MONTH="Раз на місяць" NR_FOREVER="Завжди" NR_FEATURE_UNDER_DEV="Ця опція в стадії розробки" NR_LIKE_THIS_EXTENSION="Подобається це розширення?" NR_LEAVE_A_REVIEW="Залишити відгук на JED" NR_SUPPORT="Підтримка" NR_NEED_SUPPORT="Потрібна підтримка?" NR_DROP_EMAIL="Напишіть мені по електронній пошті" NR_READ_DOCUMENTATION="Читати документацію" NR_COPYRIGHT="%s - Tassos.gr - Всі права захищені" NR_DASHBOARD="Панель" NR_NAME="Ім'я" NR_WRONG_COORDINATES="Надані координати некоректні" NR_ENTER_COORDINATES="Широта, Довгота" NR_NO_ITEMS_FOUND="Елементи не знайдені" NR_ITEM_IDS="Ні ID елементів" NR_TOGGLE="Переключитися" NR_EXPAND="Розгорнути" NR_COLLAPSE="Згорнути" NR_SELECTED="Вибрані" NR_MAXIMIZE="Максимізувати" NR_MINIMIZE="Мнімізіровать" NR_SELECTION="Вибір" NR_INSTALL="Установка" NR_INSTALL_NOW="Встановити зараз" NR_INSTALLED="Установлено" NR_COMING_SOON="Скоро ..." NR_ROADMAP="Заплановано" NR_MEDIA_VERSIONING="Використовувати версії медіа" NR_MEDIA_VERSIONING_DESC="Виберіть, щоб додати додатковий номер версії до кінця носія (JS / CSS) URL-адрес, щоб змусити браузери завантажувати правильний файл." NR_LOAD_JQUERY="Завантаження jQuery" NR_LOAD_JQUERY_DESC="Виберіть завантаження ядра JQuery скрипт. Ви можете відключити цю функцію, якщо у вас є конфлікти, або якщо ваш шаблон або інші розширення завантажують власну версію JQuery." NR_SELECT_CURRENCY="Виберіть валюту" NR_CONVERTFORMS="Форми" NR_CONVERTFORMS_LIST="Кампанія" NR_ASSIGN_CONVERTFORMS_DESC="Показати відвідувачів які підписалися на відповідну кампанію форм" NR_CONVERTFORMS_LIST_DESC="Виберіть кампанії ConvertForms, які потрібно призначити." NR_LEFT="Ліво" NR_CENTER="Центр" NR_RIGHT="Право" NR_BOTTOM="Низ" NR_TOP="Верх" NR_AUTO="Авто" NR_CUSTOM="Спеціальне" NR_UPLOAD="Завантаження" NR_IMAGE="Зображення" NR_INTRO_IMAGE="Вступне зображення" NR_FULL_IMAGE="Повне зображення" NR_IMAGE_SELECT="Вибрати зображення" NR_IMAGE_SIZE_COVER="Обкладинка" NR_IMAGE_SIZE_CONTAIN="Містить" NR_REPEAT="Повторювати" NR_REPEAT_X="Повторювати по X" NR_REPEAT_Y="Повторювати по Y" NR_REPEAT_NO="Не повторювати" NR_FIELD_STATE_DESC="Встановити стан елемента" NR_CREATED_DATE="Дата створення" NR_CREATED_DATE_DESC="Дата створення елемента" NR_MODIFIFED_DATE="Дата зміни" NR_MODIFIFED_DATE_DESC="Дата зміни елемента" NR_CATEGORIES="Категорія" NR_CATEGORIES_DESC="Виберіть категорії, яким слід призначити." NR_ALSO_ON_CHILD_ITEMS="Також дочірні елементи" NR_ALSO_ON_CHILD_ITEMS_DESC="Також призначити для дочірніх елементів вибрані елементи?" NR_PAGE_TYPE="Тип сторінки" NR_PAGE_TYPES="Типи сторінок" NR_PAGE_TYPES_DESC="Виберіть, на яких типах сторінок призначення має бути активним." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" NR_ARTICLE_VIEW_DESC="Увімкнути для врахування перегляду статті" NR_CATEGORY_VIEW="Перегляд категорії" NR_CATEGORY_VIEW_DESC="Увімкнути для врахування перегляду категорії" NR_ARTICLES="Статті" NR_ARTICLES_DESC="Виберіть статті для присвоєння." NR_ARTICLE="Стаття" NR_ARTICLE_AUTHORS="Автори" NR_ARTICLE_AUTHORS_DESC="Виберіть авторів для присвоєння." NR_ONLY="Тільки" NR_OTHERS="Інші" NR_SMARTTAGS="Розумні теги" NR_SMARTTAGS_SHOW="Показати розумні теги" NR_SMARTTAGS_NOTFOUND="Не знайдено смарт-тегів" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Пошук розумних тегів" NR_CONTACT_US="Зв'яжіться з нами" NR_FONT_COLOR="Колір шрифту" NR_FONT_SIZE="Розмір шрифту" NR_FONT_SIZE_DESC="Виберіть розмір шрифту в пікселях" NR_TEXT="Текст" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Увімкнути переосмислення виводу" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Вмикає візуалізацію розширення, коли перекривається макет сторінки (tmpl). Приклади: tmpl = компонент або tmpl = модально." NR_EXECUTE_ON_FORMAT_OVERRIDE="Увімкнути при перезапис формату" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Вмикає візуалізацію розширення, коли формат сторінки не відрізняється від HTML. Приклади: format = raw або format = json." NR_GEOLOCATING="Геолокація" NR_GEOLOCATING_DESC="Геолокація не завжди на 100% точна. Геолокація заснована на IP-адресі відвідувача. Не всі IP-адреси є фіксованими або відомими." NR_CITY="Місто" NR_CITY_NAME="Назва міста" NR_CONDITION_CITY_DESC="Введіть назву міста англійською мовою. Введіть кілька міст, розділених комою." NR_CONTINENT="Континент" NR_REGION="Регіон" NR_CONDITION_REGION_DESC="Значення складається з двох частин, двох літер ISO 3166-1 код країни та коду регіону. Значення має бути у такій формі: COUNTRY_CODE-REGION_CODE. Для повного списку кодів регіонів натисніть на Знайти Посилання коду регіону. " NR_ASSIGN_COUNTRIES="Країна" NR_ASSIGN_COUNTRIES_DESC2="Показати відвідувачів, які фізично перебувають у певній країні" NR_ASSIGN_COUNTRIES_DESC="Виберіть країни, які потрібно призначити" NR_ASSIGN_CONTINENTS="Континент" NR_ASSIGN_CONTINENTS_DESC="Виберіть континенти для призначення" NR_ASSIGN_CONTINENTS_DESC2="Показати відвідувачів, які перебувають фізично на певному континенті" NR_ICONTACT_ACCOUNTID_ERROR="Не вдалося отримати ідентифікатор акаунта iContact" NR_TAG_CLIENTDEVICE="Тип пристрою відвідувачів" NR_TAG_CLIENTOS="Операційна система відвідувачів" NR_TAG_CLIENTBROWSER="Переглядач відвідувачів" NR_TAG_CLIENTUSERAGENT="Рядок відвідувачого агента" NR_TAG_IP="IP-адреса відвідувача" NR_TAG_URL="URL-адреса сторінки" NR_TAG_URLENCODED="Кодована URL-адреса сторінки" NR_TAG_URLPATH="Шлях до сторінки" NR_TAG_REFERRER="Посилання на сторінку" NR_TAG_SITENAME="Назва сайту" NR_TAG_SITEURL="URL-адреса сайту" NR_TAG_PAGETITLE="Заголовок сторінки" NR_TAG_PAGEDESC="Мета опису сторінки" NR_TAG_PAGELANG="Код мови сторінки" NR_TAG_USERID="Ідентифікатор користувача" NR_TAG_USERNAME="Повне ім'я користувача" NR_TAG_USERLOGIN="Вхід користувача" NR_TAG_USEREMAIL="Електронна пошта користувача" NR_TAG_USERFIRSTNAME="Ім'я користувача" NR_TAG_USERLASTNAME="Прізвище користувача" NR_TAG_USERGROUPS="Ідентифікатори груп користувачів" NR_TAG_DATE="Дата" NR_TAG_TIME="Час" NR_TAG_RANDOMID="Випадковий ідентифікатор" NR_ICON="Ікона" NR_SELECT_MODULE="Вибір модуля" NR_SELECT_CONTINENT="Вибрати континент" NR_SELECT_COUNTRY="Вибрати країну" NR_PLUGIN="Плагін" NR_GMAP_KEY="Ключ API Карт Google" NR_GMAP_KEY_DESC="Ключ API Карт Google використовується розширеннями Tassos.gr. Якщо у вас виникли проблеми із завантаженням карти Google, вам, можливо, потрібно ввести власний ключ API." NR_GMAP_FIND_KEY="Отримати ключ API" NR_ARE_YOU_SURE="Ви впевнені?" NR_CUSTOMURL="Спеціальна URL-адреса" NR_SAMPLE="Зразок" NR_DEBUG="Налагодження" NR_CUSTOMURL="Спеціальна URL-адреса" NR_READMORE="Детальніше" NR_IPADDRESS="IP-адреса" NR_ASSIGN_BROWSERS="Веб-переглядач" NR_ASSIGN_BROWSERS_DESC="Виберіть браузери, які потрібно призначити" NR_ASSIGN_BROWSERS_DESC2="Націлити відвідувачів, які переглядають ваш сайт за допомогою конкретних браузерів, таких як Chrome, Firefox або Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Край" NR_IE="Internet Explorer" NR_SAFARI="Сафарі" NR_OPERA="Опера" NR_ASSIGN_OS="Операційна система" NR_ASSIGN_OS_DESC="Виберіть операційні системи для призначення" NR_ASSIGN_OS_DESC2="Націлити відвідувачів, які використовують певні операційні системи, такі як Windows, Linux або Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Кількість переглядів сторінки" NR_ASSIGN_PAGEVIEWS_DESC="Націлити відвідувачів, які переглянули певну кількість сторінок" NR_ASSIGN_PAGEVIEWS_VIEWS="Перегляд сторінки" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Введіть кількість переглядів сторінки" NR_ASSIGN_COOKIENAME_NAME="Ім'я файлу cookie" NR_ASSIGN_COOKIENAME_NAME_DESC="Введіть ім'я файлу cookie, яке потрібно призначити" NR_ASSIGN_COOKIENAME_NAME_DESC2="Націлити відвідувачів, які зберігають певні файли cookie у своєму браузері" NR_FEWER_THAN="Менше ніж" NR_GREATER_THAN="Більше" NR_EXACTLY="Точно" NR_EXISTS="Існує" NR_IS_EQUAL="Дорівнює" NR_CONTAINS="Містить" NR_STARTS_WITH="Починається з" NR_ENDS_WITH="Закінчується на" NR_ASSIGN_COOKIENAME_CONTENT="Вміст файлів cookie" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Вміст файлу cookie" NR_ASSIGN_IP_ADDRESSES_DESC2="Націлити відвідувачів, які стоять за певною IP-адресою (діапазоном)" NR_ASSIGN_IP_ADDRESSES_DESC="Введіть список знаків із комою та / або"_QQ_" введіть "_QQ_"розділені IP-адреси та діапазони

Приклад:
127.0.0.1,
192.10-120.2,
168 " NR_ASSIGN_USER_ID="Ідентифікатор користувача" NR_ASSIGN_USER_ID_DESC="Націлити конкретних користувачів Joomla за їх ідентифікаторами" NR_ASSIGN_USER_ID_SELECTION_DESC="Введіть розділені комами ідентифікатори користувача Joomla" NR_ASSIGN_COMPONENTS="Компонент" NR_ASSIGN_COMPONENTS_DESC="Виберіть компоненти, які потрібно призначити" NR_ASSIGN_COMPONENTS_DESC2="Націлити відвідувачів, які переглядають конкретні компоненти" NR_ASSIGN_TIMERANGE="Діапазон часу" NR_ASSIGN_TIMERANGE_DESC="Націлити відвідувачів залежно від часу вашого сервера" NR_START_TIME="Час початку" NR_END_TIME="Час закінчення" NR_START_PUBLISHING_TIMERANGE_DESC="Введіть час для початку публікації" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Введіть час для завершення публікації" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_DESC="Щоб отримати веб-сайт та секретний ключ для вашого домену, перейдіть на сторінку https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Ключ сайту" NR_RECAPTCHA_SITE_KEY_DESC="Використовується в коді JavaScript, який подається вашим користувачам." NR_RECAPTCHA_SECRET_KEY="Секретний ключ" NR_RECAPTCHA_SECRET_KEY_DESC="Використовується для зв'язку між вашим сервером та сервером reCAPTCHA. Не забудьте зберегти це в таємниці." NR_RECAPTCHA_SITE_KEY_ERROR="Ключ сайту reCaptcha відсутній або недійсний" NR_PREVIOUS_MONTH="Попередній місяць" NR_NEXT_MONTH="Наступний місяць" NR_ASSIGN_GROUP_PAGE_URL="Сторінка / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Націлити відвідувачів, які переглядають конкретні пункти меню чи URL-адреси" NR_ASSIGN_GROUP_DATETIME_DESC="Запустити вікно залежно від дати та часу вашого сервера" NR_ASSIGN_GROUP_USER_VISITOR="Користувач / відвідувач Joomla" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Націлити зареєстрованих користувачів або відвідувачів, які переглянули певну кількість сторінок" NR_ASSIGN_GROUP_PLATFORM="Платформа для відвідувачів" NR_ASSIGN_GROUP_PLATFORM_DESC="Націлити відвідувачів, які використовують мобільний, Google Chrome або навіть Windows" NR_ASSIGN_GROUP_GEO_DESC="Націлити відвідувачів, які фізично перебувають у певному регіоні" NR_ASSIGN_GROUP_JCONTENT="Joomla! Вміст" NR_ASSIGN_GROUP_JCONTENT_DESC="Націлити відвідувачів, які переглядають конкретні статті чи категорії Joomla" NR_ASSIGN_GROUP_SYSTEM="Система / Інтеграції" NR_ASSIGN_GROUP_SYSTEM_DESC="Націлити відвідувачів, які взаємодіяли з певними сторонніми розширеннями Joomla" NR_ASSIGN_GROUP_ADVANCED="Розширене націлювання на відвідувачів" NR_ASSIGN_USERGROUP_DESC="Цільова група користувачів Joomla" NR_ASSIGN_ARTICLE_DESC="Націлити відвідувачів, які переглядають конкретні статті Joomla" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Націлити відвідувачів, які переглядають конкретні категорії Joomla" NR_EXTENSION_REQUIRED="Для забезпечення нормальної роботи компонента %s потрібно включити плагін %s." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Націлити відвідувачів, які переглядають певні елементи, категорії або теги K2" NR_ASSIGN_K2_ITEMS="Елемент" NR_ASSIGN_K2_ITEMS_DESC="Націлити відвідувачів, які переглядають конкретні елементи K2." NR_ASSIGN_K2_ITEMS_LIST_DESC="Виберіть елементи K2 для призначення" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Збіг за певними ключовими словами у вмісті елемента. Відокремте комою чи новим рядком." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Збіг мета-ключових слів елемента. Відокремте комою або новим рядком." NR_ASSIGN_K2_PAGETYPES_DESC="Націлити відвідувачів, які переглядають конкретні типи сторінок K2" NR_ASSIGN_K2_ITEM_OPTION="Елемент" NR_ASSIGN_K2_LATEST_OPTION="Останні елементи користувачів або категорій" NR_ASSIGN_K2_TAG_OPTION="Сторінка тегів" NR_ASSIGN_K2_CATEGORY_OPTION="Сторінка категорії" NR_ASSIGN_K2_ITEM_FORM_OPTION="Форма редагування елемента" NR_ASSIGN_K2_USER_PAGE_OPTION="Сторінка користувача (блог)" NR_ASSIGN_K2_TAGS_DESC="Націлити відвідувачів, які переглядають елементи K2 із конкретними тегами" NR_ASSIGN_K2_CATEGORIES_DESC="Націлити відвідувачів, які переглядають конкретні категорії K2" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Категорії" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Елементи" NR_ASSIGN_PAGE_TYPES_DESC="Виберіть типи сторінок, які потрібно призначити" NR_ASSIGN_TAGS_DESC="Виберіть теги, які потрібно призначити" NR_CONTENT_KEYWORDS="Ключові слова вмісту" NR_META_KEYWORDS="Мета ключових слів" NR_TAG="Тег" NR_NORMAL="Нормальний" NR_COMPACT="Компактний" NR_LIGHT="Світло" NR_DARK="Темно" NR_SIZE="Розмір" NR_THEME="Тема" NR_SINGLE="Одномісний" NR_MULTIPLE="Кілька" NR_RANGE="Діапазон" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Будь ласка, підтвердіть" NR_RECAPTCHA_INVALID_SECRET_KEY="Недійсний секретний ключ" NR_PAGE="Сторінка" NR_YOU_ARE_USING_EXTENSION="Ви використовуєте %s %s" NR_UPDATE="Оновити" NR_SHOW_UPDATE_NOTIFICATION="Показати повідомлення про оновлення" NR_SHOW_UPDATE_NOTIFICATION_DESC="Якщо вибрано, сповіщення про оновлення відображатиметься у вікні головного компонента, коли є нова версія цього розширення." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s доступний" NR_ERROR_EMAIL_IS_DISABLED="Надсилання пошти вимкнено. Електронні листи не можна було надсилати." NR_ASSIGN_ITEMS="Елемент" NR_COUNTRY_AF="Афганістан" NR_COUNTRY_AX="Аландські острови" NR_COUNTRY_AL="Албанія" NR_COUNTRY_DZ="Алжир" NR_COUNTRY_AS="Американське Самоа" NR_COUNTRY_AD="Андорра" NR_COUNTRY_AO="Ангола" NR_COUNTRY_AI="Ангілья" NR_COUNTRY_AQ="Антарктида" NR_COUNTRY_AG="Антигуа і Барбуда" NR_COUNTRY_AR="Аргентина" NR_COUNTRY_AM="Вірменія" NR_COUNTRY_AW="Аруба" NR_COUNTRY_AU="Австралія" NR_COUNTRY_AT="Австрія" NR_COUNTRY_AZ="Азербайджан" NR_COUNTRY_BS="Багами" NR_COUNTRY_BH="Бахрейн" NR_COUNTRY_BD="Бангладеш" NR_COUNTRY_BB="Барбадос" NR_COUNTRY_BY="Білорусь" NR_COUNTRY_BE="Бельгія" NR_COUNTRY_BZ="Беліз" NR_COUNTRY_BJ="Бенін" NR_COUNTRY_BM="Бермуди" NR_COUNTRY_BT="Бутан" NR_COUNTRY_BO="Болівія" NR_COUNTRY_BA="Боснія та Герцеговина" NR_COUNTRY_BW="Ботсвана" NR_COUNTRY_BV="Острів Буве" NR_COUNTRY_BR="Бразилія" NR_COUNTRY_IO="Британська територія Індійського океану" NR_COUNTRY_BN="Бруней Даруссалам" NR_COUNTRY_BG="Болгарія" NR_COUNTRY_BF="Буркіна-Фасо" NR_COUNTRY_BI="Бурунді" NR_COUNTRY_KH="Камбоджа" NR_COUNTRY_CM="Камерун" NR_COUNTRY_CA="Канада" NR_COUNTRY_CV="Кабо-Верде" NR_COUNTRY_KY="Кайманові острови" NR_COUNTRY_CF="Центральноафриканська республіка" NR_COUNTRY_TD="Чад" NR_COUNTRY_CL="Чилі" NR_COUNTRY_CN="Китай" NR_COUNTRY_CX="Острів Різдва" NR_COUNTRY_CC="Кокосові (Кілінгські) острови" NR_COUNTRY_CO="Колумбія" NR_COUNTRY_KM="Коморські острови" NR_COUNTRY_CG="Конго" NR_COUNTRY_CD="Конго, Демократична Республіка" NR_COUNTRY_CK="Острови Кука" NR_COUNTRY_CR="Коста-Ріка" NR_COUNTRY_CI="Кот-д'Івуар" NR_COUNTRY_HR="Хорватія" NR_COUNTRY_CU="Куба" ; NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Кіпр" NR_COUNTRY_CZ="Чехія" NR_COUNTRY_DK="Данія" NR_COUNTRY_DJ="Джибуті" NR_COUNTRY_DM="Домініка" NR_COUNTRY_DO="Домініканська Республіка" NR_COUNTRY_EC="Еквадор" NR_COUNTRY_EG="Єгипет" NR_COUNTRY_SV="Сальвадор" NR_COUNTRY_GQ="Екваторіальна Гвінея" NR_COUNTRY_ER="Еритрея" NR_COUNTRY_EE="Естонія" NR_COUNTRY_ET="Ефіопія" NR_COUNTRY_FK="Фолклендські острови (Мальвіни)" NR_COUNTRY_FO="Фарерські острови" NR_COUNTRY_FJ="Фіджі" NR_COUNTRY_FI="Фінляндія" NR_COUNTRY_FR="Франція" NR_COUNTRY_GF="Французька Гвіана" NR_COUNTRY_PF="Французька Полінезія" NR_COUNTRY_TF="Південні французькі території" NR_COUNTRY_GA="Габон" NR_COUNTRY_GM="Гамбія" NR_COUNTRY_GE="Грузія" NR_COUNTRY_DE="Німеччина" NR_COUNTRY_GH="Гана" NR_COUNTRY_GI="Гібралтар" NR_COUNTRY_GR="Греція" NR_COUNTRY_GL="Гренландія" NR_COUNTRY_GD="Гренада" NR_COUNTRY_GP="Гваделупа" NR_COUNTRY_GU="Гуам" NR_COUNTRY_GT="Гватемала" NR_COUNTRY_GG="Гернсі" NR_COUNTRY_GN="Гвінея" NR_COUNTRY_GW="Гвінея-Біссау" NR_COUNTRY_GY="Гайана" NR_COUNTRY_HT="Гаїті" NR_COUNTRY_HM="Острови Херда та Макдональд" NR_COUNTRY_VA="Святий Престол (місто Ватикан)" NR_COUNTRY_HN="Гондурас" NR_COUNTRY_HK="Гонконг" NR_COUNTRY_HU="Угорщина" NR_COUNTRY_IS="Ісландія" NR_COUNTRY_IN="Індія" NR_COUNTRY_ID="Індонезія" NR_COUNTRY_IR="Іран, Ісламська Республіка" NR_COUNTRY_IQ="Ірак" NR_COUNTRY_IE="Ірландія" NR_COUNTRY_IM="Острів Мен" NR_COUNTRY_IL="Ізраїль" NR_COUNTRY_IT="Італія" NR_COUNTRY_JM="Ямайка" NR_COUNTRY_JP="Японія" NR_COUNTRY_JE="Джерсі" NR_COUNTRY_JO="Йорданія" NR_COUNTRY_KZ="Казахстан" NR_COUNTRY_KE="Кенія" NR_COUNTRY_KI="Кірібаті" NR_COUNTRY_KP="Корея, Демократична Народна Республіка" NR_COUNTRY_KR="Корея, Республіка" NR_COUNTRY_KW="Кувейт" NR_COUNTRY_KG="Киргизстан" NR_COUNTRY_LA="Лаоська Народна Демократична Республіка" NR_COUNTRY_LV="Латвія" NR_COUNTRY_LB="Ліван" NR_COUNTRY_LS="Лесото" NR_COUNTRY_LR="Ліберія" NR_COUNTRY_LY="Лівійська арабська Джамахірія" NR_COUNTRY_LI="Ліхтенштейн" NR_COUNTRY_LT="Литва" NR_COUNTRY_LU="Люксембург" NR_COUNTRY_MO="Макао" NR_COUNTRY_MK="Македонія" NR_COUNTRY_MG="Мадагаскар" NR_COUNTRY_MW="Малаві" NR_COUNTRY_MY="Малайзія" NR_COUNTRY_MV="Мальдіви" NR_COUNTRY_ML="Малі" NR_COUNTRY_MT="Мальта" NR_COUNTRY_MH="Маршаллові острови" NR_COUNTRY_MQ="Мартиніка" NR_COUNTRY_MR="Мавританія" NR_COUNTRY_MU="Маврикій" NR_COUNTRY_YT="Майотта" NR_COUNTRY_MX="Мексика" NR_COUNTRY_FM="Мікронезія, федеративні держави" NR_COUNTRY_MD="Молдова, Республіка" NR_COUNTRY_MC="Монако" NR_COUNTRY_MN="Монголія" NR_COUNTRY_ME="Чорногорія" NR_COUNTRY_MS="Монтсеррат" NR_COUNTRY_MA="Марокко" NR_COUNTRY_MZ="Мозамбік" NR_COUNTRY_MM="М'янма" NR_COUNTRY_NA="Намібія" NR_COUNTRY_NR="Науру" NR_COUNTRY_NM="Північна Македонія" NR_COUNTRY_NP="Непал" NR_COUNTRY_NL="Нідерланди" NR_COUNTRY_AN="Нідерландські Антильські острови" NR_COUNTRY_NC="Нова Каледонія" NR_COUNTRY_NZ="Нова Зеландія" NR_COUNTRY_NI="Нікарагуа" NR_COUNTRY_NE="Нігер" NR_COUNTRY_NG="Нігерія" NR_COUNTRY_NU="Ніуе" NR_COUNTRY_NF="Острів Норфолк" NR_COUNTRY_MP="Північні Маріанські острови" NR_COUNTRY_NO="Норвегія" NR_COUNTRY_OM="Оман" NR_COUNTRY_PK="Пакистан" NR_COUNTRY_PW="Палау" NR_COUNTRY_PS="Палестинська територія" NR_COUNTRY_PA="Панама" NR_COUNTRY_PG="Папуа-Нова Гвінея" NR_COUNTRY_PY="Парагвай" NR_COUNTRY_PE="Перу" NR_COUNTRY_PH="Філіппіни" NR_COUNTRY_PN="Піткерн" NR_COUNTRY_PL="Польща" NR_COUNTRY_PT="Португалія" NR_COUNTRY_PR="Пуерто-Рико" NR_COUNTRY_QA="Катар" NR_COUNTRY_RE="Поєднання" NR_COUNTRY_RO="Румунія" NR_COUNTRY_RU="Російська Федерація" NR_COUNTRY_RW="Руанда" NR_COUNTRY_SH="Свята Єлена" NR_COUNTRY_KN="Сент-Кітс і Невіс" NR_COUNTRY_LC="Сент-Люсія" NR_COUNTRY_PM="Сен-П'єр і Мікелон" NR_COUNTRY_VC="Сент-Вінсент і Гренадини" NR_COUNTRY_WS="Самоа" NR_COUNTRY_SM="Сан-Марино" NR_COUNTRY_ST="Сан-Томе і Принсіпі" NR_COUNTRY_SA="Саудівська Аравія" NR_COUNTRY_SN="Сенегал" NR_COUNTRY_RS="Сербія" NR_COUNTRY_SC="Сейшельські острови" NR_COUNTRY_SL="Сьєрра-Леоне" NR_COUNTRY_SG="Сінгапур" NR_COUNTRY_SK="Словаччина" NR_COUNTRY_SI="Словенія" NR_COUNTRY_SB="Соломонові острови" NR_COUNTRY_SO="Сомалі" NR_COUNTRY_ZA="Південна Африка" NR_COUNTRY_GS="Південна Джорджія та Південні Сандвічеві острови" NR_COUNTRY_ES="Іспанія" NR_COUNTRY_LK="Шрі-Ланка" NR_COUNTRY_SD="Судан" NR_COUNTRY_SS="Південний Судан" NR_COUNTRY_SR="Суринам" NR_COUNTRY_SJ="Шпицберген та Ян Майен" NR_COUNTRY_SZ="Свазіленд" NR_COUNTRY_SE="Швеція" NR_COUNTRY_CH="Швейцарія" NR_COUNTRY_SY="Сирійська Арабська Республіка" NR_COUNTRY_TW="Тайвань" NR_COUNTRY_TJ="Таджикистан" NR_COUNTRY_TZ="Танзанія, Об'єднана Республіка" NR_COUNTRY_TH="Таїланд" NR_COUNTRY_TL="Тимор-Лешті" NR_COUNTRY_TG="Того" NR_COUNTRY_TK="Токелау" NR_COUNTRY_TO="Тонга" NR_COUNTRY_TT="Тринідад і Тобаго" NR_COUNTRY_TN="Туніс" NR_COUNTRY_TR="Туреччина" NR_COUNTRY_TM="Туркменістан" NR_COUNTRY_TC="Острови Теркс і Кайкос" NR_COUNTRY_TV="Тувалу" NR_COUNTRY_UG="Уганда" NR_COUNTRY_UA="Україна" NR_COUNTRY_AE="Об'єднані Арабські Емірати" NR_COUNTRY_GB="Великобританія" NR_COUNTRY_US="Сполучені Штати" NR_COUNTRY_UM="Малі віддалені острови США" NR_COUNTRY_UY="Уругвай" NR_COUNTRY_UZ="Узбекистан" NR_COUNTRY_VU="Вануату" NR_COUNTRY_VE="Венесуела" NR_COUNTRY_VN="В'єтнам" NR_COUNTRY_VG="Віргінські острови, Британські" NR_COUNTRY_VI="Віргінські острови, США." NR_COUNTRY_WF="Уолліс і Футуна" NR_COUNTRY_EH="Західна Сахара" NR_COUNTRY_YE="Ємен" NR_COUNTRY_ZM="Замбія" NR_COUNTRY_ZW="Зімбабве" NR_CONTINENT_AF="Африка" NR_CONTINENT_AS="Азія" NR_CONTINENT_EU="Європа" NR_CONTINENT_NA="Північна Америка" NR_CONTINENT_SA="Південна Америка" NR_CONTINENT_OC="Океанія" NR_CONTINENT_AN="Антарктида" NR_FRONTEND="Інтерфейс" NR_BACKEND="Адміністрація" NR_EMBED="Приставлено" NR_RATE="Тариф %s" NR_REPORT_ISSUE="Повідомте про проблему" NR_CANNOT_CREATE_FOLDER="Не вдається створити папку для переміщення файлу.%s" NR_CANNOT_MOVE_FILE="Не вдається перемістити файл: %s" NR_UPLOAD_INVALID_FILE_TYPE="Непідтримуваний файл: %s. Дозволеними типами файлів є:%s" NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Не вдається завантажити файл: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" PK!] Bsystem/nrframework/language/fr-FR/fr-FR.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="Système - Framework Novarain" PLG_SYSTEM_NRFRAMEWORK_DESC="Framework Novarain - utilisé par les extensions de Tassos.gr" NOVARAIN_FRAMEWORK="Framework Novarain" ; TRANSLATABLE NR_IGNORE="Ignorer" NR_INCLUDE="Inclure" NR_EXCLUDE="Exclure" NR_SELECTION="Sélection" NR_ASSIGN_MENU_NOITEM="Ne pas inclure d'élément ID" NR_ASSIGN_MENU_NOITEM_DESC="Assigner également lorsqu'il n'y a pas d'élément ID de menu de défini dans l'URL ?" NR_ASSIGN_MENU_CHILD="Également sur les éléments enfants" NR_ASSIGN_MENU_CHILD_DESC="Assigné aussi sur les éléments enfants de l'élément sélectionné ?" NR_COPY_OF="Copie de %s" NR_ASSIGN_DATETIME_DESC="Ciblez les visiteurs en fonction de l’horodatage de votre serveur" NR_DATETIME="Période" NR_TIME="Temps" NR_DATE="Date" NR_DATETIME_DESC="Définir la période pour auto publier/dé-publier" NR_START_PUBLISHING="Début de la période" NR_START_PUBLISHING_DESC="Spécifier la date de début de publication" NR_FINISH_PUBLISHING="Date et heure de fin" NR_FINISH_PUBLISHING_DESC="Spécifier la date de fin de publication" NR_DATETIME_NOTE="La date et l'heure définie utilisera la date et l'heure de votre serveur, pas celle du système de vos visiteurs." NR_ASSIGN_PHP="PHP" NR_PHPCODE="Code PHP" NR_ASSIGN_PHP_DESC="Entrez un morceau de code PHP à évaluer." NR_ASSIGN_PHP_DESC2="Ciblez les visiteurs qui testent un code PHP personnalisé. Le code doit retourner true ou false.

Par exemple :
retrun ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Heure sur le site" NR_SECONDS="Secondes" NR_ASSIGN_TIMEONSITE_DESC="Entrez une durée en seconde pour comparer avec le temps total de l'utilisateur passé sur l'ensemble de votre site (durée de visite).

Exemple :
Si vous voulez afficher une boîte après que l'utilisateur ai passé 3 minutes sur l'ensemble de votre site, entrez 180." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Cibler les visiteurs qui naviguent sur des URL spécifiques." NR_ASSIGN_URLS_DESC="Entrez (une partie) des URLs à comparer.
Utilisez une nouvelle ligne pour chaque comparaison." NR_ASSIGN_URLS_LIST="Correspondance d'URL" NR_ASSIGN_URLS_REGEX="Utiliser une expression régulière" NR_ASSIGN_URLS_REGEX_DESC="Sélectionnez pour traiter la valeur comme des expressions régulières." NR_ASSIGN_LANGS="Langage" NR_ASSIGN_LANGS_DESC="Ciblez les visiteurs qui naviguent sur votre site Web dans une langue spécifique." NR_ASSIGN_LANGS_LIST_DESC="Sélectionnez les langages à assigner" NR_ASSIGN_DEVICES="Appareil" NR_ASSIGN_DEVICES_DESC2="Ciblez les visiteurs utilisant des appareils spécifiques comme Mobile, Tablette ou Ordinateur." NR_ASSIGN_DEVICES_DESC="Sélectionnez les appareils à assigner" NR_ASSIGN_DEVICES_NOTE="Gardez en tête que la détection d'appareil n'est pas à 100% exacte. Les utilisateurs peuvent configurer leur navigateur pour imiter d'autres appareils." NR_MENU="Menu" NR_MENU_ITEMS="Élément du menu" NR_MENU_ITEMS_DESC="Ciblez les visiteurs qui naviguent avec des éléments de menu spéciaux" NR_USERGROUP="Groupe d'utilisateurs" NR_USERGROUP_DESC="Sélectionnez les groupes d'utilisateurs à affecter.

Note : Si vous voulez le rendre public, réglez-le sur Ignorer et ne sélectionnez pas l'option Public." NR_ACCESSLEVEL="Groupe d'utilisateur" NR_USERACCESSLEVEL="Niveau d'accès de l'utilisateur" NR_USERACCESSLEVEL_DESC="Sélectionnez les niveaux d'accès de visualisation de l'utilisateur à affecter." NR_SHOW_COPYRIGHT="Afficher le copyright" NR_SHOW_COPYRIGHT_DESC="Si selectionné, une supplément de copyright sera afficher sur la vue Admin. Les extensions Tassos.gr n'affichent jamais de copyright ou de liens externes sur le devant du site." NR_WIDTH="Largeur" NR_WIDTH_DESC="Entrez la largeur en px, em ou %

Exemple : 400px" NR_HEIGHT="Hauteur" NR_HEIGHT_DESC="Entrez la hauteur en px, em ou %

Exemple : 400px" NR_PADDING="Espacement" NR_PADDING_DESC="Entrez l'espacement en px, em ou %

Exemple : 20px" NR_MARGIN="Marge" NR_MARGIN_DESC="La propriété CSS de marge est utilisée pour générer un espace autour de la boîte et deféinir la taille de la bordure exterieur en pixels ou en %.

Exemple 1 : 25px
Exemple 2 : 5%

Spécifiez la marge de chaque coté [haut droite bas gauche] :

En haut seulement : 25px 0 0 0
A droite seulement : 0 25px 0 0
En bas seulement : 0 0 25px 0
A gauche seulement : 0 0 0 25px" NR_COLOR_HOVER="Couleur au survol" NR_COLOR="Couleur" NR_COLOR_DESC="Définissez une couleur au format HEX ou RGBA." NR_TEXT_COLOR="Couleur du texte" NR_BACKGROUND="Arrière-plan" NR_BACKGROUND_COLOR="Couleur de l'arrière-plan" NR_BACKGROUND_COLOR_DESC="Définir une couleur d'arrière plan au format HEX ou RGBA. Pour désactiver, entrez 'none'. Pour une transparence absolue, entrez 'transparent'." NR_URL_SHORTENING_FAILED="Erreur de la réduction de %s avec %s . %s." NR_EXPORT="Exporter" NR_IMPORT="Importer" NR_PLEASE_CHOOSE_A_VALID_FILE="Veuillez choisir un nom de fichier valide" NR_IMPORT_ITEMS="Importer des éléments" NR_PUBLISH_ITEMS="Publier des éléments" NR_AS_EXPORTED="Tel qu'exporté" NR_TITLE="Titre" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="AcyMailing List" NR_ACYMAILING_LIST_DESC="Sélectionnez les listes AcyMailing à assigner." NR_ASSIGN_ACYMAILING_DESC="Ciblez les visiteurs qui ont souscrit à des listes spécifiques AcyMailing" NR_AKEEBASUBS="Abonnements Akeeba" NR_AKEEBASUBS_LEVELS="Niveaux" NR_AKEEBASUBS_LEVELS_DESC="Sélectionnez les niveaux d'abonnements Akeeba à assigner." NR_ASSIGN_AKEEBASUBS_DESC="Ciblez les visiteurs qui ont souscrit à des abonnements Akeeba spécifiques" NR_MATCH="Comparer" NR_MATCH_DESC="La méthode de comparaison utilisé pour comparer la valeur" NR_ASSIGN_MATCHING_METHOD="Méthode de comparaison" NR_ASSIGN_MATCHING_METHOD_DESC="Doit-on tout comparer ou seulement certains éléments ?

Tous
Afficher si tous les éléments ci-dessous correspondent.

N'importe lequel
Afficher si n'importe lequel (un ou plusieurs) des éléments ci-dessous correspondent.
Les groupes d'éléments où 'Ignorer' est sélectionné seront ignorés." NR_ANY="N'importe lequel" NR_ALL="Tous" NR_ASSIGN_REFERRER="URL de référence " NR_ASSIGN_REFERRER_DESC2="Cibler les visiteurs qui arrivent sur votre site à partir d'une source de trafic spécifique." NR_ASSIGN_REFERRER_DESC="Entrez une URL de référence par ligne : Exemple :

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Gardez en tête que la découverte d'URL de référence n'est pas sûre à 100%. Certains serveurs utilisent des proxies pour masquer ou fausser ces informations." NR_PROFEATURE_HEADER="%s est une fonctionnalité premium" NR_PROFEATURE_DESC="Nous sommes désolé, %s n'est pas disponible pour votre offre. Merci de migrer vers l'offre PRO pour débloquer toutes ces magnifiques fonctionnalités." NR_PROFEATURE_DISCOUNT="Bonus: %s utilisateurs gratuits obtiennent 20% de rabais sur le prix régulier, appliqué directement lors de l'achat" NR_ONLY_AVAILABLE_IN_PRO="Uniquement disponible dans la version PRO" NR_UPGRADE_TO_PRO="Mettre à niveau vers Pro" NR_UPGRADE_TO_PRO_TO_UNLOCK="Mettre à niveau vers la version Pro pour débloquer" NR_UPGRADE_TO_PRO_VERSION="Magnifique ! Plus qu'une étape. Cliquez sur ce bouton ci dessous pour compléter la migration vers la version Pro." NR_UNLOCK_PRO_FEATURE="Débloquer les fonctionnalités premiums" NR_USING_THE_FREE_VERSION="Vous utilisez la version FREE de Convert Forms. Achetez la version PRO pour disposer de toutes les fonctionnalités" NR_LEFT_TO_RIGHT="De gauche à droite" NR_RIGHT_TO_LEFT="De droite à gauche" NR_BGIMAGE="Image d'arrière-plan" NR_BGIMAGE_DESC="Définir une image d'arrière-plan" NR_BGIMAGE_FILE="Image" NR_BGIMAGE_FILE_DESC="Sélectionner ou téléversé un fichier comme image d'arrière-plan." NR_BGIMAGE_REPEAT="Répétition" NR_BGIMAGE_REPEAT_DESC="La propriété de répétition de l'arrière-plan définit si/comment l'image de fond va se répéter. Par défaut, l'image de fond se répète à la fois verticalement et horizontalement.

Repeat : l'image de fond se répétera à la fois verticalement et horizontalement.

Repeat-x : l'image de fond se répétera horizontalement seulement

Repeat-y : l'image de fond se répétera verticalement seulement

No-repeat : l'image de fond ne se répétera pas." NR_BGIMAGE_SIZE="Taille" NR_BGIMAGE_SIZE_DESC="Définit la taille de l'image d'arrière plan.

Auto : l'image de fond utilise sa largeur et sa hauteur

Cover : redimensionne l'image de fond pour recouvrir complètement la zone d'arrière plan. Certaines parties de l'image peuvent donc ne plus être visible en fonction du positionnement de la zone d'arrière plan

Contain : Redimensionne l'image de fond proportionnellement l'image afin qu'elle rentre parfaitement dans la zone d'arrière plan

100% 100% : Recadre l'image de fond pour recouvrir complètement la zone de contenu." NR_BGIMAGE_POSITION="Position" NR_BGIMAGE_POSITION_DESC="La propriété position de l'arrière plan définit où se place l'image de fond. Par défaut, l'image est placé en haut à gauche de l'arrière plan. La première valeur correspond à la position horizontale, et la seconde à la verticale.

Vous pouvez utilisez n'importe quelle valeur prédéfinie ou entrez une valeur personnalisée en pourcentage : x% y% ou en pixel xPos yPos." NR_RTL="Activez le RTL" NR_RTL_DESC="La direction du texte de droite à gauche est essentielle pour les écritures RTL comme l'arabe, l'hébreu, le syriaque et le thaïlandais." NR_HORIZONTAL="Horizontal" NR_VERTICAL="Vertical" NR_FORM_ORIENTATION="Orientation du formulaire" NR_FORM_ORIENTATION_DESC="Selectionnez l'orientation du formulaire" NR_ASSIGN_CATEGORY="Catégories" NR_ASSIGN_CATEGORY_DESC="Sélectionner les catégories à assigner" NR_ASSIGN_CATEGORY_CHILD="Également sur les éléments enfants" NR_ASSIGN_CATEGORY_CHILD_DESC="Assigné aussi sur les éléments enfants de l'élément sélectionné ?" NR_NEW="Nouveau" NR_LIST="Liste" NR_DOCUMENTATION="Documentation" NR_KNOWLEDGEBASE="Base de connaissance" NR_FAQ="FAQ" NR_INFORMATION="Information" NR_EXTENSION="Extension" NR_VERSION="Version" NR_CHANGELOG=" Journal des modifications" NR_DOWNLOAD="Clé de téléchargement" NR_DOWNLOAD_KEY_MISSING="La clé de téléchargement est absente" NR_DOWNLOAD_KEY="Clé de téléchargement" NR_DOWNLOAD_KEY_DESC="Vous trouverez votre \"Download Key\" en vous connectant à votre compte sur Tassos.gr, dans la section \"download\".

Note : saisir cette clé ici ne permet pas de mettre à jour une version gratuite vers la version Pro. Pour bénéficier des fonctionnalités Pro vous devez aussi installer la version Pro." NR_DOWNLOAD_KEY_HOW="Pour pouvoir mettre à jour %s via la mise à jour Joomla, vous devrez entrer votre clé de téléchargement dans les paramètres du plugin du framework Novarain." NR_DOWNLOAD_KEY_FIND="Trouver la clé de téléchargement" NR_DOWNLOAD_KEY_UPDATE="Mettre à jour la clé de téléchargement" NR_OK="OK" NR_MISSING="Manquant" NR_LICENSE="Licence" NR_AUTHOR="Auteur" NR_FOLLOWME="Suivez-moi" NR_FOLLOW="Suivre %s" NR_TRANSLATE_INTEREST="Seriez-vous intéresser pour participer à la traduction de %s dans votre langue ?" NR_TRANSIFEX_REQUEST="Envoyez-moi une demande sur Transifex" NR_HELP_WITH_TRANSLATIONS="Aider à la traduction" NR_PUBLISHING_ASSIGNMENTS="Conditions d'affichage" NR_ADVANCED="Avancés" NR_USEGLOBAL="Usage global" NR_WEEKDAY="Jour de la semaine" NR_MONTH="Mois" NR_MONDAY="Lundi" NR_TUESDAY="Mardi" NR_WEDNESDAY="Mercredi" NR_THURSDAY="Jeudi" NR_FRIDAY="Vendredi" NR_SATURDAY="Samedi" NR_WEEKEND="Weekend" NR_WEEKDAYS="Jours de la semaine" NR_SUNDAY="Dimanche" NR_JANUARY="Janvier" NR_FEBRUARY="Février" NR_MARCH="Mars" NR_APRIL="Avril" NR_MAY="Mai" NR_JUNE="Juin" NR_JULY="Juillet " NR_AUGUST="Août " NR_SEPTEMBER="Septembre" NR_OCTOBER="Octobre" NR_NOVEMBER="Novembre" NR_DECEMBER="Décembre" NR_NEVER="Jamais" NR_SECONDS="Secondes" NR_MINUTES="Minutes" NR_HOURS="Heures" NR_DAYS="Jours" NR_SESSION="Session" NR_EVER="Toujours" NR_COOKIE="Cookie" NR_BOTH="Les deux" NR_NONE="Aucun" NR_NONE_SELECTED="Aucun sélectionné" NR_DESKTOPS="Ordinateur" NR_MOBILES="Mobile" NR_TABLETS="Tablette" NR_PER_SESSION="Par session" NR_PER_DAY="Par jour" NR_PER_WEEK="Par semaine" NR_PER_MONTH="Par mois" NR_FOREVER="Pour toujours" NR_FEATURE_UNDER_DEV="Cette fonctionnalité est en cours de développement" NR_LIKE_THIS_EXTENSION="Vous aimez cette extension ?" NR_LEAVE_A_REVIEW="Laissez un avis sur JED" NR_SUPPORT="Support" NR_NEED_SUPPORT="Besoin d'aide ?" NR_DROP_EMAIL="Envoyer moi un mail" NR_READ_DOCUMENTATION="Lire la documentation" NR_COPYRIGHT="%s - Tassos.gr Tous Droits Réservés" NR_DASHBOARD="Tableau de bord" NR_NAME="Nom" NR_WRONG_COORDINATES="Les coordonnées que vous avez fournies ne sont pas valides." NR_ENTER_COORDINATES="Latitude,Longitude" NR_NO_ITEMS_FOUND="Pas d'élément trouvé" NR_ITEM_IDS="Aucun ID d'élément" NR_TOGGLE="Basculer" NR_EXPAND="Étendre " NR_COLLAPSE="Rabattre " NR_SELECTED="Sélectionné " NR_MAXIMIZE="Maximiser" NR_MINIMIZE="Minimiser" NR_SELECTION="Sélection" NR_INSTALL="Intaller" NR_INSTALL_NOW="Installer dès à présent" NR_INSTALLED="Installé" NR_COMING_SOON="A venir" NR_ROADMAP="Sur la feuille de route" NR_MEDIA_VERSIONING="Utiliser la version média" NR_MEDIA_VERSIONING_DESC="Sélectionnez cette option pour ajouter le numéro de version de l'extension à la fin des urls du média (js/css), afin de forcer les navigateurs à charger le bon fichier." NR_LOAD_JQUERY="Importer jQuery" NR_LOAD_JQUERY_DESC="Sélectionnez cette option pour charger le script de base de jQuery. Vous pouvez désactiver cette option si vous rencontrez des conflits, lorsque votre modèle ou d'autres extensions chargent leur propre version de jQuery." NR_SELECT_CURRENCY="Sélectionner une monnaie" NR_CONVERTFORMS="Convertir des formulaires" NR_CONVERTFORMS_LIST="Campagne" NR_ASSIGN_CONVERTFORMS_DESC="Cibler les visiteurs qui ont souscrit à des campagnes spécifiques de ConvertForms." NR_CONVERTFORMS_LIST_DESC="Sélectionner une campagne du convertisseur de formulaire à assigner" NR_LEFT="Gauche" NR_CENTER="Centre" NR_RIGHT="Droite" NR_BOTTOM="Bas" NR_TOP="Haut" NR_AUTO="Auto" NR_CUSTOM="Personnaliser" NR_UPLOAD="Téléverser" NR_IMAGE="Image" NR_INTRO_IMAGE="Image d'intro" NR_FULL_IMAGE="Image principale" NR_IMAGE_SELECT="Sélectionner l'image" NR_IMAGE_SIZE_COVER="Couvrir" NR_IMAGE_SIZE_CONTAIN="Contenir" NR_REPEAT="Répéter " NR_REPEAT_X="Répéter sur l'axe X" NR_REPEAT_Y="Répéter sur l'axe Y" NR_REPEAT_NO="Non répéter" NR_FIELD_STATE_DESC="Définir l'état de l'élément" NR_CREATED_DATE="Date de création" NR_CREATED_DATE_DESC="La date de création de l'élément" NR_MODIFIFED_DATE="Date de modification" NR_MODIFIFED_DATE_DESC="La dernière date de modification de cet élément." NR_CATEGORIES="Catégorie" NR_CATEGORIES_DESC="Sélectionnez les catégories à assigner" NR_ALSO_ON_CHILD_ITEMS="Également sur les éléments enfants" NR_ALSO_ON_CHILD_ITEMS_DESC="Assigné aussi sur les éléments enfants de l'élément sélectionné ?" NR_PAGE_TYPE="Type de page" NR_PAGE_TYPES="Types de page" NR_PAGE_TYPES_DESC="Sélectionnez les types de page sur lesquels l'affectation doit être active." NR_CONTENT_VIEW_CATEGORY_BLOG="Blog de catégorie" NR_CONTENT_VIEW_CATEGORY_LIST="Liste de catégorie" NR_CONTENT_VIEW_CATEGORIES="Liste de toutes les catégories" NR_CONTENT_VIEW_ARCHIVED="Articles archivés" NR_CONTENT_VIEW_FEATURES="Articles en vedette" NR_CONTENT_VIEW_CREATE_ARTICLE="Créer un article" NR_CONTENT_VIEW_ARTICLE="Article" NR_ARTICLE_VIEW_DESC="Activer pour prendre en compte la vue Article" NR_CATEGORY_VIEW="Vue par catégorie" NR_CATEGORY_VIEW_DESC="Activer pour prendre en compte la vue Catégorie" NR_CONTENT_VIEW="Vue du composant de contenu" NR_CONTENT_VIEW_DESC="Sélectionnez les vues à affecter." NR_ARTICLES="Articles" NR_ARTICLES_DESC="Sélectionnez les articles à assigner." NR_ARTICLE="Article" NR_ARTICLE_AUTHORS="Auteurs" NR_ARTICLE_AUTHORS_DESC="Sélectionnez les auteurs à assigner." NR_ONLY="Seulement" NR_OTHERS="Autres" NR_SMARTTAGS="Smart Tags" NR_SMARTTAGS_SHOW="Afficher Smart Tags" NR_SMARTTAGS_NOTFOUND="Pas de Smart Tags trouvé" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Rechercher les Smarts Tags" NR_CONTACT_US="Contactez-nous" NR_FONT_COLOR="Couleur de la police" NR_FONT_SIZE="Taille de la police" NR_FONT_SIZE_DESC="Choisissez une taille de police en pixels" NR_TEXT="Texte" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Activer sur la surcharge de la sortie" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Active le rendu de l'extension lorsque la mise en page (tmpl) est surchargée. Exemples : tmpl=composant ou tmpl=modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Activer sur la surcharge du format" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Active le rendu de l'extension lorsque le format de page n'est pas autre chose que de HTML. Exemples : format=raw ou format=json." NR_GEOLOCATING="Géolocalisation" NR_GEOLOCATION="Géolocalisation" NR_GEOLOCATING_DESC="La géolocalisation n'est pas toujours exacte à 100 %. La géolocalisation est basée sur l'adresse IP du visiteur. Toutes les adresses IP ne sont pas fixes ou connues." NR_CITY="Ville" NR_CITY_NAME="Nom de Ville" NR_CONDITION_CITY_DESC="Entrez un nom de ville en anglais. Entrez plusieurs villes séparées par une virgule." NR_CONTINENT="Continent" NR_REGION="Région" NR_CONDITION_REGION_DESC="La valeur comprend deux parties, le code de pays à deux lettres ISO 3166-1 et le code de région. La valeur doit donc être sous la forme suivante: COUNTRY_CODE-REGION_CODE. Pour une liste complète des codes de région, cliquez sur le lien Trouver un code de région." NR_ASSIGN_COUNTRIES="Pays" NR_ASSIGN_COUNTRIES_DESC2="Ciblez les visiteurs qui se trouvent physiquement dans un pays spécifique." NR_ASSIGN_COUNTRIES_DESC="Sélectionnez les pays à assigner" NR_ASSIGN_CONTINENTS="Continent" NR_ASSIGN_CONTINENTS_DESC="Sélectionnez les continents à assigner" NR_ASSIGN_CONTINENTS_DESC2="Ciblez les visiteurs qui se trouvent physiquement sur un continent spécifique." NR_ICONTACT_ACCOUNTID_ERROR="L'ID de compte AccountID n'a pas pu être récupéré" NR_TAG_CLIENTDEVICE="Type d'appareil du visiteur" NR_TAG_CLIENTOS="Système d'exploitation du visiteur" NR_TAG_CLIENTBROWSER="Navigateur du visiteur" NR_TAG_CLIENTUSERAGENT="Chaîne user agent du visiteur" NR_TAG_IP="Adresse IP du visiteur" NR_TAG_URL="URL de la page" NR_TAG_URLENCODED="URL encodée de la page" NR_TAG_URLPATH="Lien de la page" NR_TAG_REFERRER="Référence de la page" NR_TAG_SITENAME="Nom du site" NR_TAG_SITEURL="URL du site" NR_TAG_PAGETITLE="Titre de la page" NR_TAG_PAGEDESC="Méta-description de la page" NR_TAG_PAGELANG="Langage du code de la page" NR_TAG_USERID="ID de l'utilisateur" NR_TAG_USERNAME="Nom complet de l'utilisateur" NR_TAG_USERLOGIN="Login de l'utilisateur" NR_TAG_USEREMAIL="Mail de l'utilisateur" NR_TAG_USERFIRSTNAME="Prénom de l'utilisateur" NR_TAG_USERLASTNAME="Nom de famille de l'utilisateur" NR_TAG_USERGROUPS="ID's des groupes d'utilisateurs" NR_TAG_DATE="Date" NR_TAG_TIME="Temps" NR_TAG_RANDOMID="ID aléatoire" NR_ICON="Icône" NR_SELECT_MODULE="Sélectionnez un module" NR_SELECT_CONTINENT="Sélectionner un continent" NR_SELECT_COUNTRY="Sélectionner un pays" NR_PLUGIN="Plugin" NR_GMAP_KEY="Clé de l'API Google Maps" NR_GMAP_KEY_DESC="Si vous rencontrez des problèmes avec Google Map qui ne se charge pas, vous devez probablement entrer votre propre clé API." NR_GMAP_FIND_KEY="Obtenir une clé de l'API" NR_ARE_YOU_SURE="Êtes-vous sur ?" NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Êtes-vous sûr de vouloir supprimer cet élément ?" NR_CUSTOMURL="URL personnalisée" NR_SAMPLE="Exemple" NR_DEBUG="Debug" NR_CUSTOMURL="URL personnalisée" NR_READMORE="Lire plus" NR_IPADDRESS="Adresse IP" NR_ASSIGN_BROWSERS="Navigateur" NR_ASSIGN_BROWSERS_DESC="Sélectionnez les navigateurs à assigner" NR_ASSIGN_BROWSERS_DESC2="Ciblez les visiteurs qui naviguent sur votre site avec des navigateurs spécifiques tels que Chrome, Firefox ou Internet Explorer." NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Système d'exploitation" NR_ASSIGN_OS_DESC="Sélectionnez les systèmes d'exploitations à assigner" NR_ASSIGN_OS_DESC2="Ciblez les visiteurs qui utilisent des systèmes d'exploitation spécifiques tels que Windows, Linux ou Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Nombre de page" NR_ASSIGN_PAGEVIEWS_DESC="Ciblez les visiteurs qui ont consulté un certain nombre de pages" NR_ASSIGN_PAGEVIEWS_VIEWS="Pages" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Entrez le nombre de pages" NR_ASSIGN_COOKIENAME_NAME="Nom du cookie" NR_ASSIGN_COOKIENAME_NAME_DESC="Entrez le nom du cookie à assigner" NR_ASSIGN_COOKIENAME_NAME_DESC2="Ciblez les visiteurs qui ont des cookies spécifiques stockés dans leur navigateur." NR_FEWER_THAN="Moins que" NR_FEWER_THAN_OR_EQUAL_TO="Inférieur ou égal à" NR_GREATER_THAN="Plus que" NR_GREATER_THAN_OR_EQUAL_TO="Supérieur ou égal à" NR_EXACTLY="Exactement" NR_EXISTS="Existe" NR_NOT_EXISTS="N'existe pas" NR_IS_EQUAL="Équivaut à" NR_DOES_NOT_EQUAL="N'est pas égal à" NR_CONTAINS="Contient" NR_DOES_NOT_CONTAIN="Ne contient pas" NR_STARTS_WITH="Commence par" NR_DOES_NOT_START_WITH="Ne commence pas par" NR_ENDS_WITH="Fini avec" NR_DOES_NOT_END_WITH="Ne se termine pas par" NR_ASSIGN_COOKIENAME_CONTENT="Contenu du cookie" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Le contenu du cookie" NR_ASSIGN_IP_ADDRESSES_DESC2="Cibler les visiteurs qui sont cachés derrière une adresse IP spécifique (intervalle)" NR_ASSIGN_IP_ADDRESSES_DESC="Entrez une liste avec des adresses IP spécifiques séparé par 'entrée' et/ou par une virgule

Exemple :
127.0.0.1,
192.10-120.2,
168" NR_USER="Utilisateur" NR_ASSIGN_USER_SELECTION_DESC="Sélectionner les utilisateurs de Joomla à affecter." NR_ASSIGN_USER_ID="ID de l'utilisateur" NR_ASSIGN_USER_ID_DESC="Cibler spécifiquement les utilisateurs Joomla par leur ID" NR_ASSIGN_USER_ID_SELECTION_DESC="Entrez les IDs des utilisateurs Joomla séparé par une virgule" NR_ASSIGN_COMPONENTS="Composant" NR_ASSIGN_COMPONENTS_DESC="Sélectionnez les composants à assigner" NR_ASSIGN_COMPONENTS_DESC2="Cibler les visiteurs qui naviguent sur des composants spécifiques." NR_ASSIGN_TIMERANGE="Intervalle de temps" NR_ASSIGN_TIMERANGE_DESC="Ciblez les visiteurs en fonction de l’heure de votre serveur" NR_START_TIME="Début du temps" NR_END_TIME="Fin du temps" NR_START_PUBLISHING_TIMERANGE_DESC="Spécifier l'heure de début de publication" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Entrez l'heure de fin de publication" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_DESC="Pour obtenir une clé de site et une clé secrète pour votre domaine, allez à l'adresse suivante: https://www.google.com/recaptcha" NR_RECAPTCHA_SITE_KEY="Clé du site" NR_RECAPTCHA_SITE_KEY_DESC="Utilisé dans le code JavaScript servi à vos utilisateurs" NR_RECAPTCHA_SECRET_KEY="Clé secrète" NR_RECAPTCHA_SECRET_KEY_DESC="Utilisé pour la communication entre votre serveur et celui de reCAPTCHA. Assurez-vous de garder le secret." NR_RECAPTCHA_SITE_KEY_ERROR="La clé du site reCaptcha est soit manquante soit invalide" NR_PREVIOUS_MONTH="Mois dernier" NR_NEXT_MONTH="Mois suivant" NR_ASSIGN_GROUP_PAGE_URL="Page / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Cibler les visiteurs qui naviguent sur des éléments de menu spécifiques ou des URL." NR_ASSIGN_GROUP_DATETIME_DESC="Déclencher une boîte en fonction de la date et de l'heure de votre serveur" NR_ASSIGN_GROUP_USER_VISITOR="Utilisateur / Visiteur Joomla" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Cibler les utilisateurs enregistrés ou les visiteurs qui ont consulté un certain nombre de pages" NR_ASSIGN_GROUP_PLATFORM="Plateforme Visiteur" NR_ASSIGN_GROUP_PLATFORM_DESC="Ciblez les visiteurs qui utilisent Mobile, Google Chrome ou même Windows." NR_ASSIGN_GROUP_GEO_DESC="Ciblez les visiteurs qui se trouvent physiquement dans une région spécifique." NR_ASSIGN_GROUP_JCONTENT="Contenu Joomla!" NR_ASSIGN_GROUP_JCONTENT_DESC="Ciblez les visiteurs qui regardent des articles ou des catégories spécifiques de Joomla" NR_ASSIGN_GROUP_SYSTEM="Système / Intégration" NR_INTEGRATIONS="Intégrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Ciblez les visiteurs qui interagissent avec des extensions Joomla spécifiques d'une tierce partie." NR_ASSIGN_GROUP_ADVANCED="Ciblage avancé des visiteurs" NR_ASSIGN_USERGROUP_DESC="Cibler spécifiquement les groupes d'utilisateurs Joomla" NR_ASSIGN_ARTICLE_DESC="Cibler les visiteurs qui consultent des articles spécifiques de Joomla" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Cibler les visiteurs qui consultent des catégories spécifiques de Joomla" NR_EXTENSION_REQUIRED="%scomposant nécessite%s que le plugin soit activé pour fonctionner correctement." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Cibler les visiteurs qui naviguent dans des éléments, des catégories ou des balises K2 spécifiques." NR_ASSIGN_K2_ITEMS="Élément " NR_ASSIGN_K2_ITEMS_DESC="Cibler les visiteurs qui naviguent dans des éléments K2 spécifiques." NR_ASSIGN_K2_ITEMS_LIST_DESC="Sélectionnez les éléments K2 à assigner" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Comparer un mot clé spécifique dans le contenu de l'élément; Séparer par une virgule ou un saut de ligne." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Comparez les méta-mots-clés de l'élément. Séparez par une virgule ou une nouvelle ligne." NR_ASSIGN_K2_PAGETYPES_DESC="Cibler les visiteurs qui naviguent dans des types de page K2 spécifiques." NR_ASSIGN_K2_ITEM_OPTION="Élément " NR_ASSIGN_K2_LATEST_OPTION="Derniers éléments depuis les utilisateurs ou les catégories" NR_ASSIGN_K2_TAG_OPTION="Baliser la page" NR_ASSIGN_K2_CATEGORY_OPTION="Catégorie de page" NR_ASSIGN_K2_ITEM_FORM_OPTION="Formulaire de modification d'élément" NR_ASSIGN_K2_USER_PAGE_OPTION="Page utilisateur (blog)" NR_ASSIGN_K2_TAGS_DESC="Ciblez les visiteurs qui naviguent sur les articles K2 avec des balises spécifiques" NR_ASSIGN_K2_CATEGORIES_DESC="Cibler les visiteurs qui naviguent dans des catégories K2 spécifiques." NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Catégories" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Éléments" NR_ASSIGN_PAGE_TYPES_DESC="Sélectionnez les types de page à assigner" NR_ASSIGN_TAGS_DESC="Sélectionnez les balises à assigner" NR_CONTENT_KEYWORDS="Mots-clés du contenu" NR_META_KEYWORDS="Méta-keywords" NR_TAG="Balise" NR_NORMAL="Normal" NR_COMPACT="Compact" NR_LIGHT="Léger" NR_DARK="Sombre" NR_SIZE="Taille" NR_THEME="Thème" NR_SINGLE="Seul" NR_MULTIPLE="Multiple" NR_RANGE="Intervalle" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Merci de valider" NR_RECAPTCHA_INVALID_SECRET_KEY="Clé secrète invalide" NR_PAGE="Page" NR_YOU_ARE_USING_EXTENSION="Vous utilisez %s%s" NR_UPDATE="Mettre à jour" NR_SHOW_UPDATE_NOTIFICATION="Afficher la notification de mise à jour" NR_SHOW_UPDATE_NOTIFICATION_DESC="Si cette option est sélectionnée, une notification de mise à jour apparaît dans la vue des composants principaux lorsqu'il existe une nouvelle version pour cette extension." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%sest disponible" NR_ERROR_EMAIL_IS_DISABLED="L'envoi de mails est désactivé. Les mails ne peuvent être envoyés" NR_ASSIGN_ITEMS="Item" NR_COUNTRY_AF="Afghanistan" NR_COUNTRY_AX="Iles Aland" NR_COUNTRY_AL="Albanie" NR_COUNTRY_DZ="Algerie" NR_COUNTRY_AS="American Samoa" NR_COUNTRY_AD="Andorre" NR_COUNTRY_AO="Angola" NR_COUNTRY_AI="Anguilla" NR_COUNTRY_AQ="Antarctique" NR_COUNTRY_AG="Antigua et Barbuda" NR_COUNTRY_AR="Argentine" NR_COUNTRY_AM="Arménie" NR_COUNTRY_AW="Aruba" NR_COUNTRY_AU="Australie" NR_COUNTRY_AT="Autriche" NR_COUNTRY_AZ="Azerbaidjan" NR_COUNTRY_BS="Bahamas" NR_COUNTRY_BH="Bahrain" NR_COUNTRY_BD="Bangladesh" NR_COUNTRY_BB="Barbades" NR_COUNTRY_BY="Belarus" NR_COUNTRY_BE="Belgique" NR_COUNTRY_BZ="Bélize" NR_COUNTRY_BJ="Bénin" NR_COUNTRY_BM="Bermudes" NR_COUNTRY_BQ_BO="Bonaire" NR_COUNTRY_BQ_SA="Saba" NR_COUNTRY_BQ_SE="Sint Eustatius" NR_COUNTRY_BT="Bhoutan" NR_COUNTRY_BO="Bolivie" NR_COUNTRY_BA="Bosnie Herzégovine" NR_COUNTRY_BW="Botswana" NR_COUNTRY_BV="Ile Bouvet" NR_COUNTRY_BR="Brésil" NR_COUNTRY_IO="Territoire britannique de l'Océan Indien" NR_COUNTRY_BN="Brunei Darussalam" NR_COUNTRY_BG="Bulgarie" NR_COUNTRY_BF="Burkina Faso" NR_COUNTRY_BI="Burundi" NR_COUNTRY_KH="Cambodge" NR_COUNTRY_CM="Cameroun" NR_COUNTRY_CA="Canada" NR_COUNTRY_CV="Cap Vert" NR_COUNTRY_KY="Iles Cayman" NR_COUNTRY_CF="République Centrafricaine" NR_COUNTRY_TD="Tchad" NR_COUNTRY_CL="Chili" NR_COUNTRY_CN="Chine" NR_COUNTRY_CX="Ile Christmas" NR_COUNTRY_CC="Iles Cocos (Keeling)" NR_COUNTRY_CO="Colombie" NR_COUNTRY_KM="Comors" NR_COUNTRY_CG="Congo" NR_COUNTRY_CD="Congo, République démocratique" NR_COUNTRY_CK="Iles Cook" NR_COUNTRY_CR="Costa Rica" NR_COUNTRY_CI="Côte d'Ivoire" NR_COUNTRY_HR="Croatie" NR_COUNTRY_CU="Cuba" NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Chypre" NR_COUNTRY_CZ="République tchèque" NR_COUNTRY_DK="Danemark" NR_COUNTRY_DJ="Djibouti" NR_COUNTRY_DM="Dominique" NR_COUNTRY_DO="République dominicaine" NR_COUNTRY_EC="Equateur" NR_COUNTRY_EG="Egypte" NR_COUNTRY_SV="Salvador" NR_COUNTRY_GQ="Guinée Equatoriale" NR_COUNTRY_ER="Érythrée" NR_COUNTRY_EE="Estonie" NR_COUNTRY_ET="Ethiopie" NR_COUNTRY_FK="Iles Falkland (Malvines)" NR_COUNTRY_FO="Iles Féroé " NR_COUNTRY_FJ="Iles Fiji" NR_COUNTRY_FI="Finlande" NR_COUNTRY_FR="France" NR_COUNTRY_GF="Guyane française" NR_COUNTRY_PF="Polynésie française" NR_COUNTRY_TF="Terres australes et antarctiques françaises" NR_COUNTRY_GA="Gabon" NR_COUNTRY_GM="Gambie" NR_COUNTRY_GE="Georgie" NR_COUNTRY_DE="Allemagne" NR_COUNTRY_GH="Ghana" NR_COUNTRY_GI="Gibraltar" NR_COUNTRY_GR="Grèce" NR_COUNTRY_GL="Groënland" NR_COUNTRY_GD="Grenade" NR_COUNTRY_GP="Guadeloupe" NR_COUNTRY_GU="Guam" NR_COUNTRY_GT="Guatemala" NR_COUNTRY_GG="Guernesey" NR_COUNTRY_GN="Guinée" NR_COUNTRY_GW="Guinée-Bissau" NR_COUNTRY_GY="Guyana" NR_COUNTRY_HT="Haïti" NR_COUNTRY_HM="Îles Heard et McDonald" NR_COUNTRY_VA="Vatican" NR_COUNTRY_HN="Honduras" NR_COUNTRY_HK="Hong Kong" NR_COUNTRY_HU="Hongrie" NR_COUNTRY_IS="Islande" NR_COUNTRY_IN="Inde" NR_COUNTRY_ID="Indonésie" NR_COUNTRY_IR="République Islamique d'Iran" NR_COUNTRY_IQ="Irak" NR_COUNTRY_IE="Irlande" NR_COUNTRY_IM="Ile de Man" NR_COUNTRY_IL="Israël" NR_COUNTRY_IT="Italie" NR_COUNTRY_JM="Jamaïque" NR_COUNTRY_JP="Japon" NR_COUNTRY_JE="Jersey" NR_COUNTRY_JO="Jordan" NR_COUNTRY_KZ="Kazakhstan" NR_COUNTRY_KE="Kenya" NR_COUNTRY_KI="Kiribati" NR_COUNTRY_KP="République démocratique de Corée" NR_COUNTRY_KR="République de Corée" NR_COUNTRY_KW="Koweit" NR_COUNTRY_KG="Kyrgyzstan" NR_COUNTRY_LA="République populaire démocratique du Laos" NR_COUNTRY_LV="Lettonie" NR_COUNTRY_LB="Liban" NR_COUNTRY_LS="Lesotho" NR_COUNTRY_LR="Liberia" NR_COUNTRY_LY="Libyan Arab Jamahiriya" NR_COUNTRY_LI="Liechtenstein" NR_COUNTRY_LT="Lituanie " NR_COUNTRY_LU="Luxembourg" NR_COUNTRY_MO="Macao" NR_COUNTRY_MK="Macédoine" NR_COUNTRY_MG="Madagascar" NR_COUNTRY_MW="Malawi" NR_COUNTRY_MY="Malaisie" NR_COUNTRY_MV="Maldives" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Malte" NR_COUNTRY_MH="Iles Marshall" NR_COUNTRY_MQ="Martinique" NR_COUNTRY_MR="Mauritanie" NR_COUNTRY_MU="Ile Maurice" NR_COUNTRY_YT="Mayotte" NR_COUNTRY_MX="Mexique" NR_COUNTRY_FM="Micronésie" NR_COUNTRY_MD="Moldavie" NR_COUNTRY_MC="Monaco" NR_COUNTRY_MN="Mongolie" NR_COUNTRY_ME="Montenegro" NR_COUNTRY_MS="Montserrat" NR_COUNTRY_MA="Maroc" NR_COUNTRY_MZ="Mozambique" NR_COUNTRY_MM="Myanmar" NR_COUNTRY_NA="Namibie" NR_COUNTRY_NR="Nauru" NR_COUNTRY_NM="North Macedonia" NR_COUNTRY_NP="Népal" NR_COUNTRY_NL="Pays-bas" NR_COUNTRY_AN="Antilles néerlandaises" NR_COUNTRY_NC="Nouvelle Calédonie" NR_COUNTRY_NZ="Nouvelle Zélande" NR_COUNTRY_NI="Nicaragua" NR_COUNTRY_NE="Niger" NR_COUNTRY_NG="Nigeria" NR_COUNTRY_NU="Niue" NR_COUNTRY_NF="Ile Norfolk" NR_COUNTRY_MP="Iles Mariannes du Nord" NR_COUNTRY_NO="Norvège" NR_COUNTRY_OM="Oman" NR_COUNTRY_PK="Pakistan" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Territoire Palestinien" NR_COUNTRY_PA="Panama" NR_COUNTRY_PG="Papouasie Nouvelle-Guinée" NR_COUNTRY_PY="Paraguay" NR_COUNTRY_PE="Pérou" NR_COUNTRY_PH="Philippines" NR_COUNTRY_PN="Pitcairn" NR_COUNTRY_PL="Pologne" NR_COUNTRY_PT="Portugal" NR_COUNTRY_PR="Porto Rico" NR_COUNTRY_QA="Qatar" NR_COUNTRY_RE="La réunion" NR_COUNTRY_RO="Roumanie" NR_COUNTRY_RU="Fédération de Russie" NR_COUNTRY_RW="Rwanda" NR_COUNTRY_SH="Sainte Hélène" NR_COUNTRY_KN="Saint Kitts et Nevis" NR_COUNTRY_LC="Sainte Lucie" NR_COUNTRY_PM="Saint Pierre et Miquelon" NR_COUNTRY_VC="Saint Vincent et Grenadines" NR_COUNTRY_WS="Samoa" NR_COUNTRY_SM="San Marin" NR_COUNTRY_ST="Sao Tome et Principe" NR_COUNTRY_SA="Arabie Saoudite" NR_COUNTRY_SN="Sénégal" NR_COUNTRY_RS="Serbie" NR_COUNTRY_SC="Seychelles" NR_COUNTRY_SL="Sierra Leone" NR_COUNTRY_SG="Singapour" NR_COUNTRY_SK="Slovaquie" NR_COUNTRY_SI="Slovénie" NR_COUNTRY_SB="Iles Solomon" NR_COUNTRY_SO="Somalie" NR_COUNTRY_ZA="Afrique du Sud" NR_COUNTRY_GS="Géorgie du Sud-et-les îles Sandwich du Sud" NR_COUNTRY_ES="Espagne" NR_COUNTRY_LK="Sri Lanka" NR_COUNTRY_SD="Soudan" NR_COUNTRY_SS="Sud Soudan" NR_COUNTRY_SR="Surinam" NR_COUNTRY_SJ="Svalbard et Jan Mayen" NR_COUNTRY_SZ="Swaziland" NR_COUNTRY_SE="Suède" NR_COUNTRY_CH="Suisse" NR_COUNTRY_SY="Syrie" NR_COUNTRY_TW="Taiwan" NR_COUNTRY_TJ="Tadjikistan" NR_COUNTRY_TZ="Tanzanie" NR_COUNTRY_TH="Thaïlande" NR_COUNTRY_TL="Timor-Leste" NR_COUNTRY_TG="Togo" NR_COUNTRY_TK="Tokelau" NR_COUNTRY_TO="Tonga" NR_COUNTRY_TT="Trinidad et Tobago" NR_COUNTRY_TN="Tunisie" NR_COUNTRY_TR="Turquie" NR_COUNTRY_TM="Turkménistan" NR_COUNTRY_TC="Iles Turks-et-Caïcos" NR_COUNTRY_TV="Tuvalu" NR_COUNTRY_UG="Ouganda" NR_COUNTRY_UA="Ukraine" NR_COUNTRY_AE="Émirats Arabes Unis" NR_COUNTRY_GB="Royaume Uni" NR_COUNTRY_US="États Unis" NR_COUNTRY_UM="Îles mineures éloignées des États-Unis" NR_COUNTRY_UY="Uruguay" NR_COUNTRY_UZ="Ouzbekistan" NR_COUNTRY_VU="Vanuatu" NR_COUNTRY_VE="Venezuela " NR_COUNTRY_VN="Vietnam" NR_COUNTRY_VG="Iles Vierges britanniques" NR_COUNTRY_VI="Iles Vierges US" NR_COUNTRY_WF="Wallis et Futuna" NR_COUNTRY_EH="Sahara occidental" NR_COUNTRY_YE="Yemen" NR_COUNTRY_ZM="Zambie" NR_COUNTRY_ZW="Zimbabwe" NR_CONTINENT_AF="Afrique" NR_CONTINENT_AS="Asie" NR_CONTINENT_EU="Europe" NR_CONTINENT_NA="Amérique du Nord" NR_CONTINENT_SA="Amérique du sud" NR_CONTINENT_OC="Océanie" NR_CONTINENT_AN="Antarctique" NR_FRONTEND="Site" NR_BACKEND="Administration" NR_EMBED="Intégrer" NR_RATE="Notation %s" NR_REPORT_ISSUE="Signaler une erreur" NR_RESPONSIVE_CONTROL_TITLE="Valeur définie par appareil" NR_TAG_PAGEGENERATOR="Générateur de pages" NR_TAG_PAGELANGURL="URL de la langue de la page" NR_TAG_PAGEKEYWORDS="Mots-clés de la page" NR_TAG_SITEEMAIL="Courriel du site" NR_TAG_DAY="Jour" NR_TAG_MONTH="Mois" NR_TAG_YEAR="Année" NR_TAG_USERREGISTERDATE="Date d'enregistrement" NR_TAG_PAGEBROWSERTITLE="Titre du navigateur" NR_TAG_EBID="ID de la boîte" NR_TAG_EBTITLE="Titre de la boîte" NR_TAG_QUERYSTRINGOPTION="Chaîne de requête : Option" NR_TAG_QUERYSTRINGVIEW="Chaîne de requête : Vue" NR_TAG_QUERYSTRINGLAYOUT="Chaîne de requête: Mise en page" NR_TAG_QUERYSTRINGTMPL="Chaîne de requête : Modèle" NR_CANNOT_CREATE_FOLDER="Impossible de créer le dossier pour y placer le fichier : %s" NR_CANNOT_MOVE_FILE="Impossible de déplacer le fichier : %s" NR_UPLOAD_INVALID_FILE_TYPE="Type de fichier non supporté : %s(%s) Les types de fichiers autorisés sont : %s" NR_UPLOAD_NO_MIME_TYPE="Impossible de deviner le type de fichier : %s. Vérifiez que l'extension PHP fileinfo est activée." NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Impossible d'envoyer le fichier : %s" NR_START_OVER="Recommencer" NR_TRY_AGAIN="Réessayer" NR_ERROR="Erreur" NR_CANCEL="Annuler" NR_PLEASE_WAIT="Veuillez patienter" NR_STAR="Etoile %s" NR_HCAPTCHA="hCaptcha" NR_TYPE="Type" NR_CHECKBOX="Case à cocher" NR_INVISIBLE="Invisible" NR_HCAPTCHA_DESC="Pour obtenir une clé de site et une clé secrète pour votre domaine, allez sur https://dashboard.hcaptcha.com/sites." NR_HCAPTCHA_SECRET_KEY_DESC="Utilisé dans la communication entre votre serveur et le serveur hCaptcha. Veillez à ce qu'il reste secret." NR_OUTDATED_EXTENSION="Votre version de %s a plus de quelques%d jours et est très probablement déjà périmée. Veuillez vérifier si une%s version %s plus récente est publiée et l'installez la" NR_GENERAL="Général" NR_GALLERY_MANAGER_BROWSE="Parcourir" NR_GALLERY_MANAGER_ADD_IMAGES="Ajouter des images" NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Parcourir la médiathèque" NR_GALLERY_MANAGER_REMOVE_IMAGES="Supprimer toutes les images" NR_GALLERY_MANAGER_TITLE_HINT="Entrez un titre" NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Entrez une description" NR_GALLERY_MANAGER_FILE_MISSING="Le fichier est manquant. Veuillez essayer de le retélécharger." NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Paramètres du widget manquants." NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Les paramètres du widget ne sont pas valides." NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Impossible de télécharger un fichier" NR_GALLERY_MANAGER_ERROR_INVALID_FILE="Ce fichier ne semble pas sûr ou invalide et ne peut pas être téléchargé." NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Êtes-vous sûr de vouloir supprimer tous les éléments de la galerie ?" NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Êtes-vous sûr de vouloir supprimer tous les éléments sélectionnés de la galerie ?" NR_GALLERY_MANAGER_CONFIRM_DELETE="Êtes-vous sûr de vouloir supprimer cet élément de la galerie ?" NR_GALLERY_MANAGER_IN_QUEUE="Dans la file d'attente" NR_GALLERY_MANAGER_UPLOADING="Téléchargement..." NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Supprimer les images sélectionnées" NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Vérifier pour supprimer plusieurs images" NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Cliquez pour supprimer l'image" NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Sélectionner tout" NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Désélectionner tout" NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Sélectionner ou désélectionner toutes les images" NR_GALLERY_MANAGER_ADD_DROPDOWN="Afficher/masquer les options du menu" NR_GALLERY_MANAGER_SELECT_ITEM="Sélectionnez un élément de la galerie" NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Faites glisser et déposez les images ici ou" NR_TECHNOLOGY="Technologie" NR_ENGAGEBOX_SELECT_BOX="Boîtes de sélection" NR_CONTENT_ARTICLE="Article de contenu" NR_CONTENT_CATEGORY="Catégorie de contenu" NR_VIEWED_ANOTHER_BOX="EngageBox - Vu un autre Popup" NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campagne" NR_K2_ITEM="K2 - Objet" NR_K2_CATEGORY="K2 - Catégorie" NR_K2_TAG="K2 - Étiquette" NR_K2_PAGE_TYPE="K2 - Type de page" NR_AKEEBASUBS_LEVEL="Niveau AkeebaSubs" NR_CB_SELECT_CONDITION="Sélectionner la condition" NR_CB_ADD_CONDITION_GROUP="Ajouter un ensemble de conditions" NR_CB_SELECT_CONDITION_GET_STARTED="Sélectionnez une condition pour commencer." NR_CB_TRASH_CONDITION="État de la poubelle" NR_CB_TRASH_CONDITION_GROUP="Groupe d'état de la poubelle" NR_CB_ADD_CONDITION="Ajouter une condition" NR_CB_SHOW_WHEN="Afficher lorsque" NR_CB_OF_THE_CONDITIONS_MATCH="des conditions ci-dessous sont remplies" NR_PHP_COLLECTION_SCRIPTS="Une collection de scripts d'affectation PHP prêts à l'emploi est disponible. Voir la collection" NR_IS="Est" NR_IS_NOT="N'est pas" NR_IS_EMPTY="est vide" NR_IS_NOT_EMPTY="N'est pas vide" NR_IS_BETWEEN="Se situe entre" NR_IS_NOT_BETWEEN="N'est pas entre" NR_DISPLAY_CONDITIONS_LOADING="Chargement des conditions d'affichage..." NR_CB_TOGGLE_RULE_GROUP_STATUS="Activer ou désactiver le jeu de conditions" NR_CB_TOGGLE_RULE_STATUS="Activer ou désactiver la condition" NR_DISPLAY_CONDITIONS_HINT_DATE="La date et l'heure de votre serveur sont %s." NR_DISPLAY_CONDITIONS_HINT_TIME="Le temps de votre serveur est %s." NR_DISPLAY_CONDITIONS_HINT_DAY="Aujourd'hui, c'est %s." NR_DISPLAY_CONDITIONS_HINT_MONTH="Le mois en cours est %s." NR_DISPLAY_CONDITIONS_HINT_USERID="L'identifiant du compte sur lequel vous êtes connecté est %s." NR_DISPLAY_CONDITIONS_HINT_USERGROUP="Les groupes d'utilisateurs affectés au compte sur lequel vous êtes connecté sont: %s." NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="Les niveaux d'accès de visualisation attribués au compte sur lequel vous êtes connecté sont: %s." NR_DISPLAY_CONDITIONS_HINT_DEVICE="Le type de l'appareil que vous utilisez est %s." NR_DISPLAY_CONDITIONS_HINT_BROWSER="Le navigateur que vous utilisez est %s." NR_DISPLAY_CONDITIONS_HINT_OS="Le système d'exploitation que vous utilisez est %s." NR_DISPLAY_CONDITIONS_HINT_GEO="D'après votre adresse IP (%s), %sl'endroit où vous vous trouvez physiquement est %s." NR_DISPLAY_CONDITIONS_HINT_IP="Votre adresse IP est %s." NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Sur la base de votre adresse IP (%s), nous n'avons pas pu déterminer où vous vous trouvez physiquement." NR_GEO_MAINTENANCE="Maintenance de la base de données de géolocalisation" NR_GEO_MAINTENANCE_DESC="La base de données utilisée pour déterminer l'emplacement géographique de vos visiteurs est périmée ou n'est pas installée. Veuillez cliquer sur le bas ci-dessous pour mettre à jour la base de données. Il est conseillé de la mettre à jour au moins une fois par mois." NR_EDIT="Modifier" NR_GEO_PLUGIN_DISABLED="Plugin de géolocalisation désactivé" NR_GEO_PLUGIN_DISABLED_DESC="Veuillez activer le plugin %s\"System - Tassos.gr GeoIP Plugin\"%s pour pouvoir utiliser les services de géolocalisation." NR_INVALID_IMAGE_PATH="Chemin de l'image non valide : %s" PK!X:YO~~Bsystem/nrframework/language/fa-IR/fa-IR.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="سیستم - فریمورک Novarain" PLG_SYSTEM_NRFRAMEWORK_DESC="فریمورک Novarain - استفاده شده توسط افزونه های Tassos.gr" NOVARAIN_FRAMEWORK="فریمورک Novarain" ; TRANSLATABLE NR_IGNORE="چشم پوشی" NR_INCLUDE="شامل" NR_EXCLUDE="محروم" NR_SELECTION="انتخاب" NR_ASSIGN_MENU_NOITEM="شامل بدون شناسه مورد" NR_ASSIGN_MENU_NOITEM_DESC="اختصاص موقعی که هیچ منویی به شناسه مورد تنظیم نشده باشد؟" ; NR_ASSIGN_MENU_CHILD="Also on child items" ; NR_ASSIGN_MENU_CHILD_DESC="Also assign to child items of the selected items?" NR_COPY_OF="کپی از %s" ; NR_ASSIGN_DATETIME_DESC="Target visitors based on your server's datetime" NR_DATETIME="زمان قرار" ; NR_TIME="Time" ; NR_DATE="Date" NR_DATETIME_DESC="زمان قرار برای انتشار/عدم انتشار خودکار وارد کنید." ; NR_START_PUBLISHING="Start Datetime" NR_START_PUBLISHING_DESC="تاریخ برای شروع انتشار وارد کنید." ; NR_FINISH_PUBLISHING="End Datetime" NR_FINISH_PUBLISHING_DESC="تاریخ پایان انتشار را وارد کنید." NR_DATETIME_NOTE="تخصیص تاریخ و زمان استفاده از تاریخ/زمان از سرور های خود ، نه سیستم بازدید کننده." ; NR_ASSIGN_PHP="PHP" ; NR_PHPCODE="PHP Code" ; NR_ASSIGN_PHP_DESC="Enter a piece of PHP code to evaluate." ; NR_ASSIGN_PHP_DESC2="Target visitors evaluating custom PHP code. The code must return the value true or false.

For instance:
return ($user->name == 'Tassos Marinos');" ; NR_ASSIGN_TIMEONSITE="Time on Site" NR_SECONDS="ساعت" ; NR_ASSIGN_TIMEONSITE_DESC="Enter a duration in seconds to compare with the user's total time (Visit duration) spent on your entire site .

Example:
If you want to display a box after the user has spent 3 minutes on your the entire site, enter 180." NR_ASSIGN_URLS="آدرس" ; NR_ASSIGN_URLS_DESC2="Target visitors who are browsing specific URLs" NR_ASSIGN_URLS_DESC=" آدرس ها (بخشی از ) را برای مطابقت وارد کنید.
از یک خط جدید برای هر مورد متفاوت استفاده کنید." NR_ASSIGN_URLS_LIST="آدرس های مشابه" ; NR_ASSIGN_URLS_REGEX="Use Regular Expression" NR_ASSIGN_URLS_REGEX_DESC="انتخاب برای ارتباط ارزش به عنوان عبارات منظم." ; NR_ASSIGN_LANGS="Language" ; NR_ASSIGN_LANGS_DESC="Target visitors who are browsing your website in specific language" NR_ASSIGN_LANGS_LIST_DESC="انتخاب زبان برای اختصاص به" ; NR_ASSIGN_DEVICES="Device" ; NR_ASSIGN_DEVICES_DESC2="Target visitors using specific device such as Mobile, Tablet or Desktop." NR_ASSIGN_DEVICES_DESC="برای اختصاص به دستگاه ها انتخاب کنید" NR_ASSIGN_DEVICES_NOTE="به خاطر داشته باشید که تشخیص دستگاه همیشه 100% دقیق نیست. کاربران می توانند مرورگر خود را به تقلید از دستگاه های دیگر نصب پیکربندی کنند" ; NR_MENU="Menu" ; NR_MENU_ITEMS="Menu Item" ; NR_MENU_ITEMS_DESC="Target visitors who are browsing specific menu items" ; NR_USERGROUP="User Group" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." ; NR_ACCESSLEVEL="User Group" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="نمایش کپی رایت" NR_SHOW_COPYRIGHT_DESC="اگر انتخاب شده باشد، اطلاعات اضافی به کپی رایت در دیدگاه مدیر نمایش داده میشود. افزونه های Tassos.gr هرگز اطلاعات کپی رایت و یا لینک دهنده در ظاهر را نمایش نمی دهند." NR_WIDTH="عرض" NR_WIDTH_DESC="عرض را به پیکسل، EM یا٪ وارد کنید

به عنوان مثال: 400px " NR_HEIGHT="ارتفاع" NR_HEIGHT_DESC="ارتفاء را به پیکسل، EM یا٪ وارد کنید

به عنوان مثال: 400px" NR_PADDING="لایه گذاری" NR_PADDING_DESC="لایه گذاری رابه پیکسل، EM یا٪ وارد کنید

به عنوان مثال: 20px" ; NR_MARGIN="Margin" ; NR_MARGIN_DESC="The CSS margin propertiy is used to generate space around the box and set the size of the white space outside the border in pixels or in %.

Example 1: 25px
Example 2: 5%

Specifying the margin for each side [top right bottom left]:

Top side only: 25px 0 0 0
Right side only: 0 25px 0 0
Bottom side only: 0 0 25px 0
Left side only: 0 0 0 25px" ; NR_COLOR_HOVER="Hover Color" NR_COLOR="رنگ" ; NR_COLOR_DESC="Define a color in HEX or RGBA format." NR_TEXT_COLOR="رنگ متن" ; NR_BACKGROUND="Background" NR_BACKGROUND_COLOR="رنگ پس زمینه" ; NR_BACKGROUND_COLOR_DESC="Define a background color in HEX or RGBA format. To disable enter 'none'. For absolute transparency enter 'transparent'." NR_URL_SHORTENING_FAILED="کوتاه%s با %s شکست خورد. %s." NR_EXPORT="خروجی" NR_IMPORT="وراد کردن" NR_PLEASE_CHOOSE_A_VALID_FILE="لطفا یک نام فایل معتبر انتخاب کنید" NR_IMPORT_ITEMS="وارد کردن موارد" NR_PUBLISH_ITEMS="موارد انتشار" NR_AS_EXPORTED="به عنوان خروجی گرفته شده" ; NR_TITLE="Title" NR_ACYMAILING="خبرنامه AcyMailing" ; NR_ACYMAILING_LIST="AcyMailing List" ; NR_ACYMAILING_LIST_DESC="Select AcyMailing lists to assign to." ; NR_ASSIGN_ACYMAILING_DESC="Target visitors who have subscribed to specific AcyMailing lists" NR_AKEEBASUBS="عضویت Akeeba " NR_AKEEBASUBS_LEVELS="سطوح" ; NR_AKEEBASUBS_LEVELS_DESC="Select Akeeba Subscription levels to assign to." ; NR_ASSIGN_AKEEBASUBS_DESC="Target visitors who have subscribed to specific Akeeba Subscriptions" ; NR_MATCH="Match" ; NR_MATCH_DESC="The used matching method to compare the value" NR_ASSIGN_MATCHING_METHOD="روش های مشابه" ; NR_ASSIGN_MATCHING_METHOD_DESC="Should all or any assignments be matched?

All
Will be published if All of below assignments are matched.

Any
Will be published if Any (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." NR_ANY="هر" ; NR_ALL="All" ; NR_ASSIGN_REFERRER="Referrer URL" ; NR_ASSIGN_REFERRER_DESC2="Target visitors who land on your site from a specific traffic source" ; NR_ASSIGN_REFERRER_DESC="Enter one Referrer URL per line: Eg:

google.com
facebook.com/mypage" ; NR_ASSIGN_REFERRER_NOTE="Keep in mind that URL Referrer discovery is not always 100% accurate. Some servers may use proxies that strip this information out and it can be easily forged." ; NR_PROFEATURE_HEADER="%s is a PRO Feature" ; NR_PROFEATURE_DESC="We're sorry, %s is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features." ; NR_PROFEATURE_DISCOUNT="Bonus: %s free users get 20% off regular price, automatically applied at checkout." NR_ONLY_AVAILABLE_IN_PRO="فقط در نسخه تجاری فعال است." NR_UPGRADE_TO_PRO="ارتقاء به نسخه تجاری" ; NR_UPGRADE_TO_PRO_TO_UNLOCK="Upgrade to Pro version to unlock" ; NR_UPGRADE_TO_PRO_VERSION="Awesome! Only one step left. Click on the button below to complete the upgrade to the Pro version." ; NR_UNLOCK_PRO_FEATURE="Unlock Pro Feature" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." NR_LEFT_TO_RIGHT="چپ به راست" NR_RIGHT_TO_LEFT="راست به چپ" NR_BGIMAGE="تصویر پس زمینه" NR_BGIMAGE_DESC="تنظیم تصویر پس زمینه" NR_BGIMAGE_FILE="تصویر" NR_BGIMAGE_FILE_DESC="یک فایل برای تصویر پس زمینه انتخاب و یا آپلود کنید." NR_BGIMAGE_REPEAT="تکرار" NR_BGIMAGE_REPEAT_DESC="ویژگی تکرار پس زمینه اگر تنظیم شده باشد/چگونه یک تصویر پس زمینه تکرار خواهد شد. به طور پیش فرض، تصویر پس زمینه صورت عمودی و افقی تکرار شده است.

تکرار: تصویر پس زمینه صورت عمودی و افقی تکرار شود.

X: تکرار تصویر پس زمینه را تکرار فقط به صورت افقی

y: تکرار تصویر پس زمینه را تکرار فقط عمودی

کننده: تصویر پس زمینه تکرار خواهد شد" NR_BGIMAGE_SIZE="اندازه" ; NR_BGIMAGE_SIZE_DESC="Specify the size of a background image.

Auto:The background-image contains its width and height

Cover: Scale the background image to be as large as possible so that the background area is completely covered by the background image. Some parts of the background image may not be in view within the background positioning area

Contain: Scale the image to the largest size such that both its width and its height can fit inside the content area

100% 100%: Stretch the background image to completely cover the content area." NR_BGIMAGE_POSITION="موقعیت" NR_BGIMAGE_POSITION_DESC="موقعیت پس زمینهموقعیت شروع تصویر پس زمینه را تنظیم می کند. تصویر پس زمینه پیش فرض در گوشه بالا سمت چپ قرار می گیرد. مقدار اول موقعیت افقی و ارزش دوم عمودی است.

شما می توانید یکی از مقادیر از پیش تعریف شده یا مقداری سفارشی وارد کنید بر حسب درصد: x y % و یا در yPos xPos پیکسل استفاده کنید." NR_RTL="فعال کردن راست به چپ" NR_RTL_DESC="جهت متن راست به چپ برای اسکریپت راست به چپ مانند عربی، عبری، سریانی، و ثنا ضروری است." NR_HORIZONTAL="افقی" NR_VERTICAL="عمودی" NR_FORM_ORIENTATION="جهت فرم" NR_FORM_ORIENTATION_DESC="جهت فرم را انتخاب کنید" NR_ASSIGN_CATEGORY="دسته بندی ها" NR_ASSIGN_CATEGORY_DESC="انتخاب دسته بندی ها برای اختصاص" NR_ASSIGN_CATEGORY_CHILD="زیرمجموعه ها همچنین" NR_ASSIGN_CATEGORY_CHILD_DESC=" به زیرمجموعه آیتم های انتخاب شده اختصاص می دهید؟" NR_NEW="جدید" NR_LIST="لیست" NR_DOCUMENTATION="مستندات" ; NR_KNOWLEDGEBASE="Knowledgebase" NR_FAQ="سوال و جواب" NR_INFORMATION="اطلاعات" NR_EXTENSION="افزونه" NR_VERSION="نسخه" NR_CHANGELOG="تغییرات" ; NR_DOWNLOAD="Download" ; NR_DOWNLOAD_KEY_MISSING="Download Key is missing" NR_DOWNLOAD_KEY="کلید دانلود" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." NR_DOWNLOAD_KEY_HOW="برای اینکه قادر به به روز رسانی %s از طریق به روز رسانی جوملا باشید ، شما نیاز درارید در تنظیمات پلاگین فریمورک Novarain خود کلید دانلود را وارد کنید." NR_DOWNLOAD_KEY_FIND="پیدا کردن کلید دانلود" NR_DOWNLOAD_KEY_UPDATE="بروزرسانی کلید دانلود" NR_OK="تایید" NR_MISSING="مفقود" NR_LICENSE="لایسنس" NR_AUTHOR="نویسنده" NR_FOLLOWME="دنبال کردن من" NR_FOLLOW="دنبال کردن %s" NR_TRANSLATE_INTEREST="آیا علاقمند به کمک به ترجمه %s به زبان خود هستید؟" NR_TRANSIFEX_REQUEST="اراسل درخواست به من در ترانسیفکس" NR_HELP_WITH_TRANSLATIONS="کمک برای ترجمه" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="پیشرفته" NR_USEGLOBAL="استفاده از پیکربندی کلی " ; NR_WEEKDAY="Day of Week" ; NR_MONTH="Month" ; NR_MONDAY="Monday" ; NR_TUESDAY="Tuesday" ; NR_WEDNESDAY="Wednesday" ; NR_THURSDAY="Thursday" ; NR_FRIDAY="Friday" ; NR_SATURDAY="Saturday" ; NR_WEEKEND="Weekend" ; NR_WEEKDAYS="Weekdays" ; NR_SUNDAY="Sunday" ; NR_JANUARY="January" ; NR_FEBRUARY="February" ; NR_MARCH="March" ; NR_APRIL="April" ; NR_MAY="May" ; NR_JUNE="June" ; NR_JULY="July" ; NR_AUGUST="August" ; NR_SEPTEMBER="September" ; NR_OCTOBER="October" ; NR_NOVEMBER="November" ; NR_DECEMBER="December" NR_NEVER="هیچوقت" NR_SECONDS="ساعت" NR_MINUTES="دقیقه" NR_HOURS="ساعت" NR_DAYS="روز" NR_SESSION="نشست" NR_EVER="همیشه" NR_COOKIE="کوکی" NR_BOTH="هردو" NR_NONE="هیچکدام" ; NR_NONE_SELECTED="None Selected" ; NR_DESKTOPS="Desktop" ; NR_MOBILES="Mobile" ; NR_TABLETS="Tablet" ; NR_PER_SESSION="Per Session" ; NR_PER_DAY="Per Day" ; NR_PER_WEEK="Per Week" ; NR_PER_MONTH="Per Month" ; NR_FOREVER="Forever" ; NR_FEATURE_UNDER_DEV="This feature is under development" ; NR_LIKE_THIS_EXTENSION="Like this extension?" ; NR_LEAVE_A_REVIEW="Leave a review on JED" ; NR_SUPPORT="Support" ; NR_NEED_SUPPORT="Need support?" ; NR_DROP_EMAIL="Drop me an e-mail" ; NR_READ_DOCUMENTATION="Read the Documentation" ; NR_COPYRIGHT="%s - Tassos.gr All Rights Reserved" ; NR_DASHBOARD="Dashboard" ; NR_NAME="Name" ; NR_WRONG_COORDINATES="The coordinates you provided are not valid" ; NR_ENTER_COORDINATES="Latitude,Longitude" ; NR_NO_ITEMS_FOUND="No Items Found" ; NR_ITEM_IDS="No Item IDs" ; NR_TOGGLE="Toggle" ; NR_EXPAND="Expand" ; NR_COLLAPSE="Collapse" ; NR_SELECTED="Selected" ; NR_MAXIMIZE="Maximize" ; NR_MINIMIZE="Minimize" NR_SELECTION="انتخاب" ; NR_INSTALL="Install" ; NR_INSTALL_NOW="Install Now" ; NR_INSTALLED="Installed" ; NR_COMING_SOON="Coming soon" ; NR_ROADMAP="On the roadmap" ; NR_MEDIA_VERSIONING="Use Media Versioning" ; NR_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." ; NR_LOAD_JQUERY="Load jQuery" ; NR_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." ; NR_SELECT_CURRENCY="Select a Currency" ; NR_CONVERTFORMS="Convert Forms" ; NR_CONVERTFORMS_LIST="Campaign" ; NR_ASSIGN_CONVERTFORMS_DESC="Target visitors who have subscribed to specific ConvertForms campaigns" ; NR_CONVERTFORMS_LIST_DESC="Select ConvertForms campaigns to assign to." ; NR_LEFT="Left" ; NR_CENTER="Center" ; NR_RIGHT="Right" ; NR_BOTTOM="Bottom" ; NR_TOP="Top" ; NR_AUTO="Auto" ; NR_CUSTOM="Custom" ; NR_UPLOAD="Upload" ; NR_IMAGE="Image" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" ; NR_IMAGE_SELECT="Select Image" ; NR_IMAGE_SIZE_COVER="Cover" ; NR_IMAGE_SIZE_CONTAIN="Contain" ; NR_REPEAT="Repeat" ; NR_REPEAT_X="Repeat x" ; NR_REPEAT_Y="Repeat y" ; NR_REPEAT_NO="No repeat" ; NR_FIELD_STATE_DESC="Set item's state" ; NR_CREATED_DATE="Created Date" ; NR_CREATED_DATE_DESC="The date the item was created" ; NR_MODIFIFED_DATE="Modified Date" ; NR_MODIFIFED_DATE_DESC="The date that the item was last modified." ; NR_CATEGORIES="Category" ; NR_CATEGORIES_DESC="Select the categories to assign to." ; NR_ALSO_ON_CHILD_ITEMS="Also on child items" ; NR_ALSO_ON_CHILD_ITEMS_DESC="Also assign to child items of the selected items?" ; NR_PAGE_TYPE="Page type" ; NR_PAGE_TYPES="Page types" ; NR_PAGE_TYPES_DESC="Select on what page types the assignment should be active." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" ; NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" ; NR_CATEGORY_VIEW="Category View" ; NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." ; NR_ARTICLES="Articles" ; NR_ARTICLES_DESC="Select the articles to assign to." ; NR_ARTICLE="Article" ; NR_ARTICLE_AUTHORS="Authors" ; NR_ARTICLE_AUTHORS_DESC="Select the authors to assign to." ; NR_ONLY="Only" ; NR_OTHERS="Others" ; NR_SMARTTAGS="Smart Tags" ; NR_SMARTTAGS_SHOW="Show Smart Tags" ; NR_SMARTTAGS_NOTFOUND="No Smart Tags found" ; NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" ; NR_CONTACT_US="Contact us" ; NR_FONT_COLOR="Font Color" ; NR_FONT_SIZE="Font Size" ; NR_FONT_SIZE_DESC="Choose a font size in pixels" ; NR_TEXT="Text" ; NR_URL="URL" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE="Enable on Output Override" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Enables the extension rendering when the page layout (tmpl) is overriden. Examples: tmpl=component or tmpl=modal." ; NR_EXECUTE_ON_FORMAT_OVERRIDE="Enable on Format Override" ; NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Enables the extension rendering when the page format is not other than HTML. Examples: format=raw or format=json." ; NR_GEOLOCATING="Geolocating" ; NR_GEOLOCATION="Geolocation" ; NR_GEOLOCATING_DESC="Geolocating is not always 100% accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known." ; NR_CITY="City" ; NR_CITY_NAME="City Name" ; NR_CONDITION_CITY_DESC="Enter a city name in English. Enter multiple cities separated by comma." ; NR_CONTINENT="Continent" ; NR_REGION="Region" ; NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." ; NR_ASSIGN_COUNTRIES="Country" ; NR_ASSIGN_COUNTRIES_DESC2="Target visitors who are physically in a specific country" ; NR_ASSIGN_COUNTRIES_DESC="Select the countries to assign to" ; NR_ASSIGN_CONTINENTS="Continent" ; NR_ASSIGN_CONTINENTS_DESC="Select the continents to assign to" ; NR_ASSIGN_CONTINENTS_DESC2="Target visitors who are physically in a specific continent" ; NR_ICONTACT_ACCOUNTID_ERROR="The iContact AccountID could not be retrieved" ; NR_TAG_CLIENTDEVICE="Visitor Device Type" ; NR_TAG_CLIENTOS="Visitor Operating System" ; NR_TAG_CLIENTBROWSER="Visitor Browser" ; NR_TAG_CLIENTUSERAGENT="Visitor Agent String" ; NR_TAG_IP="Visitor IP Address" ; NR_TAG_URL="Page URL" ; NR_TAG_URLENCODED="Page URL Encoded" ; NR_TAG_URLPATH="Page Path" ; NR_TAG_REFERRER="Page Referrer" ; NR_TAG_SITENAME="Site Name" ; NR_TAG_SITEURL="Site URL" ; NR_TAG_PAGETITLE="Page Title" ; NR_TAG_PAGEDESC="Page Meta Description" ; NR_TAG_PAGELANG="Page Language Code" ; NR_TAG_USERID="User ID" ; NR_TAG_USERNAME="User Full Name" ; NR_TAG_USERLOGIN="User Login" ; NR_TAG_USEREMAIL="User Email" ; NR_TAG_USERFIRSTNAME="User First Name" ; NR_TAG_USERLASTNAME="User Last Name" ; NR_TAG_USERGROUPS="User Groups IDs" ; NR_TAG_DATE="Date" ; NR_TAG_TIME="Time" ; NR_TAG_RANDOMID="Random ID" ; NR_ICON="Icon" ; NR_SELECT_MODULE="Select a Module" ; NR_SELECT_CONTINENT="Select a Continent" ; NR_SELECT_COUNTRY="Select a Country" ; NR_PLUGIN="Plugin" ; NR_GMAP_KEY="Google Maps API Key" ; NR_GMAP_KEY_DESC="The Google Maps API Key is being used by Tassos.gr extensions. If you face any troubles with a Google Map not being loaded then you probably need to enter your own API Key." ; NR_GMAP_FIND_KEY="Get an API key" ; NR_ARE_YOU_SURE="Are you sure?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" ; NR_CUSTOMURL="Custom URL" ; NR_SAMPLE="Sample" ; NR_DEBUG="Debug" ; NR_CUSTOMURL="Custom URL" ; NR_READMORE="Read More" ; NR_IPADDRESS="IP Address" ; NR_ASSIGN_BROWSERS="Browser" ; NR_ASSIGN_BROWSERS_DESC="Select the browsers to assign to" ; NR_ASSIGN_BROWSERS_DESC2="Target visitors who are browsing your site with specific browsers such as Chrome, Firefox or Internet Explorer" ; NR_CHROME="Chrome" ; NR_FIREFOX="Firefox" ; NR_EDGE="Edge" ; NR_IE="Internet Explorer" ; NR_SAFARI="Safari" ; NR_OPERA="Opera" ; NR_ASSIGN_OS="Operating System" ; NR_ASSIGN_OS_DESC="Select the operating systems to assign to" ; NR_ASSIGN_OS_DESC2="Target visitors who are using specific operating systems such as Windows, Linux or Mac" ; NR_LINUX="Linux" ; NR_MAC="MacOS" ; NR_ANDROID="Android" ; NR_IOS="iOS" ; NR_WINDOWS="Windows" ; NR_BLACKBERRY="Blackberry" ; NR_CHROMEOS="Chrome OS" ; NR_ASSIGN_PAGEVIEWS="Number of Pageviews" ; NR_ASSIGN_PAGEVIEWS_DESC="Target visitors who have viewed certain number of pages" ; NR_ASSIGN_PAGEVIEWS_VIEWS="Pageviews" ; NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Enter the number of page views" ; NR_ASSIGN_COOKIENAME_NAME="Cookie Name" ; NR_ASSIGN_COOKIENAME_NAME_DESC="Enter the name of the cookie to assign to" ; NR_ASSIGN_COOKIENAME_NAME_DESC2="Target visitors who have specific cookies stored in their browser" ; NR_FEWER_THAN="Fewer than" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" ; NR_GREATER_THAN="Greater than" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" ; NR_EXACTLY="Exactly" ; NR_EXISTS="Exists" ; NR_NOT_EXISTS="Does not exists" ; NR_IS_EQUAL="Equals" ; NR_DOES_NOT_EQUAL="Does not equal" ; NR_CONTAINS="Contains" ; NR_DOES_NOT_CONTAIN="Does not contain" ; NR_STARTS_WITH="Starts with" ; NR_DOES_NOT_START_WITH="Does not start with" ; NR_ENDS_WITH="Ends with" ; NR_DOES_NOT_END_WITH="Does not end with" ; NR_ASSIGN_COOKIENAME_CONTENT="Cookie Content" ; NR_ASSIGN_COOKIENAME_CONTENT_DESC="The cookie's content" ; NR_ASSIGN_IP_ADDRESSES_DESC2="Target visitors who are behind a specific IP address (range)" ; NR_ASSIGN_IP_ADDRESSES_DESC="Enter a list of comma and/or 'enter' separated ip addresses and ranges

Example:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." ; NR_ASSIGN_USER_ID="User ID" ; NR_ASSIGN_USER_ID_DESC="Target specific Joomla Users by their IDs" ; NR_ASSIGN_USER_ID_SELECTION_DESC="Enter comma separated Joomla user IDs" ; NR_ASSIGN_COMPONENTS="Component" ; NR_ASSIGN_COMPONENTS_DESC="Select the components to assign to" ; NR_ASSIGN_COMPONENTS_DESC2="Target visitors who are browsing specific components" ; NR_ASSIGN_TIMERANGE="Time Range" ; NR_ASSIGN_TIMERANGE_DESC="Target visitors based on your server's time" ; NR_START_TIME="Start Time" ; NR_END_TIME="End Time" ; NR_START_PUBLISHING_TIMERANGE_DESC="Enter the time to start publishing" ; NR_FINISH_PUBLISHING_TIMERANGE_DESC="Enter the time to end publishing" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." ; NR_RECAPTCHA_SITE_KEY="Site Key" ; NR_RECAPTCHA_SITE_KEY_DESC="Used in the JavaScript code that is served to your users." ; NR_RECAPTCHA_SECRET_KEY="Secret Key" ; NR_RECAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret." ; NR_RECAPTCHA_SITE_KEY_ERROR="The reCaptcha Site Key is either missing or invalid" ; NR_PREVIOUS_MONTH="Previous Month" ; NR_NEXT_MONTH="Next Month" ; NR_ASSIGN_GROUP_PAGE_URL="Page / URL" ; NR_ASSIGN_GROUP_PAGE_URL_DESC="Target visitors who are browsing specific menu items or URLs" ; NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" ; NR_ASSIGN_GROUP_USER_VISITOR="Joomla User / Visitor" ; NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" ; NR_ASSIGN_GROUP_PLATFORM="Visitor Platform" ; NR_ASSIGN_GROUP_PLATFORM_DESC="Target visitors who are using Mobile, Google Chrome, or even Windows" ; NR_ASSIGN_GROUP_GEO_DESC="Target visitors who are physically in a specific region" ; NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" ; NR_ASSIGN_GROUP_JCONTENT_DESC="Target visitors who are viewing specific Joomla articles or categories" ; NR_ASSIGN_GROUP_SYSTEM="System / Integrations" ; NR_INTEGRATIONS="Integrations" ; NR_ASSIGN_GROUP_SYSTEM_DESC="Target visitors who have interacted with specific 3rd party Joomla Extensions" ; NR_ASSIGN_GROUP_ADVANCED="Advanced visitor targeting" ; NR_ASSIGN_USERGROUP_DESC="Target specific Joomla user groups" ; NR_ASSIGN_ARTICLE_DESC="Target visitors who are viewing specific Joomla articles" ; NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target visitors who are viewing specific Joomla categories" ; NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." ; NR_ASSIGN_K2="K2" ; NR_ASSIGN_K2_DESC="Target visitors who are browsing specific K2 Items, Categories or Tags" ; NR_ASSIGN_K2_ITEMS="Item" ; NR_ASSIGN_K2_ITEMS_DESC="Target visitors who are browsing specific K2 items." ; NR_ASSIGN_K2_ITEMS_LIST_DESC="Select the K2 Items to assign to" ; NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Match on specific keywords in the item's content. Seperate by a comma or a new line." ; NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Match on the item's meta keywords. Seperate by a comma or a new line." ; NR_ASSIGN_K2_PAGETYPES_DESC="Target visitors who are browsing specific K2 page types" ; NR_ASSIGN_K2_ITEM_OPTION="Item" ; NR_ASSIGN_K2_LATEST_OPTION="Latest items from users or categories" ; NR_ASSIGN_K2_TAG_OPTION="Tag Page" ; NR_ASSIGN_K2_CATEGORY_OPTION="Category Page" ; NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Edit Form" ; NR_ASSIGN_K2_USER_PAGE_OPTION="User Page (blog)" ; NR_ASSIGN_K2_TAGS_DESC="Target visitors who are browsing K2 items with specific tags" ; NR_ASSIGN_K2_CATEGORIES_DESC="Target visitors who are browsing specific K2 categories" ; NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" ; NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" ; NR_ASSIGN_PAGE_TYPES_DESC="Select the page types to assign to" ; NR_ASSIGN_TAGS_DESC="Select the tags to assign to" ; NR_CONTENT_KEYWORDS="Content keywords" ; NR_META_KEYWORDS="Meta keywords" ; NR_TAG="Tag" ; NR_NORMAL="Normal" ; NR_COMPACT="Compact" ; NR_LIGHT="Light" ; NR_DARK="Dark" ; NR_SIZE="Size" ; NR_THEME="Theme" ; NR_SINGLE="Single" ; NR_MULTIPLE="Multiple" ; NR_RANGE="Range" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_PLEASE_VALIDATE="Please validate" ; NR_RECAPTCHA_INVALID_SECRET_KEY="Invalid secret key" ; NR_PAGE="Page" ; NR_YOU_ARE_USING_EXTENSION="You are using %s %s" ; NR_UPDATE="Update" ; NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" ; NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." ; NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" ; NR_COUNTRY_GR="Greece" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!88Bsystem/nrframework/language/el-GR/el-GR.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - used by Tassos.gr extensions" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Αγνόησε" NR_INCLUDE="Συμπεριέλαβε" NR_EXCLUDE="Απόκλεισε" NR_SELECTION="Επιλογή" ; NR_ASSIGN_MENU_NOITEM="Include no Itemid" ; NR_ASSIGN_MENU_NOITEM_DESC="Also assign when no menu Itemid is set in URL?" ; NR_ASSIGN_MENU_CHILD="Also on child items" ; NR_ASSIGN_MENU_CHILD_DESC="Also assign to child items of the selected items?" ; NR_COPY_OF="Copy of %s" ; NR_ASSIGN_DATETIME_DESC="Target visitors based on your server's datetime" NR_DATETIME="Ημερομηνία ώρα" ; NR_TIME="Time" ; NR_DATE="Date" ; NR_DATETIME_DESC="Enter the datetime to auto publish/unpublish" ; NR_START_PUBLISHING="Start Datetime" ; NR_START_PUBLISHING_DESC="Enter the date to start publishing" ; NR_FINISH_PUBLISHING="End Datetime" ; NR_FINISH_PUBLISHING_DESC="Enter the date to end publishing" ; NR_DATETIME_NOTE="The date and time assignments use the date/time of your servers, not that of the visitors system." ; NR_ASSIGN_PHP="PHP" ; NR_PHPCODE="PHP Code" ; NR_ASSIGN_PHP_DESC="Enter a piece of PHP code to evaluate." ; NR_ASSIGN_PHP_DESC2="Target visitors evaluating custom PHP code. The code must return the value true or false.

For instance:
return ($user->name == 'Tassos Marinos');" ; NR_ASSIGN_TIMEONSITE="Time on Site" ; NR_SECONDS="Seconds" ; NR_ASSIGN_TIMEONSITE_DESC="Enter a duration in seconds to compare with the user's total time (Visit duration) spent on your entire site .

Example:
If you want to display a box after the user has spent 3 minutes on your the entire site, enter 180." ; NR_ASSIGN_URLS="URL" ; NR_ASSIGN_URLS_DESC2="Target visitors who are browsing specific URLs" ; NR_ASSIGN_URLS_DESC="Enter (part of) the URLs to match.
Use a new line for each different match." ; NR_ASSIGN_URLS_LIST="URL Matches" ; NR_ASSIGN_URLS_REGEX="Use Regular Expression" ; NR_ASSIGN_URLS_REGEX_DESC="Select to treat the value as regular expressions." ; NR_ASSIGN_LANGS="Language" ; NR_ASSIGN_LANGS_DESC="Target visitors who are browsing your website in specific language" ; NR_ASSIGN_LANGS_LIST_DESC="Select the Languages to assign to" ; NR_ASSIGN_DEVICES="Device" ; NR_ASSIGN_DEVICES_DESC2="Target visitors using specific device such as Mobile, Tablet or Desktop." ; NR_ASSIGN_DEVICES_DESC="Select the devices to assign to." ; NR_ASSIGN_DEVICES_NOTE="Keep in mind that device detection is not always 100% accurate. Users can setup their browser to mimic other devices" ; NR_MENU="Menu" ; NR_MENU_ITEMS="Menu Item" ; NR_MENU_ITEMS_DESC="Target visitors who are browsing specific menu items" ; NR_USERGROUP="User Group" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." ; NR_ACCESSLEVEL="User Group" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." ; NR_SHOW_COPYRIGHT="Show Copyright" ; NR_SHOW_COPYRIGHT_DESC="If selected, extra copyright info will be displayed in the admin views. Tassos.gr extensions never show copyright info or backlinks on the frontend." ; NR_WIDTH="Width" ; NR_WIDTH_DESC="Enter width in px, em or %

Example: 400px" ; NR_HEIGHT="Height" ; NR_HEIGHT_DESC="Enter height in px, em or %

Example: 400px" ; NR_PADDING="Padding" ; NR_PADDING_DESC="Enter padding in px, em or %

Example: 20px" ; NR_MARGIN="Margin" ; NR_MARGIN_DESC="The CSS margin propertiy is used to generate space around the box and set the size of the white space outside the border in pixels or in %.

Example 1: 25px
Example 2: 5%

Specifying the margin for each side [top right bottom left]:

Top side only: 25px 0 0 0
Right side only: 0 25px 0 0
Bottom side only: 0 0 25px 0
Left side only: 0 0 0 25px" ; NR_COLOR_HOVER="Hover Color" ; NR_COLOR="Color" ; NR_COLOR_DESC="Define a color in HEX or RGBA format." ; NR_TEXT_COLOR="Text Color" ; NR_BACKGROUND="Background" ; NR_BACKGROUND_COLOR="Background Color" ; NR_BACKGROUND_COLOR_DESC="Define a background color in HEX or RGBA format. To disable enter 'none'. For absolute transparency enter 'transparent'." ; NR_URL_SHORTENING_FAILED="Shortening %s with %s failed. %s." ; NR_EXPORT="Export" ; NR_IMPORT="Import" ; NR_PLEASE_CHOOSE_A_VALID_FILE="Please choose a valid filename" ; NR_IMPORT_ITEMS="Import Items" ; NR_PUBLISH_ITEMS="Publish items" ; NR_AS_EXPORTED="As exported" ; NR_TITLE="Title" ; NR_ACYMAILING="AcyMailing" ; NR_ACYMAILING_LIST="AcyMailing List" ; NR_ACYMAILING_LIST_DESC="Select AcyMailing lists to assign to." ; NR_ASSIGN_ACYMAILING_DESC="Target visitors who have subscribed to specific AcyMailing lists" ; NR_AKEEBASUBS="Akeeba Subscriptions" ; NR_AKEEBASUBS_LEVELS="Levels" ; NR_AKEEBASUBS_LEVELS_DESC="Select Akeeba Subscription levels to assign to." ; NR_ASSIGN_AKEEBASUBS_DESC="Target visitors who have subscribed to specific Akeeba Subscriptions" ; NR_MATCH="Match" ; NR_MATCH_DESC="The used matching method to compare the value" ; NR_ASSIGN_MATCHING_METHOD="Matching Method" ; NR_ASSIGN_MATCHING_METHOD_DESC="Should all or any assignments be matched?

All
Will be published if All of below assignments are matched.

Any
Will be published if Any (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." ; NR_ANY="Any" ; NR_ALL="All" ; NR_ASSIGN_REFERRER="Referrer URL" ; NR_ASSIGN_REFERRER_DESC2="Target visitors who land on your site from a specific traffic source" ; NR_ASSIGN_REFERRER_DESC="Enter one Referrer URL per line: Eg:

google.com
facebook.com/mypage" ; NR_ASSIGN_REFERRER_NOTE="Keep in mind that URL Referrer discovery is not always 100% accurate. Some servers may use proxies that strip this information out and it can be easily forged." ; NR_PROFEATURE_HEADER="%s is a PRO Feature" ; NR_PROFEATURE_DESC="We're sorry, %s is not available on your plan. Please upgrade to the PRO plan to unlock all these awesome features." ; NR_PROFEATURE_DISCOUNT="Bonus: %s free users get 20% off regular price, automatically applied at checkout." ; NR_ONLY_AVAILABLE_IN_PRO="Only available in PRO version" ; NR_UPGRADE_TO_PRO="Upgrade to Pro" ; NR_UPGRADE_TO_PRO_TO_UNLOCK="Upgrade to Pro version to unlock" ; NR_UPGRADE_TO_PRO_VERSION="Awesome! Only one step left. Click on the button below to complete the upgrade to the Pro version." ; NR_UNLOCK_PRO_FEATURE="Unlock Pro Feature" ; NR_USING_THE_FREE_VERSION="You are using the FREE version of Convert Forms. Purchase the PRO version for the full functionality." ; NR_LEFT_TO_RIGHT="Left to Right" ; NR_RIGHT_TO_LEFT="Right to Left" ; NR_BGIMAGE="Background Image" ; NR_BGIMAGE_DESC="Sets a background image" ; NR_BGIMAGE_FILE="Image" ; NR_BGIMAGE_FILE_DESC="Select or a upload a file for the background-image." ; NR_BGIMAGE_REPEAT="Repeat" ; NR_BGIMAGE_REPEAT_DESC="The background-repeat property sets if/how a background image will be repeated. By default, a background-image is repeated both vertically and horizontally.

Repeat: The background image will be repeated both vertically and horizontally.

Repeat-x: The background image will be repeated only horizontally

Repeat-y: The background image will be repeated only vertically

No-repeat: The background-image will not be repeated" ; NR_BGIMAGE_SIZE="Size" ; NR_BGIMAGE_SIZE_DESC="Specify the size of a background image.

Auto:The background-image contains its width and height

Cover: Scale the background image to be as large as possible so that the background area is completely covered by the background image. Some parts of the background image may not be in view within the background positioning area

Contain: Scale the image to the largest size such that both its width and its height can fit inside the content area

100% 100%: Stretch the background image to completely cover the content area." ; NR_BGIMAGE_POSITION="Position" ; NR_BGIMAGE_POSITION_DESC="The background-position property sets the starting position of a background image. By default, a background-image is placed at the top-left corner. The first value is the horizontal position and the second value is the vertical.

You can use either one of the predefined values, or enter a custom value in percentage: x% y% or in pixel xPos yPos." ; NR_RTL="Enable RTL" ; NR_RTL_DESC="The right-to-left text direction is essential for right-to-left scripts such as Arabic, Hebrew, Syriac, and Thaana." ; NR_HORIZONTAL="Horizontal" ; NR_VERTICAL="Vertical" ; NR_FORM_ORIENTATION="Form Orientation" ; NR_FORM_ORIENTATION_DESC="Select the form orientation" ; NR_ASSIGN_CATEGORY="Categories" ; NR_ASSIGN_CATEGORY_DESC="Select the categories to assign to" ; NR_ASSIGN_CATEGORY_CHILD="Also on child items" ; NR_ASSIGN_CATEGORY_CHILD_DESC="Also assign to child items of the selected items?" ; NR_NEW="New" ; NR_LIST="List" ; NR_DOCUMENTATION="Documentation" ; NR_KNOWLEDGEBASE="Knowledgebase" ; NR_FAQ="FAQ" ; NR_INFORMATION="Information" ; NR_EXTENSION="Extension" ; NR_VERSION="Version" ; NR_CHANGELOG="Changelog" ; NR_DOWNLOAD="Download" ; NR_DOWNLOAD_KEY_MISSING="Download Key is missing" ; NR_DOWNLOAD_KEY="Download Key" ; NR_DOWNLOAD_KEY_DESC="To find your Download Key, log into your account on Tassos.gr and go to the Downloads section.

Note: Setting the Download Key here, doesn't upgrade Free versions to Pro versions. To unlock Pro features, you'll need to install the Pro version over the Free version too." ; NR_DOWNLOAD_KEY_HOW="To be able to update %s via the Joomla updater, you will need enter your Download Key in the settings of the Novarain Framework Plugin" ; NR_DOWNLOAD_KEY_FIND="Find Download Key" ; NR_DOWNLOAD_KEY_UPDATE="Update Download Key" ; NR_OK="OK" ; NR_MISSING="Missing" ; NR_LICENSE="License" ; NR_AUTHOR="Author" ; NR_FOLLOWME="Follow me" ; NR_FOLLOW="Follow %s" ; NR_TRANSLATE_INTEREST="Would you be interested in helping out with translating %s into your Language?" ; NR_TRANSIFEX_REQUEST="Send me a request on Transifex" ; NR_HELP_WITH_TRANSLATIONS="Help with translations" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" ; NR_ADVANCED="Advanced" ; NR_USEGLOBAL="Use Global" ; NR_WEEKDAY="Day of Week" ; NR_MONTH="Month" ; NR_MONDAY="Monday" ; NR_TUESDAY="Tuesday" ; NR_WEDNESDAY="Wednesday" ; NR_THURSDAY="Thursday" ; NR_FRIDAY="Friday" ; NR_SATURDAY="Saturday" ; NR_WEEKEND="Weekend" ; NR_WEEKDAYS="Weekdays" ; NR_SUNDAY="Sunday" ; NR_JANUARY="January" ; NR_FEBRUARY="February" ; NR_MARCH="March" ; NR_APRIL="April" ; NR_MAY="May" ; NR_JUNE="June" ; NR_JULY="July" ; NR_AUGUST="August" ; NR_SEPTEMBER="September" ; NR_OCTOBER="October" ; NR_NOVEMBER="November" ; NR_DECEMBER="December" ; NR_NEVER="Never" ; NR_SECONDS="Seconds" ; NR_MINUTES="Minutes" ; NR_HOURS="Hours" ; NR_DAYS="Days" ; NR_SESSION="Session" ; NR_EVER="Ever" ; NR_COOKIE="Cookie" ; NR_BOTH="Both" ; NR_NONE="None" ; NR_NONE_SELECTED="None Selected" ; NR_DESKTOPS="Desktop" ; NR_MOBILES="Mobile" ; NR_TABLETS="Tablet" ; NR_PER_SESSION="Per Session" ; NR_PER_DAY="Per Day" ; NR_PER_WEEK="Per Week" ; NR_PER_MONTH="Per Month" ; NR_FOREVER="Forever" ; NR_FEATURE_UNDER_DEV="This feature is under development" ; NR_LIKE_THIS_EXTENSION="Like this extension?" ; NR_LEAVE_A_REVIEW="Leave a review on JED" ; NR_SUPPORT="Support" ; NR_NEED_SUPPORT="Need support?" ; NR_DROP_EMAIL="Drop me an e-mail" ; NR_READ_DOCUMENTATION="Read the Documentation" ; NR_COPYRIGHT="%s - Tassos.gr All Rights Reserved" ; NR_DASHBOARD="Dashboard" ; NR_NAME="Name" ; NR_WRONG_COORDINATES="The coordinates you provided are not valid" ; NR_ENTER_COORDINATES="Latitude,Longitude" ; NR_NO_ITEMS_FOUND="No Items Found" ; NR_ITEM_IDS="No Item IDs" ; NR_TOGGLE="Toggle" ; NR_EXPAND="Expand" ; NR_COLLAPSE="Collapse" ; NR_SELECTED="Selected" ; NR_MAXIMIZE="Maximize" ; NR_MINIMIZE="Minimize" NR_SELECTION="Επιλογή" ; NR_INSTALL="Install" ; NR_INSTALL_NOW="Install Now" ; NR_INSTALLED="Installed" ; NR_COMING_SOON="Coming soon" ; NR_ROADMAP="On the roadmap" ; NR_MEDIA_VERSIONING="Use Media Versioning" ; NR_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." ; NR_LOAD_JQUERY="Load jQuery" ; NR_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." ; NR_SELECT_CURRENCY="Select a Currency" ; NR_CONVERTFORMS="Convert Forms" ; NR_CONVERTFORMS_LIST="Campaign" ; NR_ASSIGN_CONVERTFORMS_DESC="Target visitors who have subscribed to specific ConvertForms campaigns" ; NR_CONVERTFORMS_LIST_DESC="Select ConvertForms campaigns to assign to." ; NR_LEFT="Left" ; NR_CENTER="Center" ; NR_RIGHT="Right" ; NR_BOTTOM="Bottom" ; NR_TOP="Top" ; NR_AUTO="Auto" ; NR_CUSTOM="Custom" ; NR_UPLOAD="Upload" ; NR_IMAGE="Image" ; NR_INTRO_IMAGE="Intro Image" ; NR_FULL_IMAGE="Full Image" ; NR_IMAGE_SELECT="Select Image" ; NR_IMAGE_SIZE_COVER="Cover" ; NR_IMAGE_SIZE_CONTAIN="Contain" ; NR_REPEAT="Repeat" ; NR_REPEAT_X="Repeat x" ; NR_REPEAT_Y="Repeat y" ; NR_REPEAT_NO="No repeat" ; NR_FIELD_STATE_DESC="Set item's state" ; NR_CREATED_DATE="Created Date" ; NR_CREATED_DATE_DESC="The date the item was created" ; NR_MODIFIFED_DATE="Modified Date" ; NR_MODIFIFED_DATE_DESC="The date that the item was last modified." ; NR_CATEGORIES="Category" ; NR_CATEGORIES_DESC="Select the categories to assign to." ; NR_ALSO_ON_CHILD_ITEMS="Also on child items" ; NR_ALSO_ON_CHILD_ITEMS_DESC="Also assign to child items of the selected items?" ; NR_PAGE_TYPE="Page type" ; NR_PAGE_TYPES="Page types" ; NR_PAGE_TYPES_DESC="Select on what page types the assignment should be active." ; NR_CONTENT_VIEW_CATEGORY_BLOG="Category Blog" ; NR_CONTENT_VIEW_CATEGORY_LIST="Category List" ; NR_CONTENT_VIEW_CATEGORIES="List All Categories" ; NR_CONTENT_VIEW_ARCHIVED="Archived Articles" ; NR_CONTENT_VIEW_FEATURES="Featured Articles" ; NR_CONTENT_VIEW_CREATE_ARTICLE="Create Article" ; NR_CONTENT_VIEW_ARTICLE="Single Article" ; NR_ARTICLE_VIEW_DESC="Enable to take into account the Article view" ; NR_CATEGORY_VIEW="Category View" ; NR_CATEGORY_VIEW_DESC="Enable to take into account the Category view" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." ; NR_ARTICLES="Articles" ; NR_ARTICLES_DESC="Select the articles to assign to." ; NR_ARTICLE="Article" ; NR_ARTICLE_AUTHORS="Authors" ; NR_ARTICLE_AUTHORS_DESC="Select the authors to assign to." ; NR_ONLY="Only" ; NR_OTHERS="Others" ; NR_SMARTTAGS="Smart Tags" ; NR_SMARTTAGS_SHOW="Show Smart Tags" ; NR_SMARTTAGS_NOTFOUND="No Smart Tags found" ; NR_SMARTTAGS_SEARCH_PLACEHOLDER="Search for Smart Tags" ; NR_CONTACT_US="Contact us" ; NR_FONT_COLOR="Font Color" ; NR_FONT_SIZE="Font Size" ; NR_FONT_SIZE_DESC="Choose a font size in pixels" ; NR_TEXT="Text" ; NR_URL="URL" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE="Enable on Output Override" ; NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Enables the extension rendering when the page layout (tmpl) is overriden. Examples: tmpl=component or tmpl=modal." ; NR_EXECUTE_ON_FORMAT_OVERRIDE="Enable on Format Override" ; NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Enables the extension rendering when the page format is not other than HTML. Examples: format=raw or format=json." ; NR_GEOLOCATING="Geolocating" ; NR_GEOLOCATION="Geolocation" ; NR_GEOLOCATING_DESC="Geolocating is not always 100% accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known." ; NR_CITY="City" ; NR_CITY_NAME="City Name" ; NR_CONDITION_CITY_DESC="Enter a city name in English. Enter multiple cities separated by comma." ; NR_CONTINENT="Continent" ; NR_REGION="Region" ; NR_CONDITION_REGION_DESC="The value consists of two parts, the two letter ISO 3166-1 country code and the region code. So the value should be in the following form: COUNTRY_CODE-REGION_CODE. For a full list of region codes click on the Find a Region Code link." ; NR_ASSIGN_COUNTRIES="Country" ; NR_ASSIGN_COUNTRIES_DESC2="Target visitors who are physically in a specific country" ; NR_ASSIGN_COUNTRIES_DESC="Select the countries to assign to" ; NR_ASSIGN_CONTINENTS="Continent" ; NR_ASSIGN_CONTINENTS_DESC="Select the continents to assign to" ; NR_ASSIGN_CONTINENTS_DESC2="Target visitors who are physically in a specific continent" ; NR_ICONTACT_ACCOUNTID_ERROR="The iContact AccountID could not be retrieved" ; NR_TAG_CLIENTDEVICE="Visitor Device Type" ; NR_TAG_CLIENTOS="Visitor Operating System" ; NR_TAG_CLIENTBROWSER="Visitor Browser" ; NR_TAG_CLIENTUSERAGENT="Visitor Agent String" ; NR_TAG_IP="Visitor IP Address" ; NR_TAG_URL="Page URL" ; NR_TAG_URLENCODED="Page URL Encoded" ; NR_TAG_URLPATH="Page Path" ; NR_TAG_REFERRER="Page Referrer" ; NR_TAG_SITENAME="Site Name" ; NR_TAG_SITEURL="Site URL" ; NR_TAG_PAGETITLE="Page Title" ; NR_TAG_PAGEDESC="Page Meta Description" ; NR_TAG_PAGELANG="Page Language Code" ; NR_TAG_USERID="User ID" ; NR_TAG_USERNAME="User Full Name" ; NR_TAG_USERLOGIN="User Login" ; NR_TAG_USEREMAIL="User Email" ; NR_TAG_USERFIRSTNAME="User First Name" ; NR_TAG_USERLASTNAME="User Last Name" ; NR_TAG_USERGROUPS="User Groups IDs" ; NR_TAG_DATE="Date" ; NR_TAG_TIME="Time" ; NR_TAG_RANDOMID="Random ID" ; NR_ICON="Icon" ; NR_SELECT_MODULE="Select a Module" ; NR_SELECT_CONTINENT="Select a Continent" ; NR_SELECT_COUNTRY="Select a Country" ; NR_PLUGIN="Plugin" ; NR_GMAP_KEY="Google Maps API Key" ; NR_GMAP_KEY_DESC="The Google Maps API Key is being used by Tassos.gr extensions. If you face any troubles with a Google Map not being loaded then you probably need to enter your own API Key." ; NR_GMAP_FIND_KEY="Get an API key" ; NR_ARE_YOU_SURE="Are you sure?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" ; NR_CUSTOMURL="Custom URL" ; NR_SAMPLE="Sample" ; NR_DEBUG="Debug" ; NR_CUSTOMURL="Custom URL" ; NR_READMORE="Read More" ; NR_IPADDRESS="IP Address" ; NR_ASSIGN_BROWSERS="Browser" ; NR_ASSIGN_BROWSERS_DESC="Select the browsers to assign to" ; NR_ASSIGN_BROWSERS_DESC2="Target visitors who are browsing your site with specific browsers such as Chrome, Firefox or Internet Explorer" ; NR_CHROME="Chrome" ; NR_FIREFOX="Firefox" ; NR_EDGE="Edge" ; NR_IE="Internet Explorer" ; NR_SAFARI="Safari" ; NR_OPERA="Opera" ; NR_ASSIGN_OS="Operating System" ; NR_ASSIGN_OS_DESC="Select the operating systems to assign to" ; NR_ASSIGN_OS_DESC2="Target visitors who are using specific operating systems such as Windows, Linux or Mac" ; NR_LINUX="Linux" ; NR_MAC="MacOS" ; NR_ANDROID="Android" ; NR_IOS="iOS" ; NR_WINDOWS="Windows" ; NR_BLACKBERRY="Blackberry" ; NR_CHROMEOS="Chrome OS" ; NR_ASSIGN_PAGEVIEWS="Number of Pageviews" ; NR_ASSIGN_PAGEVIEWS_DESC="Target visitors who have viewed certain number of pages" ; NR_ASSIGN_PAGEVIEWS_VIEWS="Pageviews" ; NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Enter the number of page views" ; NR_ASSIGN_COOKIENAME_NAME="Cookie Name" ; NR_ASSIGN_COOKIENAME_NAME_DESC="Enter the name of the cookie to assign to" ; NR_ASSIGN_COOKIENAME_NAME_DESC2="Target visitors who have specific cookies stored in their browser" ; NR_FEWER_THAN="Fewer than" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" ; NR_GREATER_THAN="Greater than" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" ; NR_EXACTLY="Exactly" ; NR_EXISTS="Exists" ; NR_NOT_EXISTS="Does not exists" ; NR_IS_EQUAL="Equals" ; NR_DOES_NOT_EQUAL="Does not equal" ; NR_CONTAINS="Contains" ; NR_DOES_NOT_CONTAIN="Does not contain" ; NR_STARTS_WITH="Starts with" ; NR_DOES_NOT_START_WITH="Does not start with" ; NR_ENDS_WITH="Ends with" ; NR_DOES_NOT_END_WITH="Does not end with" ; NR_ASSIGN_COOKIENAME_CONTENT="Cookie Content" ; NR_ASSIGN_COOKIENAME_CONTENT_DESC="The cookie's content" ; NR_ASSIGN_IP_ADDRESSES_DESC2="Target visitors who are behind a specific IP address (range)" ; NR_ASSIGN_IP_ADDRESSES_DESC="Enter a list of comma and/or 'enter' separated ip addresses and ranges

Example:
127.0.0.1,
192.10-120.2,
168" ; NR_USER="User" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." ; NR_ASSIGN_USER_ID="User ID" ; NR_ASSIGN_USER_ID_DESC="Target specific Joomla Users by their IDs" ; NR_ASSIGN_USER_ID_SELECTION_DESC="Enter comma separated Joomla user IDs" ; NR_ASSIGN_COMPONENTS="Component" ; NR_ASSIGN_COMPONENTS_DESC="Select the components to assign to" ; NR_ASSIGN_COMPONENTS_DESC2="Target visitors who are browsing specific components" ; NR_ASSIGN_TIMERANGE="Time Range" ; NR_ASSIGN_TIMERANGE_DESC="Target visitors based on your server's time" ; NR_START_TIME="Start Time" ; NR_END_TIME="End Time" ; NR_START_PUBLISHING_TIMERANGE_DESC="Enter the time to start publishing" ; NR_FINISH_PUBLISHING_TIMERANGE_DESC="Enter the time to end publishing" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." ; NR_RECAPTCHA_SITE_KEY="Site Key" ; NR_RECAPTCHA_SITE_KEY_DESC="Used in the JavaScript code that is served to your users." ; NR_RECAPTCHA_SECRET_KEY="Secret Key" ; NR_RECAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret." ; NR_RECAPTCHA_SITE_KEY_ERROR="The reCaptcha Site Key is either missing or invalid" ; NR_PREVIOUS_MONTH="Previous Month" ; NR_NEXT_MONTH="Next Month" ; NR_ASSIGN_GROUP_PAGE_URL="Page / URL" ; NR_ASSIGN_GROUP_PAGE_URL_DESC="Target visitors who are browsing specific menu items or URLs" ; NR_ASSIGN_GROUP_DATETIME_DESC="Trigger a box based on your server's date and time" ; NR_ASSIGN_GROUP_USER_VISITOR="Joomla User / Visitor" ; NR_ASSIGN_GROUP_USER_VISITOR_DESC="Target registered users or visitors who have viewed a certain number of pages" ; NR_ASSIGN_GROUP_PLATFORM="Visitor Platform" ; NR_ASSIGN_GROUP_PLATFORM_DESC="Target visitors who are using Mobile, Google Chrome, or even Windows" ; NR_ASSIGN_GROUP_GEO_DESC="Target visitors who are physically in a specific region" ; NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" ; NR_ASSIGN_GROUP_JCONTENT_DESC="Target visitors who are viewing specific Joomla articles or categories" ; NR_ASSIGN_GROUP_SYSTEM="System / Integrations" ; NR_INTEGRATIONS="Integrations" ; NR_ASSIGN_GROUP_SYSTEM_DESC="Target visitors who have interacted with specific 3rd party Joomla Extensions" ; NR_ASSIGN_GROUP_ADVANCED="Advanced visitor targeting" ; NR_ASSIGN_USERGROUP_DESC="Target specific Joomla user groups" ; NR_ASSIGN_ARTICLE_DESC="Target visitors who are viewing specific Joomla articles" ; NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Target visitors who are viewing specific Joomla categories" ; NR_EXTENSION_REQUIRED="%s component requires %s plugin to be enabled in order to function properly." ; NR_ASSIGN_K2="K2" ; NR_ASSIGN_K2_DESC="Target visitors who are browsing specific K2 Items, Categories or Tags" ; NR_ASSIGN_K2_ITEMS="Item" ; NR_ASSIGN_K2_ITEMS_DESC="Target visitors who are browsing specific K2 items." ; NR_ASSIGN_K2_ITEMS_LIST_DESC="Select the K2 Items to assign to" ; NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Match on specific keywords in the item's content. Seperate by a comma or a new line." ; NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Match on the item's meta keywords. Seperate by a comma or a new line." ; NR_ASSIGN_K2_PAGETYPES_DESC="Target visitors who are browsing specific K2 page types" ; NR_ASSIGN_K2_ITEM_OPTION="Item" ; NR_ASSIGN_K2_LATEST_OPTION="Latest items from users or categories" ; NR_ASSIGN_K2_TAG_OPTION="Tag Page" ; NR_ASSIGN_K2_CATEGORY_OPTION="Category Page" ; NR_ASSIGN_K2_ITEM_FORM_OPTION="Item Edit Form" ; NR_ASSIGN_K2_USER_PAGE_OPTION="User Page (blog)" ; NR_ASSIGN_K2_TAGS_DESC="Target visitors who are browsing K2 items with specific tags" ; NR_ASSIGN_K2_CATEGORIES_DESC="Target visitors who are browsing specific K2 categories" ; NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" ; NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" ; NR_ASSIGN_PAGE_TYPES_DESC="Select the page types to assign to" ; NR_ASSIGN_TAGS_DESC="Select the tags to assign to" ; NR_CONTENT_KEYWORDS="Content keywords" ; NR_META_KEYWORDS="Meta keywords" ; NR_TAG="Tag" ; NR_NORMAL="Normal" ; NR_COMPACT="Compact" ; NR_LIGHT="Light" ; NR_DARK="Dark" ; NR_SIZE="Size" ; NR_THEME="Theme" ; NR_SINGLE="Single" ; NR_MULTIPLE="Multiple" ; NR_RANGE="Range" ; NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_PLEASE_VALIDATE="Please validate" ; NR_RECAPTCHA_INVALID_SECRET_KEY="Invalid secret key" ; NR_PAGE="Page" ; NR_YOU_ARE_USING_EXTENSION="You are using %s %s" ; NR_UPDATE="Update" ; NR_SHOW_UPDATE_NOTIFICATION="Show Update Notification" ; NR_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." ; NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s is available" ; NR_ERROR_EMAIL_IS_DISABLED="Mail sending is turned off. Emails could not be sent." ; NR_ASSIGN_ITEMS="Item" ; NR_COUNTRY_AF="Afghanistan" ; NR_COUNTRY_AX="Aland Islands" ; NR_COUNTRY_AL="Albania" ; NR_COUNTRY_DZ="Algeria" ; NR_COUNTRY_AS="American Samoa" ; NR_COUNTRY_AD="Andorra" ; NR_COUNTRY_AO="Angola" ; NR_COUNTRY_AI="Anguilla" ; NR_COUNTRY_AQ="Antarctica" ; NR_COUNTRY_AG="Antigua and Barbuda" ; NR_COUNTRY_AR="Argentina" ; NR_COUNTRY_AM="Armenia" ; NR_COUNTRY_AW="Aruba" ; NR_COUNTRY_AU="Australia" ; NR_COUNTRY_AT="Austria" ; NR_COUNTRY_AZ="Azerbaijan" ; NR_COUNTRY_BS="Bahamas" ; NR_COUNTRY_BH="Bahrain" ; NR_COUNTRY_BD="Bangladesh" ; NR_COUNTRY_BB="Barbados" ; NR_COUNTRY_BY="Belarus" ; NR_COUNTRY_BE="Belgium" ; NR_COUNTRY_BZ="Belize" ; NR_COUNTRY_BJ="Benin" ; NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" ; NR_COUNTRY_BT="Bhutan" ; NR_COUNTRY_BO="Bolivia" ; NR_COUNTRY_BA="Bosnia and Herzegovina" ; NR_COUNTRY_BW="Botswana" ; NR_COUNTRY_BV="Bouvet Island" ; NR_COUNTRY_BR="Brazil" ; NR_COUNTRY_IO="British Indian Ocean Territory" ; NR_COUNTRY_BN="Brunei Darussalam" ; NR_COUNTRY_BG="Bulgaria" ; NR_COUNTRY_BF="Burkina Faso" ; NR_COUNTRY_BI="Burundi" ; NR_COUNTRY_KH="Cambodia" ; NR_COUNTRY_CM="Cameroon" ; NR_COUNTRY_CA="Canada" ; NR_COUNTRY_CV="Cape Verde" ; NR_COUNTRY_KY="Cayman Islands" ; NR_COUNTRY_CF="Central African Republic" ; NR_COUNTRY_TD="Chad" ; NR_COUNTRY_CL="Chile" ; NR_COUNTRY_CN="China" ; NR_COUNTRY_CX="Christmas Island" ; NR_COUNTRY_CC="Cocos (Keeling) Islands" ; NR_COUNTRY_CO="Colombia" ; NR_COUNTRY_KM="Comoros" ; NR_COUNTRY_CG="Congo" ; NR_COUNTRY_CD="Congo, The Democratic Republic of the" ; NR_COUNTRY_CK="Cook Islands" ; NR_COUNTRY_CR="Costa Rica" ; NR_COUNTRY_CI="Cote d'Ivoire" ; NR_COUNTRY_HR="Croatia" ; NR_COUNTRY_CU="Cuba" ; NR_COUNTRY_CW="Curaçao" ; NR_COUNTRY_CY="Cyprus" ; NR_COUNTRY_CZ="Czech Republic" ; NR_COUNTRY_DK="Denmark" ; NR_COUNTRY_DJ="Djibouti" ; NR_COUNTRY_DM="Dominica" ; NR_COUNTRY_DO="Dominican Republic" ; NR_COUNTRY_EC="Ecuador" ; NR_COUNTRY_EG="Egypt" ; NR_COUNTRY_SV="El Salvador" ; NR_COUNTRY_GQ="Equatorial Guinea" ; NR_COUNTRY_ER="Eritrea" ; NR_COUNTRY_EE="Estonia" ; NR_COUNTRY_ET="Ethiopia" ; NR_COUNTRY_FK="Falkland Islands (Malvinas)" ; NR_COUNTRY_FO="Faroe Islands" ; NR_COUNTRY_FJ="Fiji" ; NR_COUNTRY_FI="Finland" ; NR_COUNTRY_FR="France" ; NR_COUNTRY_GF="French Guiana" ; NR_COUNTRY_PF="French Polynesia" ; NR_COUNTRY_TF="French Southern Territories" ; NR_COUNTRY_GA="Gabon" ; NR_COUNTRY_GM="Gambia" ; NR_COUNTRY_GE="Georgia" ; NR_COUNTRY_DE="Germany" ; NR_COUNTRY_GH="Ghana" ; NR_COUNTRY_GI="Gibraltar" NR_COUNTRY_GR="Ελλάδα" ; NR_COUNTRY_GL="Greenland" ; NR_COUNTRY_GD="Grenada" ; NR_COUNTRY_GP="Guadeloupe" ; NR_COUNTRY_GU="Guam" ; NR_COUNTRY_GT="Guatemala" ; NR_COUNTRY_GG="Guernsey" ; NR_COUNTRY_GN="Guinea" ; NR_COUNTRY_GW="Guinea-Bissau" ; NR_COUNTRY_GY="Guyana" ; NR_COUNTRY_HT="Haiti" ; NR_COUNTRY_HM="Heard Island and McDonald Islands" ; NR_COUNTRY_VA="Holy See (Vatican City State)" ; NR_COUNTRY_HN="Honduras" ; NR_COUNTRY_HK="Hong Kong" ; NR_COUNTRY_HU="Hungary" ; NR_COUNTRY_IS="Iceland" ; NR_COUNTRY_IN="India" ; NR_COUNTRY_ID="Indonesia" ; NR_COUNTRY_IR="Iran, Islamic Republic of" ; NR_COUNTRY_IQ="Iraq" ; NR_COUNTRY_IE="Ireland" ; NR_COUNTRY_IM="Isle of Man" ; NR_COUNTRY_IL="Israel" ; NR_COUNTRY_IT="Italy" ; NR_COUNTRY_JM="Jamaica" ; NR_COUNTRY_JP="Japan" ; NR_COUNTRY_JE="Jersey" ; NR_COUNTRY_JO="Jordan" ; NR_COUNTRY_KZ="Kazakhstan" ; NR_COUNTRY_KE="Kenya" ; NR_COUNTRY_KI="Kiribati" ; NR_COUNTRY_KP="Korea, Democratic People's Republic of" ; NR_COUNTRY_KR="Korea, Republic of" ; NR_COUNTRY_KW="Kuwait" ; NR_COUNTRY_KG="Kyrgyzstan" ; NR_COUNTRY_LA="Lao People's Democratic Republic" ; NR_COUNTRY_LV="Latvia" ; NR_COUNTRY_LB="Lebanon" ; NR_COUNTRY_LS="Lesotho" ; NR_COUNTRY_LR="Liberia" ; NR_COUNTRY_LY="Libyan Arab Jamahiriya" ; NR_COUNTRY_LI="Liechtenstein" ; NR_COUNTRY_LT="Lithuania" ; NR_COUNTRY_LU="Luxembourg" ; NR_COUNTRY_MO="Macao" ; NR_COUNTRY_MK="Macedonia" ; NR_COUNTRY_MG="Madagascar" ; NR_COUNTRY_MW="Malawi" ; NR_COUNTRY_MY="Malaysia" ; NR_COUNTRY_MV="Maldives" ; NR_COUNTRY_ML="Mali" ; NR_COUNTRY_MT="Malta" ; NR_COUNTRY_MH="Marshall Islands" ; NR_COUNTRY_MQ="Martinique" ; NR_COUNTRY_MR="Mauritania" ; NR_COUNTRY_MU="Mauritius" ; NR_COUNTRY_YT="Mayotte" ; NR_COUNTRY_MX="Mexico" ; NR_COUNTRY_FM="Micronesia, Federated States of" ; NR_COUNTRY_MD="Moldova, Republic of" ; NR_COUNTRY_MC="Monaco" ; NR_COUNTRY_MN="Mongolia" ; NR_COUNTRY_ME="Montenegro" ; NR_COUNTRY_MS="Montserrat" ; NR_COUNTRY_MA="Morocco" ; NR_COUNTRY_MZ="Mozambique" ; NR_COUNTRY_MM="Myanmar" ; NR_COUNTRY_NA="Namibia" ; NR_COUNTRY_NR="Nauru" ; NR_COUNTRY_NM="North Macedonia" ; NR_COUNTRY_NP="Nepal" ; NR_COUNTRY_NL="Netherlands" ; NR_COUNTRY_AN="Netherlands Antilles" ; NR_COUNTRY_NC="New Caledonia" ; NR_COUNTRY_NZ="New Zealand" ; NR_COUNTRY_NI="Nicaragua" ; NR_COUNTRY_NE="Niger" ; NR_COUNTRY_NG="Nigeria" ; NR_COUNTRY_NU="Niue" ; NR_COUNTRY_NF="Norfolk Island" ; NR_COUNTRY_MP="Northern Mariana Islands" ; NR_COUNTRY_NO="Norway" ; NR_COUNTRY_OM="Oman" ; NR_COUNTRY_PK="Pakistan" ; NR_COUNTRY_PW="Palau" ; NR_COUNTRY_PS="Palestinian Territory" ; NR_COUNTRY_PA="Panama" ; NR_COUNTRY_PG="Papua New Guinea" ; NR_COUNTRY_PY="Paraguay" ; NR_COUNTRY_PE="Peru" ; NR_COUNTRY_PH="Philippines" ; NR_COUNTRY_PN="Pitcairn" ; NR_COUNTRY_PL="Poland" ; NR_COUNTRY_PT="Portugal" ; NR_COUNTRY_PR="Puerto Rico" ; NR_COUNTRY_QA="Qatar" ; NR_COUNTRY_RE="Reunion" ; NR_COUNTRY_RO="Romania" ; NR_COUNTRY_RU="Russian Federation" ; NR_COUNTRY_RW="Rwanda" ; NR_COUNTRY_SH="Saint Helena" ; NR_COUNTRY_KN="Saint Kitts and Nevis" ; NR_COUNTRY_LC="Saint Lucia" ; NR_COUNTRY_PM="Saint Pierre and Miquelon" ; NR_COUNTRY_VC="Saint Vincent and the Grenadines" ; NR_COUNTRY_WS="Samoa" ; NR_COUNTRY_SM="San Marino" ; NR_COUNTRY_ST="Sao Tome and Principe" ; NR_COUNTRY_SA="Saudi Arabia" ; NR_COUNTRY_SN="Senegal" ; NR_COUNTRY_RS="Serbia" ; NR_COUNTRY_SC="Seychelles" ; NR_COUNTRY_SL="Sierra Leone" ; NR_COUNTRY_SG="Singapore" ; NR_COUNTRY_SK="Slovakia" ; NR_COUNTRY_SI="Slovenia" ; NR_COUNTRY_SB="Solomon Islands" ; NR_COUNTRY_SO="Somalia" ; NR_COUNTRY_ZA="South Africa" ; NR_COUNTRY_GS="South Georgia and the South Sandwich Islands" ; NR_COUNTRY_ES="Spain" ; NR_COUNTRY_LK="Sri Lanka" ; NR_COUNTRY_SD="Sudan" ; NR_COUNTRY_SS="South Sudan" ; NR_COUNTRY_SR="Suriname" ; NR_COUNTRY_SJ="Svalbard and Jan Mayen" ; NR_COUNTRY_SZ="Swaziland" ; NR_COUNTRY_SE="Sweden" ; NR_COUNTRY_CH="Switzerland" ; NR_COUNTRY_SY="Syrian Arab Republic" ; NR_COUNTRY_TW="Taiwan" ; NR_COUNTRY_TJ="Tajikistan" ; NR_COUNTRY_TZ="Tanzania, United Republic of" ; NR_COUNTRY_TH="Thailand" ; NR_COUNTRY_TL="Timor-Leste" ; NR_COUNTRY_TG="Togo" ; NR_COUNTRY_TK="Tokelau" ; NR_COUNTRY_TO="Tonga" ; NR_COUNTRY_TT="Trinidad and Tobago" ; NR_COUNTRY_TN="Tunisia" ; NR_COUNTRY_TR="Turkey" ; NR_COUNTRY_TM="Turkmenistan" ; NR_COUNTRY_TC="Turks and Caicos Islands" ; NR_COUNTRY_TV="Tuvalu" ; NR_COUNTRY_UG="Uganda" ; NR_COUNTRY_UA="Ukraine" ; NR_COUNTRY_AE="United Arab Emirates" ; NR_COUNTRY_GB="United Kingdom" ; NR_COUNTRY_US="United States" ; NR_COUNTRY_UM="United States Minor Outlying Islands" ; NR_COUNTRY_UY="Uruguay" ; NR_COUNTRY_UZ="Uzbekistan" ; NR_COUNTRY_VU="Vanuatu" ; NR_COUNTRY_VE="Venezuela" ; NR_COUNTRY_VN="Vietnam" ; NR_COUNTRY_VG="Virgin Islands, British" ; NR_COUNTRY_VI="Virgin Islands, U.S." ; NR_COUNTRY_WF="Wallis and Futuna" ; NR_COUNTRY_EH="Western Sahara" ; NR_COUNTRY_YE="Yemen" ; NR_COUNTRY_ZM="Zambia" ; NR_COUNTRY_ZW="Zimbabwe" ; NR_CONTINENT_AF="Africa" ; NR_CONTINENT_AS="Asia" ; NR_CONTINENT_EU="Europe" ; NR_CONTINENT_NA="North America" ; NR_CONTINENT_SA="South America" ; NR_CONTINENT_OC="Oceania" ; NR_CONTINENT_AN="Antarctica" ; NR_FRONTEND="Front-end" ; NR_BACKEND="Back-end" ; NR_EMBED="Embed" ; NR_RATE="Rate %s" ; NR_REPORT_ISSUE="Report an issue" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" ; NR_CANNOT_CREATE_FOLDER="Can't create folder to move file. %s" ; NR_CANNOT_MOVE_FILE="Can't move file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." ; NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file: %s" ; NR_START_OVER="Start over" ; NR_TRY_AGAIN="Try again" ; NR_ERROR="Error" ; NR_CANCEL="Cancel" ; NR_PLEASE_WAIT="Please wait" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!)ЩBsystem/nrframework/language/de-DE/de-DE.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - used by Tassos.gr extensions" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignorieren" NR_INCLUDE="Einbeziehen" NR_EXCLUDE="Ausschließen" NR_SELECTION="Auswählen" NR_ASSIGN_MENU_NOITEM="Enthält keine Artikel-Nummer" NR_ASSIGN_MENU_NOITEM_DESC="Zuweisen, auch wenn kein Menü Artikel-ID in URL gesetzt ist?" NR_ASSIGN_MENU_CHILD="Auch für untergeordnete Elemente" NR_ASSIGN_MENU_CHILD_DESC="Auch untergeordneten Elementen der ausgewählten Elemente zuweisen?" NR_COPY_OF="Kopie der %s" NR_ASSIGN_DATETIME_DESC="Besucher basierend auf der Datums- / Uhrzeit Ihres Servers ansprechen" NR_DATETIME="Datum & Uhrzeit" NR_TIME="Zeit" NR_DATE="Datum" NR_DATETIME_DESC="Eintragen der Tageszeit zum automatischen veröffentlichen/sperren" NR_START_PUBLISHING="Startzeit" NR_START_PUBLISHING_DESC="Geben Sie das Datum der Veröffentlichung an" NR_FINISH_PUBLISHING="Endzeit" NR_FINISH_PUBLISHING_DESC="Geben Sie das Datum des Veröffentlichung Ende an" NR_DATETIME_NOTE="Die Datums- und Zeitzuordnungen des Server verwenden, nicht die des Besucher Systems." NR_ASSIGN_PHP="PHP" NR_PHPCODE="PHP Kode" NR_ASSIGN_PHP_DESC="Geben Sie einen PHP-Kode ein, der ausgewertet werden soll." NR_ASSIGN_PHP_DESC2="Richten Sie sich an Besucher, die benutzerdefinierten PHP-Code bewerten. Der Code muss den Wert true oder false zurückgeben.

For instance:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Nutzungszeit auf Seite" NR_SECONDS="Sekunden" NR_ASSIGN_TIMEONSITE_DESC="Geben Sie eine Dauer in Sekunden an, mit der Benutzergesamtzeit, die mit der verbrachten Verweildauer vergleichen wird.
Beispiel: KONTAKT Wenn ein Feld angezeigt werden soll, nachdem der Benutzer 3 Minuten auf der Webseite verbracht hat, geben Sie 180 ein." NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Target visitors who are browsing specific URLs" NR_ASSIGN_URLS_DESC="Geben Sie die URLs an die passen (Teilbereich).
Verwenden Sie für jede einzelne Bereich eine neue Zeile." NR_ASSIGN_URLS_LIST="URL Übereinstimmung" NR_ASSIGN_URLS_REGEX="Use Regular Expression" NR_ASSIGN_URLS_REGEX_DESC="Wählen Sie den Wert der als reguläre Ausdrücke behandelt werden soll." NR_ASSIGN_LANGS="Sprache" NR_ASSIGN_LANGS_DESC="Richten Sie sich an Besucher, die auf Ihrer Website in einer bestimmten Sprache surfen" NR_ASSIGN_LANGS_LIST_DESC="Sprache wählen" NR_ASSIGN_DEVICES="Geräte" NR_ASSIGN_DEVICES_DESC2="Richten Sie sich an Besucher, die auf Ihrer Website mit einen bestimmten Gerät surfen." NR_ASSIGN_DEVICES_DESC="Ordnen Sie die Geräte zu." NR_ASSIGN_DEVICES_NOTE="Beachten Sie, dass die Geräteerkennung nicht immer 100% genau ist. Benutzer können ihren Browser so einrichten, dass er andere Geräte nachahmt" NR_MENU="Menü" NR_MENU_ITEMS="Menüpunkt" NR_MENU_ITEMS_DESC="Target visitors who are browsing specific menu items" NR_USERGROUP="Benutzergruppe" NR_USERGROUP_DESC="Wählen Sie die Benutzergruppen aus, die Sie zuweisen möchten.

Hinweis: Wenn Sie es veröffentlichen wollen, stellen Sie einfach auf Ignorieren und wählen Sie nicht die Option Öffentlich." NR_ACCESSLEVEL="Nutzergruppe" NR_USERACCESSLEVEL="Benutzer-Zugriffsebene" NR_USERACCESSLEVEL_DESC="Wählen Sie die Zugriffsebenen aus, die Sie den Benutzern zuweisen möchten." NR_SHOW_COPYRIGHT="Zeige Copyright" NR_SHOW_COPYRIGHT_DESC="Wenn diese Option ausgewählt ist, werden zusätzliche Copyright-Informationen in den Administratoransichten angezeigt. Die Erweiterungen von Tassos.gr zeigen keine Copyright-Informationen oder Backlinks im Frontend an." NR_WIDTH="Breite" NR_WIDTH_DESC="Füge die Breite in px, em hinzu %

Example: 400px" NR_HEIGHT="Height" NR_HEIGHT_DESC="Füge die Höhe in px, em hinzu %

Example: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Füge padding in px, em hinzu %

Example: 20px" NR_MARGIN="Abstand" NR_MARGIN_DESC="Die CSS-Randeigenschaft wird verwendet, um Platz um das Feld zu generieren und die Größe des Leerraums außerhalb des Rahmens in Pixel oder in% festzulegen.

Beispiel 1: 25px
Beispiel 2: 5%

Festlegen des Rands für jede Seite [oben rechts unten links]:

Nur Oberseite: 25px 0 0 0
Nur rechte Seite: 0 25px 0 0
Nur Unterseite : 0 0 25px 0
Nur linke Seite: 0 0 0 25px " NR_COLOR_HOVER="Schwebefarbe" NR_COLOR="Farbe" NR_COLOR_DESC="Definiere eine Farbe im HEX oder RGBA Format." NR_TEXT_COLOR="Textfarbe" NR_BACKGROUND="Hintergrund" NR_BACKGROUND_COLOR="Hintergrundfarbe" NR_BACKGROUND_COLOR_DESC="Definieren Sie eine Hintergrundfarbe im HEX- oder RGBA-Format. Zum Deaktivieren geben Sie 'none' ein. Für absolute Transparenz geben Sie 'transparent' ein." NR_URL_SHORTENING_FAILED="Kürzung %s mit %s gescheitert. %s." NR_EXPORT="Export" NR_IMPORT="Import" NR_PLEASE_CHOOSE_A_VALID_FILE="Bitte wählen Sie einen erlaubten Dateinamen" NR_IMPORT_ITEMS="Importiere Artikel" NR_PUBLISH_ITEMS="veröffentliche Artikel" NR_AS_EXPORTED="als exportierte" NR_TITLE="Titel" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="AcyMailing Liste" NR_ACYMAILING_LIST_DESC="AcyMailing-Listen zum Zuweisen auswählen." NR_ASSIGN_ACYMAILING_DESC="Besucher ansprechen, die bestimmte AcyMailing-Listen abonniert haben" NR_AKEEBASUBS="Akeeba Abonnements" NR_AKEEBASUBS_LEVELS="Levels" NR_AKEEBASUBS_LEVELS_DESC="Wählen Sie die Akeeba-Abonnementebenen aus, denen Sie zuweisen möchten." NR_ASSIGN_AKEEBASUBS_DESC="Besucher ansprechen, die bestimmte Akeeba-Abonnements abonniert haben" NR_MATCH="Übereinstimmung" NR_MATCH_DESC="Die verwendete Matching-Methode zum Vergleichen des Wertes" NR_ASSIGN_MATCHING_METHOD="Abstimmungsmethode" NR_ASSIGN_MATCHING_METHOD_DESC="Sollten alle oder irgendwelche Zuordnungen übereinstimmen?

Alle
Wird veröffentlicht, wenn Alle der unten angegebenen Zuordnungen übereinstimmen.

Beliebig
Wird veröffentlicht, wenn Beliebig (eine oder mehrere) der folgenden Zuordnungen übereinstimmen.
Zuordnungsgruppen, in denen ' \"Ignorieren\" wird ignoriert. " NR_ANY="irgendeine" NR_ALL="Alle" NR_ASSIGN_REFERRER="Referenz URL" NR_ASSIGN_REFERRER_DESC2="Besucher ansprechen, die von einer bestimmten Verkehrsquelle auf Ihrer Website landen" NR_ASSIGN_REFERRER_DESC="Geben Sie eine Referrer-URL pro Zeile ein: ZB:

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Beachten Sie, dass die Erkennung von URL-Verweisen nicht immer 100% genau ist. Einige Server verwenden möglicherweise Proxys, die diese Informationen entfernen, und sie können leicht gefälscht werden.\"" NR_PROFEATURE_HEADER="%s ist eine PRO Eigenschaft" NR_PROFEATURE_DESC="Entschuldigung, %s ist nicht verfügbar in Ihre Abonnement. Bitte auf PRO upgraden um dieses Eigenschaft nutzen zu können" NR_PROFEATURE_DISCOUNT="Bonus: %s Sie bekommen von uns persönliche Rabbat 20% von reguläre Preis automatisch bei Vertragsabschluß und Bezahlung." NR_ONLY_AVAILABLE_IN_PRO="nur in der PRO-Version enthalten" NR_UPGRADE_TO_PRO="auf PRO-Version upgraden" NR_UPGRADE_TO_PRO_TO_UNLOCK="zur Freigabe auf PRO-Version upgraden" NR_UPGRADE_TO_PRO_VERSION="Super! Nur noch ein Schritt. Klicken Sie auf die Schaltfläche unten, um das Upgrade auf die Pro-Version abzuschließen." NR_UNLOCK_PRO_FEATURE="Pro Eigenschaften freischalten" NR_USING_THE_FREE_VERSION="Sie verwenden die KOSTENLOSE Version von Convert Forms. Für die volle Funktionalität ist die PRO-Version erforderlich." NR_LEFT_TO_RIGHT="von Links nach Rechts" NR_RIGHT_TO_LEFT="von Rechts nach Links" NR_BGIMAGE="Hintergrundbild" NR_BGIMAGE_DESC="setze ein Hintergrundbild" NR_BGIMAGE_FILE="Bild" NR_BGIMAGE_FILE_DESC="wähle ein Bild aus oder lade es hoch" NR_BGIMAGE_REPEAT="wiederhole" NR_BGIMAGE_REPEAT_DESC="Die Eigenschaft\" Hintergrundwiederholung \"legt fest, ob / wie ein Hintergrundbild wiederholt wird. Standardmäßig wird ein Hintergrundbild sowohl vertikal als auch horizontal wiederholt.

Wiederholen: Das Hintergrundbild wird sowohl vertikal als auch wiederholt horizontal.

Repeat-x: Das Hintergrundbild wird nur horizontal wiederholt.

Repeat-y: Das Hintergrundbild wird nur vertikal wiederholt.

No-repeat: Der Hintergrund -Bild wird nicht wiederholt " NR_BGIMAGE_SIZE="Größe" NR_BGIMAGE_SIZE_DESC="Geben Sie die Größe eines Hintergrundbilds an.

Auto: Das Hintergrundbild enthält Breite und Höhe.

Cover: Skalieren Sie das Hintergrundbild so groß wie möglich, damit der Hintergrund erscheint Bereich wird vollständig vom Hintergrundbild abgedeckt. Einige Teile des Hintergrundbilds werden möglicherweise nicht im Bereich für die Hintergrundpositionierung angezeigt.

Enthalten: Skalieren Sie das Bild auf die größte Größe, sodass sowohl seine Breite als auch seine Höhe passen im Inhaltsbereich

100% 100%: Dehnen Sie das Hintergrundbild, um den Inhaltsbereich vollständig zu bedecken. " NR_BGIMAGE_POSITION="Position" NR_BGIMAGE_POSITION_DESC="Die Eigenschaft\" Hintergrundposition \"legt die Startposition eines Hintergrundbilds fest. Standardmäßig wird ein Hintergrundbild in der oberen linken Ecke platziert. Der erste Wert ist die horizontale Position und der zweite Wert ist die vertikale.

Sie können entweder einen der vordefinierten Werte verwenden oder einen benutzerdefinierten Wert in Prozent eingeben: x% y% oder in Pixel xPos yPos. " NR_RTL="erlaube RTL" NR_RTL_DESC="Die Textrichtung von rechts nach links ist für Skripte von rechts nach links wie Arabisch, Hebräisch, Syrisch und Thaana von wesentlicher Bedeutung." NR_HORIZONTAL="Horizontal" NR_VERTICAL="Vertikal" NR_FORM_ORIENTATION="Formularausrichtung" NR_FORM_ORIENTATION_DESC="wähle die Formularausrichtung" NR_ASSIGN_CATEGORY="Kategorien" NR_ASSIGN_CATEGORY_DESC="wähle eine Kategorie im Kontext zu" NR_ASSIGN_CATEGORY_CHILD="auch in den Unterbereichen" NR_ASSIGN_CATEGORY_CHILD_DESC="Also assign to child items of the selected items?" NR_NEW="Neu" NR_LIST="Liste" NR_DOCUMENTATION="Dokumentation" NR_KNOWLEDGEBASE="Wissensdatenbank" NR_FAQ="FAQ" NR_INFORMATION="Information" NR_EXTENSION="Erweiterung" NR_VERSION="Version" NR_CHANGELOG="Änderungsverlauf" NR_DOWNLOAD="Download" NR_DOWNLOAD_KEY_MISSING="Download-Schlüssel fehlt" NR_DOWNLOAD_KEY="Downloadschlüssel" NR_DOWNLOAD_KEY_DESC="Um Ihren Download-Schlüssel zu finden, melden Sie sich in Ihrem Konto auf Tassos.gr an und gehen Sie zum Bereich Downloads.

Hinweis: Wenn Sie hier den Download-Schlüssel festlegen, werden kostenlose Versionen nicht auf Pro-Versionen aktualisiert. Um die Pro-Funktionen freizuschalten, müssen Sie die Pro-Version auch über die kostenlose Version installieren." NR_DOWNLOAD_KEY_HOW="Um %s über den Joomla-Updater aktualisieren zu können, müssen Sie Ihren Download-Schlüssel in den Einstellungen des Novarain Framework-Plugins eingeben." NR_DOWNLOAD_KEY_FIND="finde den Downloadschlüssel" NR_DOWNLOAD_KEY_UPDATE="aktualisiere den Downloadschlüssel" NR_OK="OK" NR_MISSING="nicht auffindbar" NR_LICENSE="Lizenz" NR_AUTHOR="Autor" NR_FOLLOWME="Folge mir" NR_FOLLOW="Folge %en" NR_TRANSLATE_INTEREST="Sind Sie interessiert, bei der Übersetzung %s in Ihre Sprache zu helfen?" NR_TRANSIFEX_REQUEST="senden Sie mir eine Anfrage über Transiflex" NR_HELP_WITH_TRANSLATIONS="hilf mit Transiflex" NR_PUBLISHING_ASSIGNMENTS="Publishing Assignments" NR_ADVANCED="Erweitert" NR_USEGLOBAL="nutze es generell" NR_WEEKDAY="Wochentag" NR_MONTH="Monat" NR_MONDAY="Montag" NR_TUESDAY="Dienstag" NR_WEDNESDAY="Mittwoch" NR_THURSDAY="Donnerstag" NR_FRIDAY="Freitag" NR_SATURDAY="Samstag" NR_WEEKEND="Wochenende" NR_WEEKDAYS="Wochentage" NR_SUNDAY="Sonntag" NR_JANUARY="Januar" NR_FEBRUARY="Februar" NR_MARCH="März" NR_APRIL="April" NR_MAY="Mai" NR_JUNE="Juni" NR_JULY="Juli" NR_AUGUST="August" NR_SEPTEMBER="September" NR_OCTOBER="Oktober" NR_NOVEMBER="November" NR_DECEMBER="Dezember" NR_NEVER="Niemals" NR_SECONDS="Sekunden" NR_MINUTES="Minuten" NR_HOURS="Stunden" NR_DAYS="Tage" NR_SESSION="Sitzung" NR_EVER="Immer" NR_COOKIE="Cookie" NR_BOTH="Beide" NR_NONE="Nicht" NR_NONE_SELECTED="Keine ausgewählt" NR_DESKTOPS="Computer" NR_MOBILES="Mobiltelefon" NR_TABLETS="Tablet" NR_PER_SESSION="pro Sitzung" NR_PER_DAY="pro Tag" NR_PER_WEEK="pro Woche" NR_PER_MONTH="pro Monat" NR_FOREVER="Dauerhaft" NR_FEATURE_UNDER_DEV="Diese Funktion ist noch in der Entwicklung" NR_LIKE_THIS_EXTENSION="Sie mögen diese Erweiterung?" NR_LEAVE_A_REVIEW="Bewerten Sie auf JED" NR_SUPPORT="Unterstützung" NR_NEED_SUPPORT="eine Unterstützung wird benötigt?" NR_DROP_EMAIL="senden Sie mir eine Email" NR_READ_DOCUMENTATION="Lsen Sie die Dokumentation" NR_COPYRIGHT="%s - Tassos.gr All Rights Reserved" NR_DASHBOARD="Oberfläche" NR_NAME="Name" NR_WRONG_COORDINATES="Die angegebenen Koordinaten sind nicht korrekt" NR_ENTER_COORDINATES="Latitude,Longitude" NR_NO_ITEMS_FOUND="keine Einträge gefunden" NR_ITEM_IDS="keine Eintrags-ID" NR_TOGGLE="Toggle" NR_EXPAND="ausklappen" NR_COLLAPSE="zusammenklappen" NR_SELECTED="ausgewählt" NR_MAXIMIZE="vergrößern" NR_MINIMIZE="Verkleinern" NR_SELECTION="Auswählen" NR_INSTALL="Installieren" NR_INSTALL_NOW="jetzt installlieren" NR_INSTALLED="Installiert" NR_COMING_SOON="kommt demnächst" NR_ROADMAP="Geplant" NR_MEDIA_VERSIONING="nutze Medienversionierung" NR_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." NR_LOAD_JQUERY="Lade jQuery" NR_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." NR_SELECT_CURRENCY="wähle eine Währung" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Kampaign" NR_ASSIGN_CONVERTFORMS_DESC="Besucher ansprechen, die bestimmte ConvertForms-Kampagnen abonniert haben" NR_CONVERTFORMS_LIST_DESC="ConvertForms-Kampagnen auswählen, denen sie zugewiesen werden sollen." NR_LEFT="links" NR_CENTER="zentriert" NR_RIGHT="rechts" NR_BOTTOM="unten" NR_TOP="oben" NR_AUTO="automatisch" NR_CUSTOM="Benutzerdefiniert" NR_UPLOAD="Hochladen" NR_IMAGE="Bild" NR_INTRO_IMAGE="Intro Bild" NR_FULL_IMAGE="Gesamtbild" NR_IMAGE_SELECT="wähle Bild" NR_IMAGE_SIZE_COVER="Hülle" NR_IMAGE_SIZE_CONTAIN="Contain" NR_REPEAT="wiederhole" NR_REPEAT_X="wiederhole x" NR_REPEAT_Y="wiederhole y" NR_REPEAT_NO="nicht wiederholen" NR_FIELD_STATE_DESC="setze Eintragsstatus" NR_CREATED_DATE="erstelle Datum" NR_CREATED_DATE_DESC="das Datum des Eintrags wurde erstellt" NR_MODIFIFED_DATE="ändere Datum" NR_MODIFIFED_DATE_DESC="The date that the item was last modified." NR_CATEGORIES="Kategorie" NR_CATEGORIES_DESC="Wählen Sie die Kategorien aus, denen Sie zuweisen möchten." NR_ALSO_ON_CHILD_ITEMS="auch bei den Untereinheiten" NR_ALSO_ON_CHILD_ITEMS_DESC="Auch untergeordneten Elementen der ausgewählten Elemente zuweisen?" NR_PAGE_TYPE="Seitentyp" NR_PAGE_TYPES="Seitentyp" NR_PAGE_TYPES_DESC="Wählen Sie aus, auf welchen Seitentypen die Zuordnung aktiv sein soll." NR_CONTENT_VIEW_CATEGORY_BLOG="Kategorien-Blog" NR_CONTENT_VIEW_CATEGORY_LIST="Kategorien-Liste" NR_CONTENT_VIEW_CATEGORIES="Alle Kategorien auflisten" NR_CONTENT_VIEW_ARCHIVED="Archivierte Artikel" NR_CONTENT_VIEW_FEATURES="Besondere Artikel" NR_CONTENT_VIEW_CREATE_ARTICLE="Artikel erstellen" NR_CONTENT_VIEW_ARTICLE="Einzelner Artikel" NR_ARTICLE_VIEW_DESC="Artikelansicht berücksichtigen" NR_CATEGORY_VIEW="Kategorieansicht" NR_CATEGORY_VIEW_DESC="Zur Berücksichtigung der Kategorieansicht aktivieren" NR_CONTENT_VIEW="Ansicht der Inhaltskomponente" NR_CONTENT_VIEW_DESC="Wählen Sie die Ansichten aus, die Sie zuordnen möchten." NR_ARTICLES="Artikel" NR_ARTICLES_DESC="wähle die Artikel im Kontext dazu." NR_ARTICLE="Artikel" NR_ARTICLE_AUTHORS="Autor" NR_ARTICLE_AUTHORS_DESC="wähle die Autoren im Kontext dazu." NR_ONLY="allein" NR_OTHERS="Andere" NR_SMARTTAGS="Smart Tags" NR_SMARTTAGS_SHOW="zeige smarte Tags" NR_SMARTTAGS_NOTFOUND="Keine Smarte Tags gefunden" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Smarte Tags finden" NR_CONTACT_US="Kontaktiere uns" NR_FONT_COLOR="Schriftfarbe" NR_FONT_SIZE="Schriftgröße" NR_FONT_SIZE_DESC="wähle die Schriftgröße in Pixel" NR_TEXT="Text" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Bei Ausgabeüberschreibung aktivieren" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Aktiviert das Rendering der Erweiterung, wenn das Seitenlayout (tmpl) überschrieben wird. Beispiele: tmpl = Komponente oder tmpl = Modal." NR_EXECUTE_ON_FORMAT_OVERRIDE="Bei Formatüberschreibung aktivieren" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Aktiviert das Rendering der Erweiterung, wenn das Seitenformat kein anderes als HTML ist. Beispiele: format = raw oder format = json." NR_GEOLOCATING="Geolocating" NR_GEOLOCATION="Geolokalisierung" NR_GEOLOCATING_DESC="Die Geolokalisierung ist nicht immer 100% genau. Die Geolokalisierung basiert auf der IP-Adresse des Besuchers. Nicht alle IP-Adressen sind fest oder bekannt." NR_CITY="Stadt" NR_CITY_NAME="Stadtname" NR_CONDITION_CITY_DESC="Geben Sie einen Städtenamen in Englisch ein. Geben Sie mehrere durch Komma getrennte Städte ein." NR_CONTINENT="Kontinent" NR_REGION="Region" NR_CONDITION_REGION_DESC="Der Wert besteht aus zwei Teilen, dem aus zwei Buchstaben bestehenden ISO 3166-1-Ländercode und dem Regionalcode. Der Wert sollte also in der folgenden Form vorliegen: COUNTRY_CODE-REGION_CODE. Für eine vollständige Liste der Regionalcodes klicken Sie auf Suchen a Region Code Link. " NR_ASSIGN_COUNTRIES="Land" NR_ASSIGN_COUNTRIES_DESC2="Besucher ansprechen, die sich physisch in einem bestimmten Land befinden" NR_ASSIGN_COUNTRIES_DESC="Länder auswählen, denen zugewiesen werden soll" NR_ASSIGN_CONTINENTS="Kontinent" NR_ASSIGN_CONTINENTS_DESC="Kontinente zum Zuweisen auswählen" NR_ASSIGN_CONTINENTS_DESC2="Besucher ansprechen, die sich physisch auf einem bestimmten Kontinent befinden" NR_ICONTACT_ACCOUNTID_ERROR="Die iContact-Konto-ID konnte nicht abgerufen werden" NR_TAG_CLIENTDEVICE="Besuchergerätetyp" NR_TAG_CLIENTOS="Besucher-Betriebssystem" NR_TAG_CLIENTBROWSER="Besucher-Browser" NR_TAG_CLIENTUSERAGENT="Besucheragent-Zeichenfolge" NR_TAG_IP="Besucher-IP-Adresse" NR_TAG_URL="Seiten-URL" NR_TAG_URLENCODED="Seiten-URL verschlüsselt" NR_TAG_URLPATH="Seitenpfad" NR_TAG_REFERRER="Seitenverweis" NR_TAG_SITENAME="Site-Name" NR_TAG_SITEURL="Site-URL" NR_TAG_PAGETITLE="Seitentitel" NR_TAG_PAGEDESC="Seiten-Meta-Beschreibung" NR_TAG_PAGELANG="Seitensprachencode" NR_TAG_USERID="Nutzer ID" NR_TAG_USERNAME="Benutzername" NR_TAG_USERLOGIN="Nutzer Login" NR_TAG_USEREMAIL="Benutzer-E-Mail" NR_TAG_USERFIRSTNAME="Vorname" NR_TAG_USERLASTNAME="Nutzer Nachname" NR_TAG_USERGROUPS="Benutzergruppen-IDs" NR_TAG_DATE="Datum" NR_TAG_TIME="Zeit" NR_TAG_RANDOMID="Zufällige ID" NR_ICON="Icon" NR_SELECT_MODULE="Wähle ein Modul" NR_SELECT_CONTINENT="Kontinent auswählen" NR_SELECT_COUNTRY="Land auswählen" NR_PLUGIN="Plugin" NR_GMAP_KEY="Google Maps API-Schlüssel" NR_GMAP_KEY_DESC="Der Google Maps-API-Schlüssel wird von den Erweiterungen von Tassos.gr verwendet. Wenn Sie Probleme damit haben, dass Google Map nicht geladen wird, müssen Sie wahrscheinlich Ihren eigenen API-Schlüssel eingeben." NR_GMAP_FIND_KEY="API-Schlüssel abrufen" NR_ARE_YOU_SURE="Sind Sie sicher?" NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Sind Sie sicher, dass Sie diesen Artikel löschen möchten?" NR_CUSTOMURL="Benutzerdefinierte URL" NR_SAMPLE="Probe" NR_DEBUG="Debug" NR_CUSTOMURL="Benutzerdefinierte URL" NR_READMORE="Weiterlesen" NR_IPADDRESS="IP-Adresse" NR_ASSIGN_BROWSERS="Browser" NR_ASSIGN_BROWSERS_DESC="Browser zum Zuweisen auswählen" NR_ASSIGN_BROWSERS_DESC2="Zielgruppe für Besucher, die Ihre Website mit bestimmten Browsern wie Chrome, Firefox oder Internet Explorer durchsuchen." NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Betriebssystem" NR_ASSIGN_OS_DESC="Wählen Sie die zuzuweisenden Betriebssysteme aus." NR_ASSIGN_OS_DESC2="Besucher ansprechen, die bestimmte Betriebssysteme wie Windows, Linux oder Mac verwenden" NR_LINUX="LINUX" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Brombeere" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Anzahl der Seitenaufrufe" NR_ASSIGN_PAGEVIEWS_DESC="Besucher ansprechen, die eine bestimmte Anzahl von Seiten angesehen haben" NR_ASSIGN_PAGEVIEWS_VIEWS="Seitenaufrufe" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Anzahl der Seitenaufrufe eingeben" NR_ASSIGN_COOKIENAME_NAME="Cookie Name" NR_ASSIGN_COOKIENAME_NAME_DESC="Geben Sie den Namen des zuzuweisenden Cookies ein" NR_ASSIGN_COOKIENAME_NAME_DESC2="Besucher ansprechen, die bestimmte Cookies in ihrem Browser gespeichert haben" NR_FEWER_THAN="Weniger als" NR_FEWER_THAN_OR_EQUAL_TO="Weniger als oder gleich" NR_GREATER_THAN="Größer als" NR_GREATER_THAN_OR_EQUAL_TO="Grösser als oder gleich" NR_EXACTLY="Genau" NR_EXISTS="Existiert" NR_NOT_EXISTS="Existiert nicht" NR_IS_EQUAL="Gleich" NR_DOES_NOT_EQUAL="Ist nicht gleich" NR_CONTAINS="Enthält" NR_DOES_NOT_CONTAIN="Enthält nicht" NR_STARTS_WITH="Beginnt mit" NR_DOES_NOT_START_WITH="Startet nicht mit" NR_ENDS_WITH="Endet mit" NR_DOES_NOT_END_WITH="Endet nicht mit" NR_ASSIGN_COOKIENAME_CONTENT="Cookie-Inhalt" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Der Inhalt des Cookies" NR_ASSIGN_IP_ADDRESSES_DESC2="Besucher ansprechen, die sich hinter einer bestimmten IP-Adresse (einem bestimmten Bereich) befinden" NR_ASSIGN_IP_ADDRESSES_DESC="Geben Sie eine Liste mit durch Kommas getrennten IP-Adressen und Bereichen ein und / oder\" geben \"Sie diese ein

Beispiel:
127.0.0.1,
192.10-120.2,
168 " NR_USER="Benutzer" NR_ASSIGN_USER_SELECTION_DESC="Wählen Sie die Joomla-Benutzer aus, die Sie zuweisen möchten." NR_ASSIGN_USER_ID="Benutzer-ID" NR_ASSIGN_USER_ID_DESC="Bestimmte Joomla-Benutzer anhand ihrer IDs ansprechen" NR_ASSIGN_USER_ID_SELECTION_DESC="Kommagetrennte Joomla-Benutzer-IDs eingeben" NR_ASSIGN_COMPONENTS="Komponente" NR_ASSIGN_COMPONENTS_DESC="Zuzuweisende Komponenten auswählen" NR_ASSIGN_COMPONENTS_DESC2="Besucher ansprechen, die bestimmte Komponenten durchsuchen" NR_ASSIGN_TIMERANGE="Zeitraum" NR_ASSIGN_TIMERANGE_DESC="Besucher basierend auf der Zeit Ihres Servers ansprechen" NR_START_TIME="Startzeit" NR_END_TIME="Endzeit" NR_START_PUBLISHING_TIMERANGE_DESC="Geben Sie die Zeit ein, zu der die Veröffentlichung beginnen soll" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Geben Sie die Zeit zum Beenden der Veröffentlichung ein" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_DESC="Um eine Site und einen geheimen Schlüssel für Ihre Domain zu erhalten, rufen Sie https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Site Key" NR_RECAPTCHA_SITE_KEY_DESC="Wird im JavaScript-Code verwendet, der Ihren Benutzern bereitgestellt wird." NR_RECAPTCHA_SECRET_KEY="Geheimschlüssel" NR_RECAPTCHA_SECRET_KEY_DESC="Wird für die Kommunikation zwischen Ihrem Server und dem reCAPTCHA-Server verwendet. Halten Sie dies unbedingt geheim." NR_RECAPTCHA_SITE_KEY_ERROR="Der reCaptcha-Site-Schlüssel fehlt oder ist ungültig" NR_PREVIOUS_MONTH="Vorheriger Monat" NR_NEXT_MONTH="Nächster Monat" NR_ASSIGN_GROUP_PAGE_URL="Seite / URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Besucher ansprechen, die bestimmte Menüelemente oder URLs durchsuchen" NR_ASSIGN_GROUP_DATETIME_DESC="Eine Box basierend auf dem Datum und der Uhrzeit Ihres Servers auslösen" NR_ASSIGN_GROUP_USER_VISITOR="Joomla Benutzer / Besucher" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Registrierte Benutzer oder Besucher ansprechen, die eine bestimmte Anzahl von Seiten angesehen haben" NR_ASSIGN_GROUP_PLATFORM="Besucherplattform" NR_ASSIGN_GROUP_PLATFORM_DESC="Besucher ansprechen, die Mobile, Google Chrome oder sogar Windows verwenden" NR_ASSIGN_GROUP_GEO_DESC="Besucher ansprechen, die sich physisch in einer bestimmten Region befinden" NR_ASSIGN_GROUP_JCONTENT="Joomla! Content" NR_ASSIGN_GROUP_JCONTENT_DESC="Besucher ansprechen, die bestimmte Artikel oder Kategorien von Joomla anzeigen" NR_ASSIGN_GROUP_SYSTEM="System / Integrationen" NR_INTEGRATIONS="Integrationen" NR_ASSIGN_GROUP_SYSTEM_DESC="Besucher ansprechen, die mit bestimmten Joomla-Erweiterungen von Drittanbietern interagiert haben" NR_ASSIGN_GROUP_ADVANCED="Erweitertes Besucher-Targeting" NR_ASSIGN_USERGROUP_DESC="Zielspezifische Joomla-Benutzergruppen" NR_ASSIGN_ARTICLE_DESC="Besucher ansprechen, die bestimmte Joomla-Artikel anzeigen" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Besucher ansprechen, die bestimmte Joomla-Kategorien anzeigen" NR_EXTENSION_REQUIRED="Für die %s -Komponente muss das %s -Plugin aktiviert sein, damit es ordnungsgemäß funktioniert." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Besucher ansprechen, die bestimmte K2-Elemente, Kategorien oder Tags durchsuchen" NR_ASSIGN_K2_ITEMS="Item" NR_ASSIGN_K2_ITEMS_DESC="Besucher ansprechen, die bestimmte K2-Artikel durchsuchen." NR_ASSIGN_K2_ITEMS_LIST_DESC="K2-Elemente auswählen, denen sie zugewiesen werden sollen" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Entspricht bestimmten Stichwörtern im Inhalt des Artikels. Durch Komma oder neue Zeile trennen." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Entspricht den Meta-Schlüsselwörtern des Artikels. Durch Komma oder neue Zeile trennen." NR_ASSIGN_K2_PAGETYPES_DESC="Besucher ansprechen, die bestimmte K2-Seitentypen durchsuchen" NR_ASSIGN_K2_ITEM_OPTION="Artikel" NR_ASSIGN_K2_LATEST_OPTION="Neueste Elemente von Benutzern oder Kategorien" NR_ASSIGN_K2_TAG_OPTION="Tag-Seite" NR_ASSIGN_K2_CATEGORY_OPTION="Kategorieseite" NR_ASSIGN_K2_ITEM_FORM_OPTION="Artikelbearbeitungsformular" NR_ASSIGN_K2_USER_PAGE_OPTION="Benutzerseite (Blog)" NR_ASSIGN_K2_TAGS_DESC="Besucher ansprechen, die K2-Artikel mit bestimmten Tags durchsuchen" NR_ASSIGN_K2_CATEGORIES_DESC="Besucher ansprechen, die bestimmte K2-Kategorien durchsuchen" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categories" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Items" NR_ASSIGN_PAGE_TYPES_DESC="Zuweisende Seitentypen auswählen" NR_ASSIGN_TAGS_DESC="Zuzuweisende Tags auswählen" NR_CONTENT_KEYWORDS="Inhaltsschlüsselwörter" NR_META_KEYWORDS="Meta-Schlüsselwörter" NR_TAG="Tag" NR_NORMAL="Normal" NR_COMPACT="Kompakt" NR_LIGHT="Licht" NR_DARK="Dunkel" NR_SIZE="Größe" NR_THEME="Theme" NR_SINGLE="Single" NR_MULTIPLE="Mehrere" NR_RANGE="Range" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Bitte validieren" NR_RECAPTCHA_INVALID_SECRET_KEY="Ungültiger geheimer Schlüssel" NR_PAGE="Seite" NR_YOU_ARE_USING_EXTENSION="Sie verwenden %s %s" NR_UPDATE="Update" NR_SHOW_UPDATE_NOTIFICATION="Update-Benachrichtigung anzeigen" NR_SHOW_UPDATE_NOTIFICATION_DESC="Bei Auswahl dieser Option wird in der Hauptkomponentenansicht eine Aktualisierungsbenachrichtigung angezeigt, wenn eine neue Version für diese Erweiterung vorhanden ist." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE="%s ist verfügbar" NR_ERROR_EMAIL_IS_DISABLED="Das Senden von E-Mails ist deaktiviert. E-Mails konnten nicht gesendet werden." NR_ASSIGN_ITEMS="Element" NR_COUNTRY_AF="Afghanistan" NR_COUNTRY_AX="Aland Islands" NR_COUNTRY_AL="Albanien" NR_COUNTRY_DZ="Algerien" NR_COUNTRY_AS="Amerikanisch-Samoa" NR_COUNTRY_AD="Andorra" NR_COUNTRY_AO="Angola" NR_COUNTRY_AI="Anguilla" NR_COUNTRY_AQ="Antarktis" NR_COUNTRY_AG="Antigua und Barbuda" NR_COUNTRY_AR="Argentinien" NR_COUNTRY_AM="Armenien" NR_COUNTRY_AW="Aruba" NR_COUNTRY_AU="Australien" NR_COUNTRY_AT="Österreich" NR_COUNTRY_AZ="Aserbaidschan" NR_COUNTRY_BS="Bahamas" NR_COUNTRY_BH="Bahrain" NR_COUNTRY_BD="Bangladesch" NR_COUNTRY_BB="Barbados" NR_COUNTRY_BY="Weißrussland" NR_COUNTRY_BE="Belgien" NR_COUNTRY_BZ="Belize" NR_COUNTRY_BJ="Benin" NR_COUNTRY_BM="Bermuda" NR_COUNTRY_BQ_BO="Bonaire" NR_COUNTRY_BQ_SA="Saba" NR_COUNTRY_BQ_SE="St. Eustatius" NR_COUNTRY_BT="Bhutan" NR_COUNTRY_BO="Bolivien" NR_COUNTRY_BA="Bosnien und Herzegowina" NR_COUNTRY_BW="Botswana" NR_COUNTRY_BV="Bouvetinsel" NR_COUNTRY_BR="Brasilien" NR_COUNTRY_IO="Britisches Territorium im Indischen Ozean" NR_COUNTRY_BN="Brunei Darussalam" NR_COUNTRY_BG="Bulgarien" NR_COUNTRY_BF="Burkina Faso" NR_COUNTRY_BI="Burundi" NR_COUNTRY_KH="Kambodscha" NR_COUNTRY_CM="Kamerun" NR_COUNTRY_CA="Kanada" NR_COUNTRY_CV="Kap Verde" NR_COUNTRY_KY="Kaimaninseln" NR_COUNTRY_CF="Zentralafrikanische Republik" NR_COUNTRY_TD="Tschad" NR_COUNTRY_CL="Chile" NR_COUNTRY_CN="China" NR_COUNTRY_CX="Weihnachtsinsel" NR_COUNTRY_CC="Kokosinseln (Keelinginseln)" NR_COUNTRY_CO="Kolumbien" NR_COUNTRY_KM="Komoren" NR_COUNTRY_CG="Kongo" NR_COUNTRY_CD="Kongo, Demokratische Republik" NR_COUNTRY_CK="Cookinseln" NR_COUNTRY_CR="Costa Rica" NR_COUNTRY_CI="Elfenbeinküste" NR_COUNTRY_HR="Kroatien" NR_COUNTRY_CU="Kuba" NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Zypern" NR_COUNTRY_CZ="Tschechische Republik" NR_COUNTRY_DK="Dänemark" NR_COUNTRY_DJ="Dschibuti" NR_COUNTRY_DM="Dominica" NR_COUNTRY_DO="Dominikanische Republik" NR_COUNTRY_EC="Ecuador" NR_COUNTRY_EG="Ägypten" NR_COUNTRY_SV="El Salvador" NR_COUNTRY_GQ="Äquatorialguinea" NR_COUNTRY_ER="Eritrea" NR_COUNTRY_EE="Estland" NR_COUNTRY_ET="Äthiopien" NR_COUNTRY_FK="Falklandinseln (Malvinas)" NR_COUNTRY_FO="Färöer" NR_COUNTRY_FJ="Fidschi" NR_COUNTRY_FI="Finnland" NR_COUNTRY_FR="Frankreich" NR_COUNTRY_GF="Französisch-Guayana" NR_COUNTRY_PF="Französisch-Polynesien" NR_COUNTRY_TF="Französische Südgebiete" NR_COUNTRY_GA="Gabun" NR_COUNTRY_GM="Gambia" NR_COUNTRY_GE="Georgia" NR_COUNTRY_DE="Deutschland" NR_COUNTRY_GH="Ghana" NR_COUNTRY_GI="Gibraltar" NR_COUNTRY_GR="Griechenland" NR_COUNTRY_GL="Grönland" NR_COUNTRY_GD="Grenada" NR_COUNTRY_GP="Guadeloupe" NR_COUNTRY_GU="Guam" NR_COUNTRY_GT="Guatemala" NR_COUNTRY_GG="Guernsey" NR_COUNTRY_GN="Guinea" NR_COUNTRY_GW="Guinea-Bissau" NR_COUNTRY_GY="Guyana" NR_COUNTRY_HT="Haiti" NR_COUNTRY_HM="Heard Island und McDonald Islands" NR_COUNTRY_VA="Heiliger Stuhl (Staat der Vatikanstadt)" NR_COUNTRY_HN="Honduras" NR_COUNTRY_HK="Hong Kong" NR_COUNTRY_HU="Ungarn" NR_COUNTRY_IS="Island" NR_COUNTRY_IN="Indien" NR_COUNTRY_ID="Indonesien" NR_COUNTRY_IR="Iran, Islamische Republik" NR_COUNTRY_IQ="Irak" NR_COUNTRY_IE="Irland" NR_COUNTRY_IM="Insel Man" NR_COUNTRY_IL="Israel" NR_COUNTRY_IT="Italien" NR_COUNTRY_JM="Jamaika" NR_COUNTRY_JP="Japan" NR_COUNTRY_JE="Jersey" NR_COUNTRY_JO="Jordan" NR_COUNTRY_KZ="Kasachstan" NR_COUNTRY_KE="Kenia" NR_COUNTRY_KI="Kiribati" NR_COUNTRY_KP="Korea, Demokratische Volksrepublik" NR_COUNTRY_KR="Korea, Republik von" NR_COUNTRY_KW="Kuwait" NR_COUNTRY_KG="Kirgisistan" NR_COUNTRY_LA="Demokratische Volksrepublik Laos" NR_COUNTRY_LV="Lettland" NR_COUNTRY_LB="Libanon" NR_COUNTRY_LS="Lesotho" NR_COUNTRY_LR="Liberia" NR_COUNTRY_LY="Libyscher arabischer Jamahiriya" NR_COUNTRY_LI="Liechtenstein" NR_COUNTRY_LT="Litauen" NR_COUNTRY_LU="Luxemburg" NR_COUNTRY_MO="Macao" NR_COUNTRY_MK="Mazedonien" NR_COUNTRY_MG="Madagaskar" NR_COUNTRY_MW="Malawi" NR_COUNTRY_MY="Malaysia" NR_COUNTRY_MV="Malediven" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Malta" NR_COUNTRY_MH="Marshallinseln" NR_COUNTRY_MQ="Martinique" NR_COUNTRY_MR="Mauretanien" NR_COUNTRY_MU="Mauritius" NR_COUNTRY_YT="Mayotte" NR_COUNTRY_MX="Mexiko" NR_COUNTRY_FM="Mikronesien, Föderierte Staaten von" NR_COUNTRY_MD="Republik Moldau" NR_COUNTRY_MC="Monaco" NR_COUNTRY_MN="Mongolei" NR_COUNTRY_ME="Montenegro" NR_COUNTRY_MS="Montserrat" NR_COUNTRY_MA="Marokko" NR_COUNTRY_MZ="Mosambik" NR_COUNTRY_MM="Myanmar" NR_COUNTRY_NA="Namibia" NR_COUNTRY_NR="Nauru" NR_COUNTRY_NM="Nord Macedonien" NR_COUNTRY_NP="Nepal" NR_COUNTRY_NL="Niederlande" NR_COUNTRY_AN="Niederländische Antillen" NR_COUNTRY_NC="Neukaledonien" NR_COUNTRY_NZ="Neuseeland" NR_COUNTRY_NI="Nicaragua" NR_COUNTRY_NE="Niger" NR_COUNTRY_NG="Nigeria" NR_COUNTRY_NU="Niue" NR_COUNTRY_NF="Norfolkinsel" NR_COUNTRY_MP="Nördliche Marianen" NR_COUNTRY_NO="Norwegen" NR_COUNTRY_OM="Oman" NR_COUNTRY_PK="Pakistan" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Palästinensisches Gebiet" NR_COUNTRY_PA="Panama" NR_COUNTRY_PG="Papua-Neuguinea" NR_COUNTRY_PY="Paraguay" NR_COUNTRY_PE="Peru" NR_COUNTRY_PH="Philippinen" NR_COUNTRY_PN="Pitcairn" NR_COUNTRY_PL="Polen" NR_COUNTRY_PT="Portugal" NR_COUNTRY_PR="Puerto Rico" NR_COUNTRY_QA="Qatar" NR_COUNTRY_RE="Wiedersehen" NR_COUNTRY_RO="Rumänien" NR_COUNTRY_RU="Russische Föderation" NR_COUNTRY_RW="Ruanda" NR_COUNTRY_SH="St. Helena" NR_COUNTRY_KN="St. Kitts und Nevis" NR_COUNTRY_LC="St. Lucia" NR_COUNTRY_PM="Saint Pierre und Miquelon" NR_COUNTRY_VC="St. Vincent und die Grenadinen" NR_COUNTRY_WS="Samoa" NR_COUNTRY_SM="San Marino" NR_COUNTRY_ST="São Tomé und Príncipe" NR_COUNTRY_SA="Saudi-Arabien" NR_COUNTRY_SN="Senegal" NR_COUNTRY_RS="Serbien" NR_COUNTRY_SC="Seychellen" NR_COUNTRY_SL="Sierra Leone" NR_COUNTRY_SG="Singapur" NR_COUNTRY_SK="Slowakei" NR_COUNTRY_SI="Slowenien" NR_COUNTRY_SB="Salomonen" NR_COUNTRY_SO="Somalia" NR_COUNTRY_ZA="Südafrika" NR_COUNTRY_GS="Südgeorgien und die Südlichen Sandwichinseln" NR_COUNTRY_ES="Spanien" NR_COUNTRY_LK="Sri Lanka" NR_COUNTRY_SD="Sudan" NR_COUNTRY_SS="Südsudan" NR_COUNTRY_SR="Suriname" NR_COUNTRY_SJ="Spitzbergen und Jan Mayen" NR_COUNTRY_SZ="Swasiland" NR_COUNTRY_SE="Schweden" NR_COUNTRY_CH="Schweiz" NR_COUNTRY_SY="Arabische Republik Syrien" NR_COUNTRY_TW="Taiwan" NR_COUNTRY_TJ="Tadschikistan" NR_COUNTRY_TZ="Tansania, Vereinigte Republik von" NR_COUNTRY_TH="Thailand" NR_COUNTRY_TL="Timor-Leste" NR_COUNTRY_TG="Togo" NR_COUNTRY_TK="Tokelau" NR_COUNTRY_TO="Tonga" NR_COUNTRY_TT="Trinidad und Tobago" NR_COUNTRY_TN="Tunesien" NR_COUNTRY_TR="Türkei" NR_COUNTRY_TM="Turkmenistan" NR_COUNTRY_TC="Turks- und Caicosinseln" NR_COUNTRY_TV="Tuvalu" NR_COUNTRY_UG="Uganda" NR_COUNTRY_UA="Ukraine" NR_COUNTRY_AE="Vereinigte Arabische Emirate" NR_COUNTRY_GB="Großbritannien" NR_COUNTRY_US="Vereinigte Staaten" NR_COUNTRY_UM="Nebeninseln der Vereinigten Staaten" NR_COUNTRY_UY="Uruguay" NR_COUNTRY_UZ="Usbekistan" NR_COUNTRY_VU="Vanuatu" NR_COUNTRY_VE="Venezuela" NR_COUNTRY_VN="Vietnam" NR_COUNTRY_VG="Britische Jungferninseln" NR_COUNTRY_VI="Amerikanische Jungferninseln" NR_COUNTRY_WF="Wallis und Futuna" NR_COUNTRY_EH="Westsahara" NR_COUNTRY_YE="Jemen" NR_COUNTRY_ZM="Sambia" NR_COUNTRY_ZW="Simbabwe" NR_CONTINENT_AF="Afrika" NR_CONTINENT_AS="Asien" NR_CONTINENT_EU="Europa" NR_CONTINENT_NA="Nordamerika" NR_CONTINENT_SA="Südamerika" NR_CONTINENT_OC="Ozeanien" NR_CONTINENT_AN="Antarktis" NR_FRONTEND="Benutzer Interface" NR_BACKEND="Administration" NR_EMBED="Verankert" NR_RATE="Bewertung %s" NR_REPORT_ISSUE="Problem melden" NR_RESPONSIVE_CONTROL_TITLE="Wert pro Gerät einstellen" NR_TAG_PAGEGENERATOR="Seiten Generator" NR_TAG_PAGELANGURL="Seiten Sprache URL" NR_TAG_PAGEKEYWORDS="Seiten Schlüsselwörter" NR_TAG_SITEEMAIL="Website E-Mail" NR_TAG_DAY="Tag" NR_TAG_MONTH="Monat" NR_TAG_YEAR="Jahr" NR_TAG_USERREGISTERDATE="Datum registrieren" NR_TAG_PAGEBROWSERTITLE="Browser Titel" NR_TAG_EBID="Box ID" NR_TAG_EBTITLE="Box Titel" NR_TAG_QUERYSTRINGOPTION="Abfrage String : Option" NR_TAG_QUERYSTRINGVIEW="Abfrage String : Ansicht" NR_TAG_QUERYSTRINGLAYOUT="Abfrage String : Layout" NR_TAG_QUERYSTRINGTMPL="Abfrage String : Template" NR_CANNOT_CREATE_FOLDER="Ordner zum Verschieben von Dateien kann nicht erstellt werden. %s" NR_CANNOT_MOVE_FILE="Datei kann nicht verschoben werden: %s" NR_UPLOAD_INVALID_FILE_TYPE="Nicht unterstützte Datei:%s. Die zulässigen Dateitypen sind:%s" NR_UPLOAD_NO_MIME_TYPE="Der Mime-Typ der Datei kann nicht erraten werden: %s. Stellen Sie sicher, dass die PHP-Erweiterung fileinfo aktiviert ist." NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Datei kann nicht hochgeladen werden: %s" NR_START_OVER="Neu beginnen" NR_TRY_AGAIN="Erneut versuchen" NR_ERROR="Fehler" NR_CANCEL="Abbrechen" NR_PLEASE_WAIT="Bitte warten" NR_STAR="stern%s" NR_HCAPTCHA="hCaptcha" NR_TYPE="Typ" NR_CHECKBOX="Kontrollbox" NR_INVISIBLE="Unsichtbar" NR_HCAPTCHA_DESC="Um eine Website und einen geheimen Schlüssel für Ihre Domain zu erhalten, besuchen Sie https://dashboard.hcaptcha.com/sites." NR_HCAPTCHA_SECRET_KEY_DESC="Wird für die Kommunikation zwischen Ihrem Server und dem hCaptcha-Server verwendet. Achten Sie darauf, ihn geheim zu halten." NR_OUTDATED_EXTENSION="Ihre Version von %s ist mehr als %d Tage alt und höchstwahrscheinlich bereits veraltet. Bitte prüfen Sie, ob eine %sneuere Version%s veröffentlicht wurde und installieren Sie diese." NR_GENERAL="Generell" NR_GALLERY_MANAGER_BROWSE="Durchsuchen" NR_GALLERY_MANAGER_ADD_IMAGES="Bilder hinzufügen" NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Medienbibliothek durchsuchen" NR_GALLERY_MANAGER_REMOVE_IMAGES="Alle Bilder entfernen" NR_GALLERY_MANAGER_TITLE_HINT="Einen Titel eingeben" NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Beschreibung" NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Eine Beschreibung eingeben" NR_GALLERY_MANAGER_FILE_MISSING="Die Datei fehlt. Bitte versuchen Sie, sie erneut hochzuladen." NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget-Einstellungen fehlen." NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget-Einstellungen ungültig." NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Datei kann nicht hochgeladen werden" NR_GALLERY_MANAGER_ERROR_INVALID_FILE="Diese Datei scheint unsicher oder ungültig zu sein und kann nicht hochgeladen werden." NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Sind Sie sicher, dass Sie alle Galerie-Elemente löschen möchten?" NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Sind Sie sicher, dass Sie die ausgewählten Galerieelemente löschen möchten?" NR_GALLERY_MANAGER_CONFIRM_DELETE="Sind Sie sicher, dass Sie dieses Galerie-Element löschen möchten?" NR_GALLERY_MANAGER_IN_QUEUE="In Warteschlange" NR_GALLERY_MANAGER_UPLOADING="Hochladen..." NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Ausgewählte Bilder entfernen" NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Anwählen, um mehrere Bilder zu löschen" NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Klicken, um Bild zu löschen" NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Alles auswählen" NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Alles abwählen" NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Alle Bilder auswählen oder abwählen" NR_GALLERY_MANAGER_ADD_DROPDOWN="Menüoptionen ein-/ausblenden" NR_GALLERY_MANAGER_SELECT_ITEM="Galerieobjekt auswählen" NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Bilder hierher ziehen und ablegen oder" NR_TECHNOLOGY="Technologie" NR_ENGAGEBOX_SELECT_BOX="Boxen auswählen" NR_CONTENT_ARTICLE="Inhalts-Artikel" NR_CONTENT_CATEGORY="Inhalts-Kategorie" NR_VIEWED_ANOTHER_BOX="EngageBox - Ein anderes Popup gesehen" NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Kampagne" NR_K2_ITEM="K2 - Artikel" NR_K2_CATEGORY="K2 - Kategorie" NR_K2_TAG="K2 - Tag" NR_K2_PAGE_TYPE="K2 - Seiten Typ" NR_AKEEBASUBS_LEVEL="Akeeba Untermenü" NR_CB_SELECT_CONDITION="Bedingung auswählen" NR_CB_ADD_CONDITION_GROUP="Bedingungsset hinzufügen" NR_CB_SELECT_CONDITION_GET_STARTED="Wählen Sie eine Bedingung aus, um zu beginnen." NR_CB_TRASH_CONDITION="Papierkorb Zustand " NR_CB_TRASH_CONDITION_GROUP="Papierkorb Zustand Gruppe" NR_CB_ADD_CONDITION="Bedingung hinzufügen" NR_CB_SHOW_WHEN="Anzeigen wenn" NR_CB_OF_THE_CONDITIONS_MATCH="der folgenden Bedingungen sind erfüllt" NR_PHP_COLLECTION_SCRIPTS="Eine Sammlung gebrauchsfertiger PHP-Aufgabenskripte ist verfügbar. Sammlung ansehen" NR_IS="Ist" NR_IS_NOT="Ist nicht" NR_IS_EMPTY="Ist leer" NR_IS_NOT_EMPTY="Ist nicht leer" NR_IS_BETWEEN="Ist zwischen" NR_IS_NOT_BETWEEN="Ist nicht zwischen" NR_DISPLAY_CONDITIONS_LOADING="Anzeigebedingungen laden..." NR_CB_TOGGLE_RULE_GROUP_STATUS="Aktivieren oder deaktivieren des Bedingungssets" NR_CB_TOGGLE_RULE_STATUS="Aktivieren oder deaktivieren der Bedingung" NR_DISPLAY_CONDITIONS_HINT_DATE="Die Datumszeit Ihres Servers ist %s." NR_DISPLAY_CONDITIONS_HINT_TIME="Die Zeit Ihres Servers ist %s." NR_DISPLAY_CONDITIONS_HINT_DAY="Heute ist %s." NR_DISPLAY_CONDITIONS_HINT_MONTH="Der aktuelle Monat ist %s." NR_DISPLAY_CONDITIONS_HINT_USERID="Die ID des Kontos, bei dem Sie angemeldet sind, lautet %s." NR_DISPLAY_CONDITIONS_HINT_USERGROUP="Die Benutzergruppen, die dem Konto, bei dem Sie angemeldet sind, zugewiesen sind, lauten %s." NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="Dem Konto, bei dem Sie angemeldet sind, sind folgende Zugriffsstufen zugewiesen: %s." NR_DISPLAY_CONDITIONS_HINT_DEVICE="Der Typ des von Ihnen verwendeten Geräts ist %s." NR_DISPLAY_CONDITIONS_HINT_BROWSER="Der von Ihnen verwendete Browser ist %s." NR_DISPLAY_CONDITIONS_HINT_OS="Das von Ihnen verwendete Betriebssystem ist %s." NR_DISPLAY_CONDITIONS_HINT_GEO="Anhand Ihrer IP-Adresse (%s) ist %s, an dem Sie sich physisch befinden, %s." NR_DISPLAY_CONDITIONS_HINT_IP="Ihre IP Adresse lautet %s." NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Anhand Ihrer IP-Adresse (%s) konnten wir nicht feststellen, wo Sie sich physisch befinden." NR_GEO_MAINTENANCE="Wartung der Geolokalisierungs-Datenbank" NR_GEO_MAINTENANCE_DESC="Die Datenbank, die zur Bestimmung des geografischen Standorts Ihrer Besucher verwendet wird, ist veraltet oder nicht installiert. Bitte klicken Sie auf die Schaltfläche unten, um die Datenbank zu aktualisieren. Es wird empfohlen, sie mindestens einmal pro Monat zu aktualisieren." NR_EDIT="Bearbeiten" NR_GEO_PLUGIN_DISABLED="Geolokalisierungs-Plugin deaktiviert" NR_GEO_PLUGIN_DISABLED_DESC="Bitte aktivieren Sie das Plugin %s\"System - Tassos.gr GeoIP Plugin\"%s, um die Geolokalisierungs-Dienste nutzen zu können." NR_INVALID_IMAGE_PATH="Ungültiger Bildpfad: %s" PK!8PɡɡBsystem/nrframework/language/it-IT/it-IT.plg_system_nrframework.ininu[; @package Novarain Framework System Plugin ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr ; NON TRANSLATABLE PLG_SYSTEM_NRFRAMEWORK="System - Novarain Framework" PLG_SYSTEM_NRFRAMEWORK_DESC="Novarain Framework - usato dalle estensioni di Tassos.gr" NOVARAIN_FRAMEWORK="Novarain Framework" ; TRANSLATABLE NR_IGNORE="Ignora" NR_INCLUDE="Includi" NR_EXCLUDE="Escludi" NR_SELECTION="Selezione" NR_ASSIGN_MENU_NOITEM="Non includere Itemid" NR_ASSIGN_MENU_NOITEM_DESC="Assegnare anche se nessun Itemid di menu è impostato nell'URL?" NR_ASSIGN_MENU_CHILD="Anche su oggetti figli" NR_ASSIGN_MENU_CHILD_DESC="Assegna anche agli oggetti figli degli oggetti selezionati?" NR_COPY_OF="Copia di %s" NR_ASSIGN_DATETIME_DESC="Indirizza i visitatori in base all'orologio (data e ora) impostati sul tuo server" NR_DATETIME="Dataora" NR_TIME="Ora" NR_DATE="Data" NR_DATETIME_DESC="Inserisci Dataora per pubblicare/annullare automaticamente" NR_START_PUBLISHING="Avvia Dataora" NR_START_PUBLISHING_DESC="Inserisci la data di inizio della pubblicazione" NR_FINISH_PUBLISHING="Fine Dataora" NR_FINISH_PUBLISHING_DESC="Inserisci la data per terminare la pubblicazione" NR_DATETIME_NOTE="Le assegnazioni di data e ora utilizzano la data/ora dei tuoi server, non quella del sistema dei visitatori." NR_ASSIGN_PHP="PHP" NR_PHPCODE="Codice PHP" NR_ASSIGN_PHP_DESC="Inserisci un pezzo di codice PHP da controllare." NR_ASSIGN_PHP_DESC2="Destinatari che valutano il codice PHP personalizzato. Il codice deve restituire il valore true o false.

Ad esempio:
return ($user->name == 'Tassos Marinos');" NR_ASSIGN_TIMEONSITE="Tempo sul sito" NR_SECONDS="Secondi" NR_ASSIGN_TIMEONSITE_DESC="Inserisci una durata in secondi da confrontare con il tempo totale dell'utente (durata della visita) trascorso visitando tutto il tuo sito.

Esempio:
Se vuoi visualizzare una casella dopo che l'utente ha trascorso 3 minuti sul tuo intero sito, inserisci 180. " NR_ASSIGN_URLS="URL" NR_ASSIGN_URLS_DESC2="Scegli come target i visitatori che stanno esplorando URL specifici" NR_ASSIGN_URLS_DESC="Inserisci parte degli URL corrispondenti.
Usa una nuova riga per ogni corrispondenza diversa." NR_ASSIGN_URLS_LIST="Corrispondenze URL" NR_ASSIGN_URLS_REGEX="Usa l'espressione regolare" NR_ASSIGN_URLS_REGEX_DESC="Seleziona per usare il valore come Regex (espressioni regolari)." NR_ASSIGN_LANGS="Lingua" NR_ASSIGN_LANGS_DESC="Indirizza i visitatori che stanno navigando nel tuo sito web in una lingua specifica" NR_ASSIGN_LANGS_LIST_DESC="Seleziona le lingue da assegnare a" NR_ASSIGN_DEVICES="Dispositivo" NR_ASSIGN_DEVICES_DESC2="Scegli come target i visitatori che utilizzano dispositivi specifici come Mobile, Tablet o Desktop." NR_ASSIGN_DEVICES_DESC="Seleziona i dispositivi da assegnare a\"" NR_ASSIGN_DEVICES_NOTE="Ricorda che il rilevamento dei dispositivi non è sempre accurato al 100%. Gli utenti possono configurare il loro browser per simulare altri dispositivi" NR_MENU="Menu" NR_MENU_ITEMS="Voce di menu" NR_MENU_ITEMS_DESC="Scegli come target i visitatori che stanno sfogliando voci di menu specifiche" NR_USERGROUP="Gruppo utenti" ; NR_USERGROUP_DESC="Select the User Groups to assign to.

Note: If you want to make it public just set to Ignore and not select the Public." NR_ACCESSLEVEL="Gruppo utenti" ; NR_USERACCESSLEVEL="User Access Level" ; NR_USERACCESSLEVEL_DESC="Select the user viewing access levels to assign to." NR_SHOW_COPYRIGHT="Visualizza copyright" NR_SHOW_COPYRIGHT_DESC="Se selezionato, verranno visualizzate ulteriori informazioni sul copyright nelle pagine di amministrazione. Le estensioni di Tassos.gr non mostrano mai le informazioni sul copyright o i backlink sulla parte pubblica (frontend)." NR_WIDTH="Larghezza" NR_WIDTH_DESC="Inserisci larghezza in px, em o %

Esempio: 400px" NR_HEIGHT="Altezza" NR_HEIGHT_DESC="Inserisci altezza in px, em o %

Esempio: 400px" NR_PADDING="Padding" NR_PADDING_DESC="Inserisci padding in px, em o %

Esempio: 20px" NR_MARGIN="Margine" NR_MARGIN_DESC="L'impostazione del margine CSS viene utilizzata per generare spazio attorno al riquadro e impostare la dimensione dello spazio bianco al di fuori del bordo in pixel o in %.

Esempio 1: 25px
Esempio 2: 5%

Specifica del margine per ciascun lato [in alto a destra in basso a sinistra]:

Solo lato superiore: 25px 0 0 0
Solo lato destro: 0 25px 0 0
Solo lato inferiore : 0 0 25px 0
Solo lato sinistro: 0 0 0 25px " NR_COLOR_HOVER="Colore al passaggio del mouse" NR_COLOR="Colore" NR_COLOR_DESC="Definisci un colore in formato HEX o RGBA." NR_TEXT_COLOR="Colore del testo" NR_BACKGROUND="Background" NR_BACKGROUND_COLOR="Colore di fondo" NR_BACKGROUND_COLOR_DESC="Definisci un colore di sfondo in formato HEX o RGBA.Per disabilitare inserisci 'none'. Per trasparenza assoluta inserisci 'transparent'." NR_URL_SHORTENING_FAILED="Abbreviazione %s con %s fallito. %S." NR_EXPORT="Esporta" NR_IMPORT="Importa" NR_PLEASE_CHOOSE_A_VALID_FILE="Scegli un nome file valido" NR_IMPORT_ITEMS="Importa elementi" NR_PUBLISH_ITEMS="Pubblica articoli" NR_AS_EXPORTED="Come esportato" NR_TITLE="Titolo" NR_ACYMAILING="AcyMailing" NR_ACYMAILING_LIST="Lista AcyMailing" NR_ACYMAILING_LIST_DESC="Seleziona gli elenchi AcyMailing che sono da assegnare." NR_ASSIGN_ACYMAILING_DESC="Indirizza i visitatori che si sono abbonati a specifici elenchi AcyMailing" NR_AKEEBASUBS="Iscrizioni Akeeba" NR_AKEEBASUBS_LEVELS="Livelli" NR_AKEEBASUBS_LEVELS_DESC="Seleziona i livelli di iscrizione Akeeba che sono da assegnare." NR_ASSIGN_AKEEBASUBS_DESC="Fai riferimento ai visitatori che hanno sottoscritto iscrizioni Akeeba specifiche" NR_MATCH="Confronto" NR_MATCH_DESC="Il metodo di comparazione utilizzato per confrontare il valore" NR_ASSIGN_MATCHING_METHOD="Metodo di comparazione" NR_ASSIGN_MATCHING_METHOD_DESC="Si devono comparare tutte o qualsiasi?

Tutti
saranno pubblicati se Tutti i metodi sottostanti sono abbinati.

Qualsiasi
sarà pubblicato se Qualsiasi (uno o più) dei seguenti metodi sono abbinati.
Gruppi di assegnazione dove Ignora è selezionato, saranno ignorati." NR_ANY="Qualsiasi" ; NR_ALL="All" NR_ASSIGN_REFERRER="URL di riferimento" NR_ASSIGN_REFERRER_DESC2="Indirizza i visitatori che arriveranno sul tuo sito da una sorgente di traffico specifica" NR_ASSIGN_REFERRER_DESC="Inserisci un URL di riferimento per ogni riga: Es:

google.com
facebook.com/mypage" NR_ASSIGN_REFERRER_NOTE="Ricorda che l'individuazione di un URL di riferimento non è sempre accurata al 100%. Alcuni server potrebbero utilizzare proxy che estendono questa informazione e possono essere facilmente falsificati." NR_PROFEATURE_HEADER="%s È una funzionalità disponibile nella versione PRO" NR_PROFEATURE_DESC="Siamo spiacenti, %s non è disponibile sul tuo piano. Esegui l'upgrade al piano PRO per sbloccare tutte queste fantastiche funzionalità." NR_PROFEATURE_DISCOUNT="Bonus: gli utenti %s gratuiti ottengono il 20% di sconto sul prezzo normale, automaticamente applicato al momento del pagamento." NR_ONLY_AVAILABLE_IN_PRO="Disponibile solo in versione PRO" NR_UPGRADE_TO_PRO="Aggiorna a Pro" NR_UPGRADE_TO_PRO_TO_UNLOCK="Esegui l'upgrade alla versione Pro per sbloccare" NR_UPGRADE_TO_PRO_VERSION="Fantastico! Solo manca solo un ulteriore passo al completamento della procedura. Fai clic sul pulsante in basso per completare l'aggiornamento alla versione Pro." NR_UNLOCK_PRO_FEATURE="Sblocca le funzioni Pro" NR_USING_THE_FREE_VERSION="Stai utilizzando la versione GRATUITA di Convert Forms. Acquista la versione PRO per la piena funzionalità." NR_LEFT_TO_RIGHT="Da sinistra a destra" NR_RIGHT_TO_LEFT="Da destra a sinistra" NR_BGIMAGE="Immagine di sfondo" NR_BGIMAGE_DESC="Imposta un'immagine di sfondo" NR_BGIMAGE_FILE="Immagine" NR_BGIMAGE_FILE_DESC="Seleziona o carica un file per l'immagine di sfondo." NR_BGIMAGE_REPEAT="Ripeti" NR_BGIMAGE_REPEAT_DESC="La proprietà background-repeat imposta se o come verrà ripetuta un'immagine di sfondo. Per impostazione predefinita, un'immagine di sfondo viene ripetuta sia verticalmente che orizzontalmente.

Ripeti: l'immagine di sfondo verrà ripetuta sia in verticale che in orizzontale.

Ripeti-x: l'immagine di sfondo verràripetuta solo in orizzontale

Ripeti-y: l'immagine di sfondo verrà ripetuta solo in verticale

Nessuna ripetizione: l'immagine non sarà ripetuta" NR_BGIMAGE_SIZE="Formato" NR_BGIMAGE_SIZE_DESC="Specifica la dimensione di un'immagine di sfondo.

Auto: l'immagine di sfondo contiene la sua larghezza e altezza

Copertina: ridimensiona l'immagine di fondo sarà il più grande possibile in modo che l'area è completamente coperta dall'immagine di fondo. Alcune parti dell'immagine, in questo caso, potrebbero non essere visibili nell'area di posizionamento dello sfondo

Contiene: ridimensiona l'immagine alla dimensione più grande in modo che sia la sua larghezza che la sua altezza possano adattarsi all'interno dell'area del contenuto

100% 100%: estende l'immagine di fondo fino a coprire completamente l'area del contenuto." NR_BGIMAGE_POSITION="Posizione" NR_BGIMAGE_POSITION_DESC="La proprietà background-position imposta la posizione iniziale di un'immagine di sfondo: per impostazione predefinita, l'immagine di sfondo viene posizionata nell'angolo in alto a sinistra.Il primo valore è la posizione orizzontale e il secondo valore è la posizione verticale.

È possibile utilizzare uno dei valori predefiniti oppure immettere un valore personalizzato in percentuale: x% y% o in pixel xPos yPos. " NR_RTL="Abilita RTL" NR_RTL_DESC="La direzione del testo da destra a sinistra è essenziale per le scritture in lingue come l'Arabo, l'Ebraico, il Siriaco o della lingua maldiviana." NR_HORIZONTAL="orizzontale" NR_VERTICAL="verticale" NR_FORM_ORIENTATION="Orientamento modulo" NR_FORM_ORIENTATION_DESC="Seleziona l'orientamento del modulo" NR_ASSIGN_CATEGORY="Categorie" NR_ASSIGN_CATEGORY_DESC="Seleziona le categorie da assegnare a" NR_ASSIGN_CATEGORY_CHILD="Anche su oggetti secondari" NR_ASSIGN_CATEGORY_CHILD_DESC="Assegna anche agli oggetti figli degli oggetti selezionati?" NR_NEW="Nuovo" NR_LIST="Lista" NR_DOCUMENTATION="Documentazione" NR_KNOWLEDGEBASE="knowledge base" NR_FAQ="FAQ" NR_INFORMATION="Informazioni" NR_EXTENSION="Estensione" NR_VERSION="Versione" NR_CHANGELOG="Changelog" NR_DOWNLOAD="Download" NR_DOWNLOAD_KEY_MISSING="Manca la chiave di download" NR_DOWNLOAD_KEY="Chiave di download" NR_DOWNLOAD_KEY_DESC="Per trovare la chiave di download, accedi al tuo account su Tassos.gr e vai alla sezione Download.

Nota: impostando la chiave di download qui non aggiornerai le versioni gratuite alle versioni Pro. Per sbloccare le funzionalità Pro, dovrai installare anche la versione Pro sopra la versione gratuita." NR_DOWNLOAD_KEY_HOW="Per poter aggiornare %s tramite l'aggiornamento di Joomla, dovrai inserire la tua chiave di download nelle impostazioni del plugin Novarain Framework" NR_DOWNLOAD_KEY_FIND="Trova chiave di download" NR_DOWNLOAD_KEY_UPDATE="Aggiorna chiave di download" NR_OK="OK" NR_MISSING="Missing" NR_LICENSE="Licenza" NR_AUTHOR="Autore" NR_FOLLOWME="Seguimi" NR_FOLLOW="Segui %s" NR_TRANSLATE_INTEREST="Saresti interessato a dare una mano nella traduzione di %s nella tua lingua?" NR_TRANSIFEX_REQUEST="Inviami una richiesta su Transifex" NR_HELP_WITH_TRANSLATIONS="Aiuto con le traduzioni" ; NR_PUBLISHING_ASSIGNMENTS="Display Conditions" NR_ADVANCED="Avanzate" NR_USEGLOBAL="Usa globale" NR_WEEKDAY="Giorno della settimana" NR_MONTH="Mese" NR_MONDAY="Lunedi" NR_TUESDAY="Martedì" NR_WEDNESDAY="Mercoledì" NR_THURSDAY="Giovedi" NR_FRIDAY="Venerdì" NR_SATURDAY="Sabato" NR_WEEKEND="Weekend" NR_WEEKDAYS="Giorni della settimana" NR_SUNDAY="Domenica" NR_JANUARY="Gennaio" NR_FEBRUARY="Febbraio" NR_MARCH="Marzo" NR_APRIL="Aprile" NR_MAY="Maggio" NR_JUNE="Giugno" NR_JULY="Luglio" NR_AUGUST="Agosto" NR_SEPTEMBER="Settembre" NR_OCTOBER="Ottobre" NR_NOVEMBER="Novembre" NR_DECEMBER="Dicembre" NR_NEVER="Mai" NR_SECONDS="Secondi" NR_MINUTES="Minutes" NR_HOURS="Ore" NR_DAYS="Giorni" NR_SESSION="Session1" NR_EVER="mai" NR_COOKIE="Cookie" NR_BOTH="Entrambi" NR_NONE="Nessuno" NR_NONE_SELECTED="Nessuno selezionato" NR_DESKTOPS="Desktop" NR_MOBILES="Mobile" NR_TABLETS="Tablet" NR_PER_SESSION="Per sessione" NR_PER_DAY="Al giorno" NR_PER_WEEK="Per settimana" NR_PER_MONTH="Al mese" NR_FOREVER="Per sempre" NR_FEATURE_UNDER_DEV="Questa funzione è in fase di sviluppo" NR_LIKE_THIS_EXTENSION="Ti piace questa estensione?" NR_LEAVE_A_REVIEW="Lascia una recensione su JED" NR_SUPPORT="Supporto" NR_NEED_SUPPORT="Hai bisogno di supporto?" NR_DROP_EMAIL="Inviami una e-mail" NR_READ_DOCUMENTATION="Leggi la documentazione" NR_COPYRIGHT=" %s - Tassos.gr Tutti i diritti riservati" NR_DASHBOARD="Dashboard" NR_NAME="Nome" NR_WRONG_COORDINATES="Le coordinate fornite non sono valide" NR_ENTER_COORDINATES="Latitudine, Longitudine" NR_NO_ITEMS_FOUND="Nessun elemento trovato" NR_ITEM_IDS="Nessun ID elemento" NR_TOGGLE="Commuta" NR_EXPAND="Espandi" NR_COLLAPSE="Comprimi" NR_SELECTED="selezionato" NR_MAXIMIZE="Massimizzare" NR_MINIMIZE="Riduci" NR_SELECTION="Selezione" NR_INSTALL="Installa" NR_INSTALL_NOW="Installa ora" NR_INSTALLED="installato" NR_COMING_SOON="Prossimamente" NR_ROADMAP="Sulla roadmap" NR_MEDIA_VERSIONING="Utilizza il controllo dei contenuti multimediali" NR_MEDIA_VERSIONING_DESC="Seleziona per aggiungere il numero di versione dell'estensione alla fine dei file multimediali (js/css), in modo che i browser forzino il caricamento del file corretto." NR_LOAD_JQUERY="Carica jQuery" NR_LOAD_JQUERY_DESC="Seleziona per caricare lo script jQuery di base. Puoi disabilitarlo in caso di conflitti se il tuo modello o altre estensioni caricano la propria versione di jQuery." NR_SELECT_CURRENCY="Seleziona una valuta" NR_CONVERTFORMS="Convert Forms" NR_CONVERTFORMS_LIST="Campagna" NR_ASSIGN_CONVERTFORMS_DESC="Indirizza i visitatori che si sono iscritti a specifiche campagne ConvertForms" NR_CONVERTFORMS_LIST_DESC="Seleziona le campagne ConvertForms da assegnare a." NR_LEFT="sinistra" NR_CENTER="Centro" NR_RIGHT="destra" NR_BOTTOM="sotto" NR_TOP="sopra" NR_AUTO="Auto" NR_CUSTOM="Persnalizzato" NR_UPLOAD="Upload" NR_IMAGE="Immagine" NR_INTRO_IMAGE="Immagine di introduzione" NR_FULL_IMAGE="Immagine completa" NR_IMAGE_SELECT="Seleziona immagine" NR_IMAGE_SIZE_COVER="Copertina" NR_IMAGE_SIZE_CONTAIN="contenere" NR_REPEAT="Ripeti" NR_REPEAT_X="Ripeti x" NR_REPEAT_Y="Ripeti y" NR_REPEAT_NO="Nessuna ripetizione" NR_FIELD_STATE_DESC="Imposta lo stato dell'oggetto" NR_CREATED_DATE="Data di creazione" NR_CREATED_DATE_DESC="La data di creazione dell'articolo" NR_MODIFIFED_DATE="Data modificata" NR_MODIFIFED_DATE_DESC="La data in cui l'elemento è stato modificato l'ultima volta." NR_CATEGORIES="Categoria" NR_CATEGORIES_DESC="Seleziona le categorie da assegnare a." NR_ALSO_ON_CHILD_ITEMS="Anche su oggetti secondari" NR_ALSO_ON_CHILD_ITEMS_DESC="Assegna anche agli oggetti figli degli oggetti selezionati?" NR_PAGE_TYPE="Tipo di pagina" NR_PAGE_TYPES="Tipi di pagina" NR_PAGE_TYPES_DESC="Seleziona su quali tipi di pagina deve essere attivo il compito." NR_CONTENT_VIEW_CATEGORY_BLOG="Blog di categoria" NR_CONTENT_VIEW_CATEGORY_LIST="Lista categorie" NR_CONTENT_VIEW_CATEGORIES="elenca tutte le categorie" NR_CONTENT_VIEW_ARCHIVED="Articoli archiviati" NR_CONTENT_VIEW_FEATURES="Articoli consigliati" NR_CONTENT_VIEW_CREATE_ARTICLE="Crea articolo" NR_CONTENT_VIEW_ARTICLE="Articolo singolo" NR_ARTICLE_VIEW_DESC="Abilita per prendere in considerazione la vista Articolo" NR_CATEGORY_VIEW="Vista categorie" NR_CATEGORY_VIEW_DESC="Abilita per prendere in considerazione la vista Categoria" ; NR_CONTENT_VIEW="Content Component View" ; NR_CONTENT_VIEW_DESC="Select the views to assign to." NR_ARTICLES="Statuto" NR_ARTICLES_DESC="Seleziona gli articoli da assegnare a\"" NR_ARTICLE="articolo" NR_ARTICLE_AUTHORS="Autori" NR_ARTICLE_AUTHORS_DESC="Seleziona gli autori da assegnare a\"" NR_ONLY="Solo" NR_OTHERS="Altri" NR_SMARTTAGS="Smart tag" NR_SMARTTAGS_SHOW="Mostra smart tag" NR_SMARTTAGS_NOTFOUND="Nessun tag smart trovato" NR_SMARTTAGS_SEARCH_PLACEHOLDER="Cerca gli smart tag" NR_CONTACT_US="Contattaci" NR_FONT_COLOR="Colore carattere" NR_FONT_SIZE="Dimensione carattere" NR_FONT_SIZE_DESC="Scegli una dimensione del carattere in pixel" NR_TEXT="testo" NR_URL="URL" NR_EXECUTE_ON_OUTPUT_OVERRIDE="Abilita su Output Override" NR_EXECUTE_ON_OUTPUT_OVERRIDE_DESC="Abilita il rendering dell'estensione quando il layout della pagina (tmpl) è sovrascritto. Esempi: tmpl=componente o tmpl=modale." NR_EXECUTE_ON_FORMAT_OVERRIDE="Abilita su sovrascrittura del formato" NR_EXECUTE_ON_FORMAT_OVERRIDE_DESC="Abilita il rendering dell'estensione quando il formato della pagina non è diverso da HTML. Esempi: format=raw o format=json." NR_GEOLOCATING="geolocalizzazione" ; NR_GEOLOCATION="Geolocation" NR_GEOLOCATING_DESC="LA geolocalizzazione non è sempre accurata al 100%. Essa si basa sull'indirizzo IP del visitatore e non tutti gli indirizzi IP sono fissi o conosciuti." NR_CITY="City" NR_CITY_NAME="Nome città" NR_CONDITION_CITY_DESC="Inserisci il nome di una città in inglese. Inserisci più città separate da una virgola." NR_CONTINENT="Continente" NR_REGION="Regione" NR_CONDITION_REGION_DESC="Il valore è composto da due parti, il codice paese ISO 3166-1 e il codice regionale delle due lettere. Quindi il valore dovrebbe essere nella seguente forma: COUNTRY_CODE-REGION_CODE. Per un elenco completo dei codici regionali fai clic su Trova Collegamento al codice regionale. " NR_ASSIGN_COUNTRIES="Nazione" NR_ASSIGN_COUNTRIES_DESC2="Indirizza i visitatori fisicamente in un paese specifico" NR_ASSIGN_COUNTRIES_DESC="Seleziona i Paesi da assegnare a" NR_ASSIGN_CONTINENTS="Continente" NR_ASSIGN_CONTINENTS_DESC="Seleziona i continenti da assegnare a" NR_ASSIGN_CONTINENTS_DESC2="Scegli come target i visitatori fisicamente in un determinato continente" NR_ICONTACT_ACCOUNTID_ERROR="Impossibile recuperare l'ID account iContact" NR_TAG_CLIENTDEVICE="Tipo dispositivo visitatore" NR_TAG_CLIENTOS="Sistema operativo visitatore" NR_TAG_CLIENTBROWSER="browser visitatori" NR_TAG_CLIENTUSERAGENT="Stringa agente visitatore" NR_TAG_IP="Indirizzo IP visitatore" NR_TAG_URL="URL della pagina" NR_TAG_URLENCODED="URL pagina codificato" NR_TAG_URLPATH="Percorso pagina" NR_TAG_REFERRER="Referente di pagina" NR_TAG_SITENAME="Nome sito" NR_TAG_SITEURL="URL del sito" NR_TAG_PAGETITLE="Titolo pagina" NR_TAG_PAGEDESC="Descrizione tags Meta della pagina" NR_TAG_PAGELANG="Codice lingua della pagina" NR_TAG_USERID="ID utente" NR_TAG_USERNAME="Nome utente completo" NR_TAG_USERLOGIN="Login utente" NR_TAG_USEREMAIL="Email utente" NR_TAG_USERFIRSTNAME="Nome utente" NR_TAG_USERLASTNAME="Cognome utente" NR_TAG_USERGROUPS="ID gruppi utente" NR_TAG_DATE="Data" NR_TAG_TIME="Ora" NR_TAG_RANDOMID="ID casuale" NR_ICON="icona" NR_SELECT_MODULE="Seleziona un modulo" NR_SELECT_CONTINENT="Seleziona un continente" NR_SELECT_COUNTRY="Seleziona un Paese" NR_PLUGIN="plugin" NR_GMAP_KEY="Chiave API di Google Maps" NR_GMAP_KEY_DESC="La chiave API di Google Maps viene utilizzata dalle estensioni Tassos.gr. Se si riscontrano problemi con una mappa di Google non caricata, probabilmente è necessario inserire la propria chiave API." NR_GMAP_FIND_KEY="Ottieni una chiave API" NR_ARE_YOU_SURE="Sei sicuro?" ; NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM="Are you sure you want to delete this item?" NR_CUSTOMURL="URL personalizzato" NR_SAMPLE="campione" NR_DEBUG="Debug" NR_CUSTOMURL="URL personalizzato" NR_READMORE="Leggi altro" NR_IPADDRESS="Indirizzo IP" NR_ASSIGN_BROWSERS="browser" NR_ASSIGN_BROWSERS_DESC="Seleziona i browser da assegnare a" NR_ASSIGN_BROWSERS_DESC2="Indirizza i visitatori che stanno esplorando il tuo sito con browser specifici come Chrome, Firefox o Internet Explorer" NR_CHROME="Chrome" NR_FIREFOX="Firefox" NR_EDGE="Edge" NR_IE="Internet Explorer" NR_SAFARI="Safari" NR_OPERA="Opera" NR_ASSIGN_OS="Sistema operativo" NR_ASSIGN_OS_DESC="Seleziona i sistemi operativi da assegnare a" NR_ASSIGN_OS_DESC2="Indirizza i visitatori che utilizzano sistemi operativi specifici come Windows, Linux o Mac" NR_LINUX="Linux" NR_MAC="MacOS" NR_ANDROID="Android" NR_IOS="iOS" NR_WINDOWS="Windows" NR_BLACKBERRY="Blackberry" NR_CHROMEOS="Chrome OS" NR_ASSIGN_PAGEVIEWS="Numero di pagine visualizzate" NR_ASSIGN_PAGEVIEWS_DESC="Scegli come target i visitatori che hanno visualizzato un certo numero di pagine" NR_ASSIGN_PAGEVIEWS_VIEWS="Pagine" NR_ASSIGN_PAGEVIEWS_VIEWS_DESC="Inserisci il numero di visualizzazioni di pagina" NR_ASSIGN_COOKIENAME_NAME="Nome cookie" NR_ASSIGN_COOKIENAME_NAME_DESC="Inserisci il nome del cookie da assegnare a" NR_ASSIGN_COOKIENAME_NAME_DESC2="Indirizza i visitatori che hanno cookie specifici memorizzati nel loro browser" NR_FEWER_THAN="Meno di" ; NR_FEWER_THAN_OR_EQUAL_TO="Fewer than or equal to" NR_GREATER_THAN="Maggiore di" ; NR_GREATER_THAN_OR_EQUAL_TO="Greater than or equal to" NR_EXACTLY="Esattamente" NR_EXISTS="esiste" NR_NOT_EXISTS="Non esiste" NR_IS_EQUAL="Equals" ; NR_DOES_NOT_EQUAL="Does not equal" NR_CONTAINS="Contiene" NR_DOES_NOT_CONTAIN="Non contiene" NR_STARTS_WITH="Inizia con" NR_DOES_NOT_START_WITH="Non inizia per" NR_ENDS_WITH="Termina con" NR_DOES_NOT_END_WITH="Non finisce con" NR_ASSIGN_COOKIENAME_CONTENT="Contenuto cookie" NR_ASSIGN_COOKIENAME_CONTENT_DESC="Contenuto del cookie" NR_ASSIGN_IP_ADDRESSES_DESC2="Indirizza i visitatori che si trovano dietro un indirizzo IP specifico (intervallo)" NR_ASSIGN_IP_ADDRESSES_DESC="Inserisci una lista di virgola e / o 'inserisci' indirizzi IP separati e intervalli

Esempio:
127.0.0.1,
192.10-120.2,
168 " NR_USER="Utente" ; NR_ASSIGN_USER_SELECTION_DESC="Select Joomla users to assign to." NR_ASSIGN_USER_ID="ID utente" NR_ASSIGN_USER_ID_DESC="Specifica come target utenti Joomla per i loro ID" NR_ASSIGN_USER_ID_SELECTION_DESC="Inserisci ID utente Joomla separati da virgola" NR_ASSIGN_COMPONENTS="Componente" NR_ASSIGN_COMPONENTS_DESC="Seleziona i componenti da assegnare a" NR_ASSIGN_COMPONENTS_DESC2="Scegli come target i visitatori che stanno esplorando componenti specifici" NR_ASSIGN_TIMERANGE="Intervallo di tempo" NR_ASSIGN_TIMERANGE_DESC="Indirizza i visitatori in base al tempo del tuo server" NR_START_TIME="Ora di inizio" NR_END_TIME="Ora di fine" NR_START_PUBLISHING_TIMERANGE_DESC="Inserisci l'ora di inizio della pubblicazione" NR_FINISH_PUBLISHING_TIMERANGE_DESC="Inserisci il tempo per terminare la pubblicazione" NR_RECAPTCHA="reCAPTCHA" ; NR_RECAPTCHA_DESC="To get a site and secret key for your domain, go to https://www.google.com/recaptcha." NR_RECAPTCHA_SITE_KEY="Chiave sito" NR_RECAPTCHA_SITE_KEY_DESC="Utilizzato nel codice JavaScript che viene offerto ai tuoi utenti." NR_RECAPTCHA_SECRET_KEY="Chiave segreta" NR_RECAPTCHA_SECRET_KEY_DESC="Utilizzato nella comunicazione tra il tuo server e il server reCAPTCHA. Assicurati di tenerlo segreto." NR_RECAPTCHA_SITE_KEY_ERROR="La chiave del sito reCaptcha è mancante o non valida" NR_PREVIOUS_MONTH="Mese precedente" NR_NEXT_MONTH="Il prossimo mese" NR_ASSIGN_GROUP_PAGE_URL="Pagina/URL" NR_ASSIGN_GROUP_PAGE_URL_DESC="Scegli come target i visitatori che stanno sfogliando voci di menu o URL specifici" NR_ASSIGN_GROUP_DATETIME_DESC="Attiva una casella in base alla data e all'ora del tuo server" NR_ASSIGN_GROUP_USER_VISITOR="Utente/visitatore di Joomla" NR_ASSIGN_GROUP_USER_VISITOR_DESC="Targeting di utenti o visitatori che hanno visualizzato un certo numero di pagine" NR_ASSIGN_GROUP_PLATFORM="Piattaforma visitatore" NR_ASSIGN_GROUP_PLATFORM_DESC="Scegli come target i visitatori che utilizzano Mobile, Google Chrome o anche Windows" NR_ASSIGN_GROUP_GEO_DESC="Indirizza i visitatori fisicamente in una regione specifica" NR_ASSIGN_GROUP_JCONTENT="Contenuto Joomla!" NR_ASSIGN_GROUP_JCONTENT_DESC="Scegli come target i visitatori che visualizzano articoli o categorie specifici di Joomla" NR_ASSIGN_GROUP_SYSTEM="Sistema/Integrazioni" ; NR_INTEGRATIONS="Integrations" NR_ASSIGN_GROUP_SYSTEM_DESC="Indirizza i visitatori che hanno interagito con specifiche estensioni di Joomla di terze parti" NR_ASSIGN_GROUP_ADVANCED="Targeting per visitatore avanzato" NR_ASSIGN_USERGROUP_DESC="Target specifici per gruppi di utenti Joomla" NR_ASSIGN_ARTICLE_DESC="Scegli come target i visitatori che visualizzano articoli specifici di Joomla" NR_ASSIGN_ARTICLE_CATEGORIES_DESC="Scegli come target i visitatori che visualizzano categorie specifiche di Joomla" NR_EXTENSION_REQUIRED="Il componente %s richiede che il plugin %s sia abilitato per funzionare correttamente." NR_ASSIGN_K2="K2" NR_ASSIGN_K2_DESC="Indirizza i visitatori che stanno sfogliando specifici articoli, categorie o tag K2" NR_ASSIGN_K2_ITEMS="Item" NR_ASSIGN_K2_ITEMS_DESC="Indirizza i visitatori che stanno sfogliando elementi K2 specifici." NR_ASSIGN_K2_ITEMS_LIST_DESC="Seleziona gli oggetti K2 da assegnare a" NR_ASSIGN_K2_ITEMS_CONTENT_KEYWORDS_DESC="Corrispondenza per parole chiave specifiche nel contenuto dell'articolo. Separa con una virgola o una nuova riga." NR_ASSIGN_K2_ITEMS_META_KEYWORDS_DESC="Corrispondenza tra le meta parole chiave dell'elemento. Separa con una virgola o una nuova riga." NR_ASSIGN_K2_PAGETYPES_DESC="Scegli come target i visitatori che stanno esplorando tipi di pagine K2 specifici" NR_ASSIGN_K2_ITEM_OPTION="Item" NR_ASSIGN_K2_LATEST_OPTION="Ultimi articoli da utenti o categorie" NR_ASSIGN_K2_TAG_OPTION="Pagina tag" NR_ASSIGN_K2_CATEGORY_OPTION="Pagina delle categorie" NR_ASSIGN_K2_ITEM_FORM_OPTION="Modulo di modifica articolo" NR_ASSIGN_K2_USER_PAGE_OPTION="Pagina utente (blog)" NR_ASSIGN_K2_TAGS_DESC="Indirizza i visitatori che stanno sfogliando articoli K2 con tag specifici" NR_ASSIGN_K2_CATEGORIES_DESC="Scegli come target i visitatori che stanno esplorando categorie K2 specifiche" NR_ASSIGN_K2_CATEGORIES_CATEGORIES_OPTION="Categorie" NR_ASSIGN_K2_CATEGORIES_ITEMS_OPTION="Elementi" NR_ASSIGN_PAGE_TYPES_DESC="Seleziona i tipi di pagina da assegnare a" NR_ASSIGN_TAGS_DESC="Seleziona i tag da assegnare a" NR_CONTENT_KEYWORDS="Parole chiave contenuto" NR_META_KEYWORDS="Meta keywords" NR_TAG="tag" NR_NORMAL="Normale" NR_COMPACT="Compatto" NR_LIGHT="Chiaro" NR_DARK="Scuro" NR_SIZE="Formato" NR_THEME="Tema" NR_SINGLE="single" NR_MULTIPLE="Multiplo" NR_RANGE="Range" NR_RECAPTCHA="reCAPTCHA" NR_RECAPTCHA_PLEASE_VALIDATE="Si prega di convalidare" NR_RECAPTCHA_INVALID_SECRET_KEY="Chiave segreta non valida" NR_PAGE="Pagina" NR_YOU_ARE_USING_EXTENSION="Stai utilizzando %s %s" NR_UPDATE="Aggiorna" NR_SHOW_UPDATE_NOTIFICATION="Mostra notifica aggiornamenti" NR_SHOW_UPDATE_NOTIFICATION_DESC="Se selezionato, verrà mostrata una notifica di aggiornamento nella vista componente principale quando c'è una nuova versione per questa estensione." NR_EXTENSION_NEW_VERSION_IS_AVAILABLE=" %s è disponibile" NR_ERROR_EMAIL_IS_DISABLED="L'invio della posta è disattivato. Non è stato possibile inviare email." NR_ASSIGN_ITEMS="Elemento" NR_COUNTRY_AF="Afghanistan" NR_COUNTRY_AX="Isole Aland" NR_COUNTRY_AL="Albania" NR_COUNTRY_DZ="Algeria" NR_COUNTRY_AS="Samoa americane" NR_COUNTRY_AD="Andorra" NR_COUNTRY_AO="Angola" NR_COUNTRY_AI="Anguilla" NR_COUNTRY_AQ="Antartide" NR_COUNTRY_AG="Antigua e Barbuda" NR_COUNTRY_AR="Argentina" NR_COUNTRY_AM="Armenia" NR_COUNTRY_AW="Aruba" NR_COUNTRY_AU="Australia" NR_COUNTRY_AT="Austria" NR_COUNTRY_AZ="Azerbaijan" NR_COUNTRY_BS="Bahamas" NR_COUNTRY_BH="Bahrain" NR_COUNTRY_BD="Bangladesh" NR_COUNTRY_BB="Barbados" NR_COUNTRY_BY="Bielorussia" NR_COUNTRY_BE="Belgio" NR_COUNTRY_BZ="Belize" NR_COUNTRY_BJ="Benin" NR_COUNTRY_BM="Bermuda" ; NR_COUNTRY_BQ_BO="Bonaire" ; NR_COUNTRY_BQ_SA="Saba" ; NR_COUNTRY_BQ_SE="Sint Eustatius" NR_COUNTRY_BT="Bhutan" NR_COUNTRY_BO="Bolivia" NR_COUNTRY_BA="Bosnia Erzegovina" NR_COUNTRY_BW="Botswana" NR_COUNTRY_BV="Bouvet, Isola " NR_COUNTRY_BR="Brasile" NR_COUNTRY_IO="Territorio britannico dell'Oceano Indiano" NR_COUNTRY_BN="Brunei" NR_COUNTRY_BG="Bulgaria" NR_COUNTRY_BF="Burkina Faso" NR_COUNTRY_BI="Burundi" NR_COUNTRY_KH="Cambogia" NR_COUNTRY_CM="Camerun" NR_COUNTRY_CA="Canada" NR_COUNTRY_CV="Capo Verde" NR_COUNTRY_KY="Isole Cayman" NR_COUNTRY_CF="Repubblica Centrafricana" NR_COUNTRY_TD="Ciad" NR_COUNTRY_CL="Cile" NR_COUNTRY_CN="Cina" NR_COUNTRY_CX="Natale, Isola di " NR_COUNTRY_CC="Isole Cocos (Keeling)" NR_COUNTRY_CO="Colombia" NR_COUNTRY_KM="Comore" NR_COUNTRY_CG="Congo" NR_COUNTRY_CD="Congo, Repubblica Democratica" NR_COUNTRY_CK="Isole Cook" NR_COUNTRY_CR="Costa Rica" NR_COUNTRY_CI="Costa d'avorio" NR_COUNTRY_HR="Croazia" NR_COUNTRY_CU="Cuba" NR_COUNTRY_CW="Curaçao" NR_COUNTRY_CY="Cipro" NR_COUNTRY_CZ="Repubblica Ceca" NR_COUNTRY_DK="Danimarca" NR_COUNTRY_DJ="Gibuti" NR_COUNTRY_DM="Dominica" NR_COUNTRY_DO="Repubblica Dominicana" NR_COUNTRY_EC="Ecuador" NR_COUNTRY_EG="Egitto" NR_COUNTRY_SV="El Salvador" NR_COUNTRY_GQ="Guinea Equatoriale" NR_COUNTRY_ER="Eritrea" NR_COUNTRY_EE="Estonia" NR_COUNTRY_ET="Etiopia" NR_COUNTRY_FK="Isole Falkland (Malvinas)" NR_COUNTRY_FO="Isole Faroe" NR_COUNTRY_FJ="Fiji" NR_COUNTRY_FI="Finlandia" NR_COUNTRY_FR="Francia" NR_COUNTRY_GF="Guyana Francese" NR_COUNTRY_PF="Polinesia Francese" NR_COUNTRY_TF="Terre australi e antartiche francesi" NR_COUNTRY_GA="Gabon" NR_COUNTRY_GM="Gambia" NR_COUNTRY_GE="Georgia" NR_COUNTRY_DE="Germania" NR_COUNTRY_GH="Ghana" NR_COUNTRY_GI="Gibilterra" NR_COUNTRY_GR="Grecia" NR_COUNTRY_GL="Groenlandia" NR_COUNTRY_GD="Grenada" NR_COUNTRY_GP="Guadalupe" NR_COUNTRY_GU="Guam" NR_COUNTRY_GT="Guatemala" NR_COUNTRY_GG="Guernsey" NR_COUNTRY_GN="Guinea" NR_COUNTRY_GW="Guinea-Bissau" NR_COUNTRY_GY="Guyana" NR_COUNTRY_HT="Haiti" NR_COUNTRY_HM="Heard e McDonald, Isole" NR_COUNTRY_VA="Santa Sede (Stato della Città del Vaticano)" NR_COUNTRY_HN="Honduras" NR_COUNTRY_HK="Hong Kong" NR_COUNTRY_HU="Ungheria" NR_COUNTRY_IS="Islanda" NR_COUNTRY_IN="India" NR_COUNTRY_ID="Indonesia" NR_COUNTRY_IR="Iran, Repubblica Islamica dell'" NR_COUNTRY_IQ="Iraq" NR_COUNTRY_IE="Irlanda" NR_COUNTRY_IM="Man, Isola di" NR_COUNTRY_IL="Israele" NR_COUNTRY_IT="Italia" NR_COUNTRY_JM="Giamaica" NR_COUNTRY_JP="Giappone" NR_COUNTRY_JE="Jersey" NR_COUNTRY_JO="Giordania" NR_COUNTRY_KZ="Kazakistan" NR_COUNTRY_KE="Kenya" NR_COUNTRY_KI="Kiribati" NR_COUNTRY_KP="Corea, Repubblica Popolare di " NR_COUNTRY_KR="Corea, Repubblica di " NR_COUNTRY_KW="Kuwait" NR_COUNTRY_KG="Kirghizistan" NR_COUNTRY_LA="Laos, Repubblica Popolare Democratica del" NR_COUNTRY_LV="Lettonia" NR_COUNTRY_LB="Libano" NR_COUNTRY_LS="Lesotho" NR_COUNTRY_LR="Liberia" NR_COUNTRY_LY="Libia" NR_COUNTRY_LI="Liechtenstein" NR_COUNTRY_LT="Lituania" NR_COUNTRY_LU="Lussemburgo" NR_COUNTRY_MO="Macao" NR_COUNTRY_MK="Macedonia" NR_COUNTRY_MG="Madagascar" NR_COUNTRY_MW="Malawi" NR_COUNTRY_MY="Malesia" NR_COUNTRY_MV="Maldive" NR_COUNTRY_ML="Mali" NR_COUNTRY_MT="Malta" NR_COUNTRY_MH="Isole Marshall" NR_COUNTRY_MQ="Martinica" NR_COUNTRY_MR="Mauritania" NR_COUNTRY_MU="Mauritius" NR_COUNTRY_YT="Mayotte" NR_COUNTRY_MX="Messico" NR_COUNTRY_FM="Micronesia, Stati Federati di " NR_COUNTRY_MD="Moldavia, Repubblica di" NR_COUNTRY_MC="Monaco, Principato di" NR_COUNTRY_MN="Mongolia" NR_COUNTRY_ME="Montenegro" NR_COUNTRY_MS="Montserrat" NR_COUNTRY_MA="Marocco" NR_COUNTRY_MZ="Mozambico" NR_COUNTRY_MM="Myanmar" NR_COUNTRY_NA="Namibia" NR_COUNTRY_NR="Nauru" NR_COUNTRY_NM="Macedonia del Nord" NR_COUNTRY_NP="Nepal" NR_COUNTRY_NL="Paesi Bassi" NR_COUNTRY_AN="Antille olandesi" NR_COUNTRY_NC="Nuova Caledonia" NR_COUNTRY_NZ="Nuova Zelanda" NR_COUNTRY_NI="Nicaragua" NR_COUNTRY_NE="Niger" NR_COUNTRY_NG="Nigeria" NR_COUNTRY_NU="Niue" NR_COUNTRY_NF="Norfolk, Isola di " NR_COUNTRY_MP="Marianne Settentrionali, Isole " NR_COUNTRY_NO="Norvegia" NR_COUNTRY_OM="Oman" NR_COUNTRY_PK="Pakistan" NR_COUNTRY_PW="Palau" NR_COUNTRY_PS="Territori palestinesi " NR_COUNTRY_PA="Panama" NR_COUNTRY_PG="Papua Nuova Guinea" NR_COUNTRY_PY="Paraguay" NR_COUNTRY_PE="Perù" NR_COUNTRY_PH="Filippine" NR_COUNTRY_PN="Pitcairn" NR_COUNTRY_PL="Polonia" NR_COUNTRY_PT="Portogallo" NR_COUNTRY_PR="Porto Rico" NR_COUNTRY_QA="Qatar" NR_COUNTRY_RE="Reunion" NR_COUNTRY_RO="Romania" NR_COUNTRY_RU="Russia" NR_COUNTRY_RW="Ruanda" NR_COUNTRY_SH="Sant'Elena" NR_COUNTRY_KN="Saint Kitts e Nevis" NR_COUNTRY_LC="Santa Lucia" NR_COUNTRY_PM="Saint Pierre e Miquelon" NR_COUNTRY_VC="Saint Vincent e Grenadine" NR_COUNTRY_WS="Samoa" NR_COUNTRY_SM="San Marino" NR_COUNTRY_ST="São Tomé e Príncipe" NR_COUNTRY_SA="Arabia Saudita" NR_COUNTRY_SN="Senegal" NR_COUNTRY_RS="Serbia" NR_COUNTRY_SC="Seychelles" NR_COUNTRY_SL="Sierra Leone" NR_COUNTRY_SG="Singapore" NR_COUNTRY_SK="Slovacchia" NR_COUNTRY_SI="Slovenia" NR_COUNTRY_SB="Salomone, Isole " NR_COUNTRY_SO="Somalia" NR_COUNTRY_ZA="Sud Africa" NR_COUNTRY_GS="Georgia del Sud e Isole Sandwich Australi" NR_COUNTRY_ES="Spagna" NR_COUNTRY_LK="Sri Lanka" NR_COUNTRY_SD="Sudan" NR_COUNTRY_SS="Sudan del Sud" NR_COUNTRY_SR="Suriname" NR_COUNTRY_SJ="Svalbard e Jan Mayen" NR_COUNTRY_SZ="Swaziland" NR_COUNTRY_SE="Svezia" NR_COUNTRY_CH="Svizzera" NR_COUNTRY_SY="Siria" NR_COUNTRY_TW="Taiwan" NR_COUNTRY_TJ="Tagikistan" NR_COUNTRY_TZ="Tanzania" NR_COUNTRY_TH="Thailandia" NR_COUNTRY_TL="Timor Est" NR_COUNTRY_TG="Togo" NR_COUNTRY_TK="Tokelau" NR_COUNTRY_TO="Tonga" NR_COUNTRY_TT="Trinidad e Tobago" NR_COUNTRY_TN="Tunisia" NR_COUNTRY_TR="Turchia" NR_COUNTRY_TM="Turkmenistan" NR_COUNTRY_TC="Turks e Caicos, Isole" NR_COUNTRY_TV="Tuvalu" NR_COUNTRY_UG="Uganda" NR_COUNTRY_UA="Ucraina" NR_COUNTRY_AE="Emirati Arabi Uniti" NR_COUNTRY_GB="Regno Unito" NR_COUNTRY_US="Stati Uniti" NR_COUNTRY_UM="Stati Uniti, Isole Minori Esterne degli" NR_COUNTRY_UY="Uruguay" NR_COUNTRY_UZ="Uzbekistan" NR_COUNTRY_VU="Vanuatu" NR_COUNTRY_VE="Venezuela" NR_COUNTRY_VN="Vietnam" NR_COUNTRY_VG="Isole Vergini Britanniche" NR_COUNTRY_VI="Isole Vergini Americane" NR_COUNTRY_WF="Wallis e Futuna" NR_COUNTRY_EH="Sahara Occidentale" NR_COUNTRY_YE="Yemen" NR_COUNTRY_ZM="Zambia" NR_COUNTRY_ZW="Zimbabwe" NR_CONTINENT_AF="Africa" NR_CONTINENT_AS="Asia" NR_CONTINENT_EU="Europa" NR_CONTINENT_NA="America del Nord" NR_CONTINENT_SA="America del Sud" NR_CONTINENT_OC="Oceania" NR_CONTINENT_AN="Antartide" NR_FRONTEND="Front-end" NR_BACKEND="Amministrazione" NR_EMBED="Incorpora" NR_RATE="Valuta %s" NR_REPORT_ISSUE="Segnala un problema" ; NR_RESPONSIVE_CONTROL_TITLE="Set value per device" ; NR_TAG_PAGEGENERATOR="Page Generator" ; NR_TAG_PAGELANGURL="Page Language URL" ; NR_TAG_PAGEKEYWORDS="Page Keywords" ; NR_TAG_SITEEMAIL="Site Email" ; NR_TAG_DAY="Day" ; NR_TAG_MONTH="Month" ; NR_TAG_YEAR="Year" ; NR_TAG_USERREGISTERDATE="Register Date" ; NR_TAG_PAGEBROWSERTITLE="Browser Title" ; NR_TAG_EBID="Box ID" ; NR_TAG_EBTITLE="Box Title" ; NR_TAG_QUERYSTRINGOPTION="Query String : Option" ; NR_TAG_QUERYSTRINGVIEW="Query String : View" ; NR_TAG_QUERYSTRINGLAYOUT="Query String : Layout" ; NR_TAG_QUERYSTRINGTMPL="Query String : Template" NR_CANNOT_CREATE_FOLDER="Impossibile creare una cartella per spostare il file. %s" NR_CANNOT_MOVE_FILE="Impossibile spostare il file: %s" ; NR_UPLOAD_INVALID_FILE_TYPE="Unsupported file type: %s (%s). The allowed file types are: %s" ; NR_UPLOAD_NO_MIME_TYPE="Unable to guess file mime type: %s. Make sure the fileinfo PHP extension is enabled." NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE="Impossibile caricare il file: %s" NR_START_OVER="Inizia da capo" NR_TRY_AGAIN="Riprova" NR_ERROR="Errore" NR_CANCEL="Cancella" NR_PLEASE_WAIT="Si prega di attendere" ; NR_STAR="star%s" ; NR_HCAPTCHA="hCaptcha" ; NR_TYPE="Type" ; NR_CHECKBOX="Checkbox" ; NR_INVISIBLE="Invisible" ; NR_HCAPTCHA_DESC="To get a site and secret key for your domain, go to https://dashboard.hcaptcha.com/sites." ; NR_HCAPTCHA_SECRET_KEY_DESC="Used in the communication between your server and the hCaptcha server. Be sure to keep it a secret." ; NR_OUTDATED_EXTENSION="Your version of %s is more than %d days old and most likely already out of date. Please check if a %snewer version%s is published and install it." ; NR_GENERAL="General" ; NR_GALLERY_MANAGER_BROWSE="Browse" ; NR_GALLERY_MANAGER_ADD_IMAGES="Add Images" ; NR_GALLERY_MANAGER_BROWSE_MEDIA_LIBRARY="Browse Media Library" ; NR_GALLERY_MANAGER_REMOVE_IMAGES="Remove all images" ; NR_GALLERY_MANAGER_TITLE_HINT="Enter a title" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION="Description" ; NR_GALLERY_MANAGER_CAPTION_DESCRIPTION_HINT="Enter a description" ; NR_GALLERY_MANAGER_FILE_MISSING="File is missing. Please try re-uploading it." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_MISSING="Widget settings missing." ; NR_GALLERY_MANAGER_WIDGET_SETTINGS_INVALID="Widget settings invalid." ; NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE="Cannot upload file" ; NR_GALLERY_MANAGER_ERROR_INVALID_FILE="This file seems unsafe or invalid and can't be uploaded." ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL="Are you sure you want to delete all gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED="Are you sure you want to delete all selected gallery items?" ; NR_GALLERY_MANAGER_CONFIRM_DELETE="Are you sure you want to delete this gallery item?" ; NR_GALLERY_MANAGER_IN_QUEUE="In Queue" ; NR_GALLERY_MANAGER_UPLOADING="Uploading..." ; NR_GALLERY_MANAGER_REMOVE_SELECTED_IMAGES="Remove selected images" ; NR_GALLERY_MANAGER_CHECK_TO_DELETE_ITEMS="Check to delete multiple images" ; NR_GALLERY_MANAGER_CLICK_TO_DELETE_ITEM="Click to delete image" ; NR_GALLERY_MANAGER_SELECT_ALL_ITEMS="Select All" ; NR_GALLERY_MANAGER_UNSELECT_ALL_ITEMS="Unselect All" ; NR_GALLERY_MANAGER_SELECT_UNSELECT_IMAGES="Select or unselect all images" ; NR_GALLERY_MANAGER_ADD_DROPDOWN="Show/hide menu options" ; NR_GALLERY_MANAGER_SELECT_ITEM="Select Gallery Item" ; NR_GALLERY_MANAGER_DRAG_AND_DROP_TEXT="Drag and drop images here or" ; NR_TECHNOLOGY="Technology" ; NR_ENGAGEBOX_SELECT_BOX="Select boxes" ; NR_CONTENT_ARTICLE="Content Article" ; NR_CONTENT_CATEGORY="Content Category" ; NR_VIEWED_ANOTHER_BOX="EngageBox - Viewed Another Popup" ; NR_CONVERT_FORMS_CAMPAIGN="Convert Forms - Campaign" ; NR_K2_ITEM="K2 - Item" ; NR_K2_CATEGORY="K2 - Category" ; NR_K2_TAG="K2 - Tag" ; NR_K2_PAGE_TYPE="K2 - Page Type" ; NR_AKEEBASUBS_LEVEL="AkeebaSubs Level" ; NR_CB_SELECT_CONDITION="Select Condition" ; NR_CB_ADD_CONDITION_GROUP="Add Condition Set" ; NR_CB_SELECT_CONDITION_GET_STARTED="Select a condition to get started." ; NR_CB_TRASH_CONDITION="Trash Condition" ; NR_CB_TRASH_CONDITION_GROUP="Trash Condition Group" ; NR_CB_ADD_CONDITION="Add Condition" ; NR_CB_SHOW_WHEN="Display when" ; NR_CB_OF_THE_CONDITIONS_MATCH="of the conditions below are met" ; NR_PHP_COLLECTION_SCRIPTS="A collection of ready-to-use PHP assignment scripts is available. View collection" ; NR_IS="Is" ; NR_IS_NOT="Is not" ; NR_IS_EMPTY="Is empty" ; NR_IS_NOT_EMPTY="Is not empty" ; NR_IS_BETWEEN="Is between" ; NR_IS_NOT_BETWEEN="Is not between" ; NR_DISPLAY_CONDITIONS_LOADING="Loading Display Conditions..." ; NR_CB_TOGGLE_RULE_GROUP_STATUS="Enable or disable Condition Set" ; NR_CB_TOGGLE_RULE_STATUS="Enable or disable Condition" ; NR_DISPLAY_CONDITIONS_HINT_DATE="Your server's date time is %s." ; NR_DISPLAY_CONDITIONS_HINT_TIME="Your server's time is %s." ; NR_DISPLAY_CONDITIONS_HINT_DAY="Today is %s." ; NR_DISPLAY_CONDITIONS_HINT_MONTH="The current month is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERID="The ID of the account you're logged-in is %s." ; NR_DISPLAY_CONDITIONS_HINT_USERGROUP="The User Groups assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_ACCESSLEVEL="The Viewing Access Levels assigned to the account you're logged-in are: %s." ; NR_DISPLAY_CONDITIONS_HINT_DEVICE="The type of the device you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_BROWSER="The browser you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_OS="The operating system you're using is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO="Based on your IP address (%s), the %s you're physically located in, is %s." ; NR_DISPLAY_CONDITIONS_HINT_IP="Your IP Address is %s." ; NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR="Based on your IP address (%s), we couldn't determine where you're physically located in." ; NR_GEO_MAINTENANCE="Geolocation Database Maintenance" ; NR_GEO_MAINTENANCE_DESC="The database used to determine your visitors' geographical location is outdated or not installed. Please click on the bottom below to update the database. You are advised to update it at least once per month." ; NR_EDIT="Edit" ; NR_GEO_PLUGIN_DISABLED="Geolocation Plugin Disabled" ; NR_GEO_PLUGIN_DISABLED_DESC="Please enable the plugin %s\"System - Tassos.gr GeoIP Plugin\"%s to be able to use the geolocation services." ; NR_INVALID_IMAGE_PATH="Invalid image path: %s" PK!2G%system/nrframework/fields/ajaxify.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use Joomla\Registry\Registry; use NRFramework\HTML; JFormHelper::loadFieldClass('list'); /* * Creates an AJAX-based dropdown * https://select2.org/ */ abstract class JFormFieldAjaxify extends JFormFieldList { /** * Textbox placeholder * * @var string */ protected $placeholder = 'Select Items'; /** * AJAX rows limit * * @var int */ protected $limit = 50; /** * Method to render the input field * * @return string */ protected function getInput() { if ($this->value && is_string($this->value)) { $this->value = \NRFramework\Functions::makeArray($this->value); } $placeholder = (string) $this->element['placeholder']; $this->placeholder = empty($placeholder) ? $this->placeholder : $placeholder; HTML::stylesheet('plg_system_nrframework/select2.css'); HTML::script('plg_system_nrframework/vendor/select2.min.js'); HTML::script('plg_system_nrframework/ajaxify.js'); $this->class .= ' input-xxlarge select2 tf-select-ajaxify'; return '
' . parent::getInput() . '
'; } protected function getAjaxEndpoint() { $reflector = new ReflectionClass($this); $filename = $reflector->getFileName(); $file = JFile::stripExt(basename($filename)); $token = JSession::getFormToken(); $field_attributes = (array) $this->element->attributes(); $data = [ 'task' => 'include', 'file' => $file, 'path' => 'plugins/system/nrframework/fields/', 'class' => get_called_class(), $token => 1, 'field_attributes' => $field_attributes['@attributes'] ]; return JURI::base() . '?option=com_ajax&format=raw&plugin=nrframework&' . http_build_query($data); } /** * Returns data object used by the AJAX request * * @param array $options * * @return array */ public function onAjax($options) { $this->options = new Registry($options); // Reinitialize Field $this->element = (array) $this->options->get('field_attributes'); $this->init(); $this->limit = $this->options->get('limit', $this->limit); $this->page = $this->options->get('page', 1); $this->search_term = $this->options->get('term'); $rows = $this->getItems(); $hasMoreRecords = false; if ($this->limit > 0) { $total = $this->getItemsTotal(); $hasMoreRecords = ($this->page * $this->limit) < $total; } $data = [ 'results' => $rows, 'pagination' => ['more' => $hasMoreRecords] ]; echo json_encode($data); } /** * Load selected options * * @return void */ protected function getOptions() { $options = $this->value; if (empty($options)) { return; } // In case the value is previously saved in a comma separated format. if (!is_array($options)) { $options = explode(',', $options); } if (!method_exists($this, 'validateOptions')) { return $options; } // Remove empty and null items $options = array_filter($options); try { return $this->validateOptions($options); } catch (Exception $e) { echo $e->getMessage(); } } /** * This method is called by the onAjax method and must return an array of arrays * * @return void */ abstract protected function getItems(); abstract protected function getItemsTotal(); }PK!Fu#system/nrframework/fields/users.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; use \NRFramework\HTML; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNR_Users extends NRFormField { public $type = 'Users'; protected function getInput() { $this->params = $this->element->attributes(); if (!is_array($this->value)) { $this->value = explode(',', $this->value); } $options = $this->getUsers(); $size = (int) $this->get('size', 300); return HTML::treeselectSimple($options, $this->name, $this->value, $this->id, $size); } public function getUsers() { $query = $this->db->getQuery(true) ->select('COUNT(u.id)') ->from('#__users AS u') ->where('u.block = 0'); $this->db->setQuery($query); $total = $this->db->loadResult(); $query->clear('select') ->select('u.name, u.username, u.id') ->order('name'); $this->db->setQuery($query); $list = $this->db->loadObjectList(); return $this->getOptionsByList($list, array('username', 'id')); } } PK!HBB.system/nrframework/fields/nrdjcfcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRDJCFCategories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = true; /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('id as value, name as text, parent_id as `parent`, IF (published=1, 0, 1) as disable') ->from('#__djcf_categories'); $db->setQuery($query); return $db->loadObjectList(); } } PK![J!system/nrframework/fields/geo.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once JPATH_PLUGINS . '/system/nrframework/helpers/fieldlist.php'; class JFormFieldNR_Geo extends NRFormFieldList { private $list; protected function getInput() { if ($this->get('detect_visitor_country', false) && empty($this->value) && $countryCode = $this->getVisitorCountryCode()) { $this->value = $countryCode; } return parent::getInput(); } protected function getOptions() { switch ($this->get('geo')) { case 'continents': $this->list = \NRFramework\Continents::getContinentsList(); $selectLabel = 'NR_SELECT_CONTINENT'; break; default: $this->list = \NRFramework\Countries::getCountriesList(); $selectLabel = 'NR_SELECT_COUNTRY'; break; } if ($this->get('use_label_as_value', false)) { $this->list = array_combine($this->list, $this->list); } $options = array(); if ($this->get("showselect", 'true') === 'true') { $options[] = JHTML::_('select.option', "", "- " . JText::_($selectLabel) . " -"); } foreach ($this->list as $key => $value) { $options[] = JHTML::_('select.option', $key, $value); } return array_merge(parent::getOptions(), $options); } /** * Detect visitor's country * * @return string The visitor's country code (GR) */ private function getVisitorCountryCode() { $path = JPATH_PLUGINS . '/system/tgeoip/'; if (!\JFolder::exists($path)) { return; } if (!class_exists('TGeoIP')) { @include_once $path . 'vendor/autoload.php'; @include_once $path . 'helper/tgeoip.php'; } $geo = new \TGeoIP(); return $geo->getCountryCode(); } }PK!uK 2system/nrframework/fields/nrhikashopcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRHikaShopCategories extends JFormFieldNRTreeSelect { /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.category_id as value, a.category_name as text, (a.category_depth - 1) AS level, a.category_parent_id as parent, IF (a.category_published=1, 0, 1) as disable') ->from('#__hikashop_category as a') ->join('LEFT', '#__hikashop_category AS b on a.category_left > b.category_left AND a.category_right < b.category_right') ->group('a.category_id, a.category_name, a.category_left') ->where($db->quoteName('a.category_type') . ' = ' . $db->quote('product')) ->where($db->quoteName('a.category_id') . ' > 2') ->order('a.category_left ASC'); $db->setQuery($query); return $db->loadObjectList(); } } PK!l  1system/nrframework/fields/nrjeventscategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRJEventsCategories extends JFormFieldNRTreeSelect { /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.id as value, a.title as text, COUNT(DISTINCT b.id) AS level, a.parent_id as parent, IF (a.published=1, 0, 1) as disable') ->from('#__categories as a') ->join('LEFT', '#__categories AS b on a.lft > b.lft AND a.rgt < b.rgt') ->where('a.extension = "com_jevents"') ->group('a.id, a.title, a.lft') ->order('a.lft ASC'); $db->setQuery($query); return $db->loadObjectList(); } } PK!6system/nrframework/fields/nreventbookingcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNREventBookingCategories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('id as value, name as text, level, parent, IF (published=1, 0, 1) as disable') ->from('#__eb_categories'); $db->setQuery($query); return $db->loadObjectList(); } } PK!YY'system/nrframework/fields/smarttags.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once dirname(__DIR__) . "/helpers/smarttags.php"; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNR_SmartTags extends NRFormField { /** * Method to render the input field * * @return string */ function getInput() { $smartTags = new NRSmartTags(); // Add extra tags by calling an external method if ($tagsMethod = $this->get("tagsMethod", null)) { $method = explode("::", $tagsMethod); if (is_array($method)) { $extraTags = call_user_func($method); $smartTags->add($extraTags); } } $tags = $smartTags->get(); if (!$tags || !is_array($tags)) { return; } $html[] = '
' . $this->prepareText($this->get("linklabel", "NR_SMARTTAGS_SHOW")) . '
'; foreach ($tags as $tag => $value) { $html[] = ''; } $html[] = '
'; $this->addScript(); return implode(" ", $html); } /** * Adds field's script and CSS into the document once */ private function addScript() { static $run; if ($run) { return; } // Add script $this->doc->addScriptDeclaration(' jQuery(function($) { $(".nrst-btn").click(function() { list = $(this).next(); $(this).find(".l").html(list.is(":visible") ? $(this).data("show-label") : $(this).data("hide-label")); list.slideToggle(); }) $(".nrst-list a").click(function() { var tag = $(this); copyTextToClipboard(tag.data("clipboard"), function(success) { if (success) { tag.addClass("copied"); } setTimeout(function() { tag.removeClass("copied"); }, 1000); }); return false; }); function copyTextToClipboard(text, callback) { var textArea = document.createElement("textarea"); textArea.style.position = "fixed"; textArea.style.top = 0; textArea.style.left = 0; textArea.style.width = "2em"; textArea.style.height = "2em"; textArea.style.background = "transparent"; textArea.value = text; document.body.appendChild(textArea); textArea.select(); try { var success = document.execCommand("copy"); callback(success); } catch (err) { callback(false); } document.body.removeChild(textArea); } }) '); // Add height if ($height = $this->get("height", null)) { $this->doc->addStyleDeclaration(' .nrst-wrap { height: ' . $height . '; overflow-x: hidden; padding-right: 10px; }' ); } // Add CSS $this->doc->addStyleDeclaration(' .nrst-wrap { display:none; } .nrst-list { display:flex; flex-wrap: wrap; margin:10px -3px 0 -3px; } .nrst-list div { min-width:50%; } .nrst-list a { -webkit-transition: background 150ms ease; -moz-transition: background 150ms ease; transition: background 150ms ease; color: inherit; text-decoration: none; display: block; border: solid 1px #ddd; padding: 7px; line-height: 1; margin: 3px; font-size: 12px; } .nrst-list a:hover { background-color:#eee; } .nrst-list a:after { font-family: "IcoMoon"; font-style: normal; speak: none; float: right; font-size: 10px; line-height: 1; } .nrst-list a:hover:after { content: "\e018"; } .nrst-list a.copied { background:#dff0d8; } .nrst-list a.copied:after { content: "\47"; color: green; } '); $run = true; } }PK!F%system/nrframework/fields/modules.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once JPATH_PLUGINS . '/system/nrframework/helpers/fieldlist.php'; class JFormFieldModules extends NRFormFieldList { /** * Method to get a list of options for a list input. * * @return array An array of JHtml options. */ protected function getOptions() { $db = $this->db; $query = $db->getQuery(true); $query->select('*') ->from('#__modules') ->where('published=1') ->where('access !=3') ->order('title'); $client = isset($this->element['client']) ? (int) $this->element['client'] : false; if ($client !== false) { $query->where('client_id = ' . $client); } $rows = $db->setQuery($query); $results = $db->loadObjectList(); $options = array(); if ($this->showSelect()) { $options[] = JHTML::_('select.option', "", '- ' . JText::_("NR_SELECT_MODULE") . ' -'); } foreach ($results as $option) { $options[] = JHTML::_('select.option', $option->id, $option->title); } $options = array_merge(parent::getOptions(), $options); return $options; } }PK!F "system/nrframework/fields/rate.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; JFormHelper::loadFieldClass('text'); require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNR_Rate extends NRFormField { /** * The form field type. * * @var string */ public $type = 'nr_rate'; /** * Method to get the field input markup. * * @return string The field input markup. */ public function getInput() { // Setup properties $this->starwidth = $this->get('starwidth', '25px'); $this->numstarts = $this->get('numstars', 5); $this->maxvalue = $this->get('maxvalue', 5); $this->halfstar = $this->get('halfstar', 0) ? "true" : "false"; $this->spacing = $this->get('spacing', "3px"); $this->ratedfill = $this->get('ratedfill', "#e7711b"); $this->value = empty($this->value) ? 0 : $this->value; static $run; if (!$run) { // Add styles and scripts to DOM JHtml::_('jquery.framework'); JHtml::script('plg_system_nrframework/vendor/jquery.rateyo.min.js', ['relative' => true, 'version' => true]); JHtml::stylesheet('plg_system_nrframework/vendor/jquery.rateyo.min.css', ['relative' => true, 'version' => true]); $this->doc->addStyleDeclaration(' .nr_rate { display: flex; align-items: center; } .nr_rate_preview { background-color: #393939; color: #fff; padding: 7px; font-size: 12px; line-height: 1; min-width: 20px; text-align: center; border-radius: 2px; position:relative; top:2px; } .nr_rate .jq-ry-container { padding: 0 10px 0 0; } .nr_rate svg { max-width: unset; } '); $run = true; } $this->doc->addScriptDeclaration(' jQuery(function($) { $("#nr_rate_'.$this->id.'").rateYo({ rating: ' . $this->value . ', starWidth: "'. $this->starwidth .'", numStars: ' . $this->numstarts . ', maxValue: ' . $this->maxvalue . ', halfStar: ' . $this->halfstar . ', spacing: "' . $this->spacing . '", ratedFill: "' . $this->ratedfill . '", onInit: function (rating) { $(this).parent().find(".nr_rate_preview").html(rating); }, onSet: function(rating) { $(this).next("input").val(rating); }, onChange: function(rating) { $(this).parent().find(".nr_rate_preview").html(rating); } }); }); '); $html[] = '
'; $html[] = '
'; $html[] = ''; $html[] = ''; $html[] = '
'; return implode(" ", $html); } }PK!g֦&system/nrframework/fields/freetext.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNR_Freetext extends NRFormField { /** * The field type. * * @var string */ public $type = 'freetext'; /** * Method to render the input field * * @return string */ protected function getInput() { $file = $this->get("file", false); $text = $this->get("text", false); $label = $this->get("label", false); if (!$label) { $html[] = '
'; } if ($file) { $html[] = $this->renderContent($this->get("file"), $this->get("path"), $this); } if ($text) { $html[] = $this->prepareText($text); } return implode(" ", $html); } /** * Render PHP file with data * * @param string $file The file name * @param string $path The pathname * @param mixed $displayData The data object passed to template file * * @return string HTML rendered */ private function renderContent($file, $path, $displayData = null) { $layout = new JLayoutFile($file, JPATH_SITE . $path, array('debug' => 0)); return $layout->render($displayData); } }PK!B49 9 *system/nrframework/fields/geodbchecker.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; class JFormFieldGeoDBChecker extends JFormField { /** * Whether TGeoIP is disabled or not. * * @var boolean */ private $tgeoip_plugin_disabled = false; protected function getLabel() { return; } /** * Renders the field. * * @param array $options * * @return string */ public function renderField($options = []) { // Check if TGeoIP plugin is enabled if (!\NRFramework\Extension::pluginIsEnabled('tgeoip')) { $this->tgeoip_plugin_disabled = true; return parent::renderField($options); } // Do not render the field if the database is up-to-date if (!\NRFramework\Extension::geoPluginNeedsUpdate()) { return; } return parent::renderField($options); } /** * Shows a warning message when the Geolocation plugin is disabled. * * @return string */ private function disabledPluginWarning() { return '
' . '

' . JText::sprintf('NR_GEO_PLUGIN_DISABLED') . '

' . '

' . JText::sprintf('NR_GEO_PLUGIN_DISABLED_DESC', '', '') . '

' . '
'; } /** * If the geolocation database is missing or its outdated, then display a helpful message * to the usser notifying them that they need to update. * * @return string */ protected function getInput() { if ($this->tgeoip_plugin_disabled) { return $this->disabledPluginWarning(); } return '
' . '

' . JText::sprintf('NR_GEO_MAINTENANCE') . '

' . '

' . JText::sprintf('NR_GEO_MAINTENANCE_DESC') . '

' . ' Update Database' . '
'; } }PK!?[ H H "system/nrframework/fields/time.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNR_Time extends NRFormField { /** * Sets the time value * * @var string $time_value */ private $time_value = null; /** * Method to get the field input markup. * * @return string The field input markup. */ public function getInput() { // Setup properties $this->hint = $this->get('hint', '00:00'); $this->class = $this->get('class'); $this->placement = $this->get('placement', 'top'); $this->align = $this->get('align', 'left'); $this->autoclose = $this->get('autoclose', 'true'); $this->default = $this->get('default', 'now'); $this->donetext = $this->get('donetext', 'Done'); $this->required = $this->get('required') === 'true'; /** * When an object is created using this class, it cannot set $this->value * So we set $time_value and then use it's value to display the time */ $this->value = !is_null($this->time_value) ? $this->time_value : $this->value; // Add styles and scripts to DOM JHtml::_('jquery.framework'); JHtml::script('plg_system_nrframework/vendor/jquery-clockpicker.min.js', ['relative' => true, 'version' => true]); JHtml::stylesheet('plg_system_nrframework/vendor/jquery-clockpicker.min.css', ['relative' => true, 'version' => true]); static $run; // Run once to initialize it if (!$run) { $this->doc->addScriptDeclaration(' jQuery(function($) { $(".clockpicker").clockpicker(); }); '); // Fix a CSS conflict caused by the template.css on Joomla 3 if (!defined('nrJ4')) { // Fuck you template.css $this->doc->addStyleDeclaration(' .clockpicker-align-left.popover > .arrow { left: 25px; } '); } $run = true; } return '
' . parent::getInput() . '
'; } /** * Sets the $time_value of the time when created as an object * due to not being able to set the $this->value byitself * * @param string $value * * @return void */ public function setValue($value) { $this->time_value = $value; } }PK!m+system/nrframework/fields/rulevaluehint.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; class JFormFieldRuleValueHint extends JFormField { protected function getLabel() { return; } /** * Method to render the input field * * @return string */ protected function getInput() { $ruleName = (string) $this->element['ruleName']; $rule = \NRFramework\Factory::getCondition($ruleName); return '
' . $rule->getValueHint() . '
'; } }PK!̺"system/nrframework/fields/nrk2.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once JPATH_PLUGINS . '/system/nrframework/helpers/groupfield.php'; class JFormFieldNRK2 extends NRFormGroupField { public $type = 'K2'; /** * Pagetypes options * * @var array */ public $pagetype_options = array( 'itemlist_category' => 'NR_ASSIGN_K2_CATEGORY_OPTION', 'item_item' => 'NR_ASSIGN_K2_ITEM_OPTION', 'item_itemform' => 'NR_ASSIGN_K2_ITEM_FORM_OPTION', 'latest_latest' => 'NR_ASSIGN_K2_LATEST_OPTION', 'itemlist_tag' => 'NR_ASSIGN_K2_TAG_OPTION', 'itemlist_user' => 'NR_ASSIGN_K2_USER_PAGE_OPTION' ); public function getItems() { $query = $this->db->getQuery(true); $query ->select('i.id, i.title as name, i.language, c.name as cat, i.published') ->from('#__k2_items as i') ->join('LEFT', '#__k2_categories AS c ON c.id = i.catid') ->order('i.title, i.ordering, i.id'); $this->db->setQuery($query); $list = $this->db->loadObjectList(); return $this->getOptionsByList($list, array('language', 'cat', 'id')); } public function getPagetypes() { asort($this->pagetype_options); foreach ($this->pagetype_options as $key => $option) { $options[] = JHTML::_('select.option', $key, JText::_($option)); } return $options; } public function getTags() { $query = $this->db->getQuery(true); $query ->select('t.id, t.name') ->from('#__k2_tags as t') ->order('t.id'); $this->db->setQuery($query); $list = $this->db->loadObjectList(); return $this->getOptionsByList($list); } public function getCategories() { $query = $this->db->getQuery(true); $query ->select('c.id, c.name, c.parent, c.published, c.language') ->from('#__k2_categories as c') ->where('c.trash = 0') ->where('c.id != c.parent') ->order('c.ordering'); $this->db->setQuery($query); $cats = $this->db->loadObjectList(); $options = []; // get category levels foreach ($cats as $c) { $level = 0; $parent_id = (int)$c->parent; while ($parent_id) { $level++; $parent_id = $this->getNextParentId($cats, $parent_id); } $c->level = $level; $options[] = $c; } // sort options $options = $this->sortTreeSelectOptions($options); return $this->getOptionsByList($options, array('language')); } /** * Sorts treeselect options * * @param array $options * @param int $parent_id * * @return array */ protected function sortTreeSelectOptions($options, $parent_id = 0) { if (empty($options)) { return []; } $result = []; $sub_options = array_filter($options, function($option) use($parent_id) { return $option->parent == $parent_id; }); foreach ($sub_options as $option) { $result[] = $option; $result = array_merge($result, $this->sortTreeSelectOptions($options, $option->id)); } return $result; } /** * Returns the next parent id * Helper method for getCategories * * @return int */ protected function getNextParentId($categories, $current_pid) { foreach($categories as $c) { if ((int)$c->id === $current_pid) { return (int)$c->parent; } } } } PK!Yt7system/nrframework/fields/nrsppagebuildercategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRSPPageBuilderCategories extends JFormFieldNRTreeSelect { /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.id as value, a.title as text, (COUNT(DISTINCT b.id) - 1) AS level, a.parent_id as parent, IF (a.published=1, 0, 1) as disable') ->from('#__categories as a') ->join('LEFT', '#__categories AS b on a.lft > b.lft AND a.rgt < b.rgt') ->where('a.extension = "com_sppagebuilder"') ->group('a.id, a.title, a.lft') ->order('a.lft ASC'); $db->setQuery($query); return $db->loadObjectList(); } } PK!EE-system/nrframework/fields/nrzoocategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRZooCategories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = true; /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('id as value, name as text, parent as `parent`, IF (published=1, 0, 1) as disable') ->from('#__zoo_category') ->order('ordering'); $db->setQuery($query); return $db->loadObjectList(); } } PK! "system/nrframework/fields/well.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNR_Well extends NRFormField { /** * The field type. * * @var string */ public $type = 'nr_well'; /** * Layout to render the form field * * @var string */ protected $renderLayout = 'well'; /** * Override renderer include path * * @return array */ protected function getLayoutPaths() { return JPATH_PLUGINS . '/system/nrframework/layouts/'; } /** * Method to render the input field * * @return string */ protected function getInput() { JHtml::stylesheet('plg_system_nrframework/fields.css', ['relative' => true, 'version' => 'auto']); $title = $this->get('label'); $description = $this->get('description'); $url = $this->get('url'); $class = $this->get('class'); $start = $this->get('start', 0); $end = $this->get('end', 0); $info = $this->get("html", null); if ($info) { $info = str_replace("{{", "<", $info); $info = str_replace("}}", ">", $info); } $html = array(); if ($start || !$end) { if ($title) { $html[] = '

' . $this->prepareText($title) . '

'; } if ($description) { $html[] = '
' . $this->prepareText($description) . $info . '
'; } if ($url) { if (defined('nrJ4')) { $html[] = ''; } else { $html[] = ''; } } } if ($end) { $html[] = '
'; } return implode('', $html); } }PK!sh'system/nrframework/fields/nrmodules.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2019 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once JPATH_PLUGINS . '/system/nrframework/helpers/fieldlist.php'; class JFormFieldNRModules extends NRFormFieldList { /** * Provide a list of all published modules. * * @return array An array of JHtml options. */ protected function getOptions() { // Get modules $modules = $this->getModules(); // get all position options $options = []; $options[] = JHTML::_('select.option', '', \JText::_('NR_NONE_SELECTED')); foreach ($modules as $module) { $options[] = JHTML::_('select.option', $module->id, $module->title . ' (' . $module->id . ')'); } return array_merge(parent::getOptions(), $options); } /** * Returns all enabled modules. * * @return object */ private function getModules() { $db = $this->db; $query = $db->getQuery(true); $query->select('id, title'); $query->from('#__modules'); $query->where('published = 1'); $db->setQuery($query); return $db->loadObjectList(); } }PK!zJ&system/nrframework/fields/nrnumber.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; JFormHelper::loadFieldClass('number'); class JFormFieldNRNumber extends JFormFieldNumber { /** * Method to render the input field * * @return string */ function getInput() { $parent = parent::getInput(); $addon = (string) $this->element['addon']; if (empty($addon)) { return $parent; } return '
' . $parent . ' ' . JText::_($addon) . '
'; } } PK!*W^"system/nrframework/fields/nros.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once JPATH_PLUGINS . '/system/nrframework/helpers/fieldlist.php'; class JFormFieldNROs extends NRFormFieldList { /** * Browsers List * * @var array */ public $options = array( 'linux' => 'NR_LINUX', 'mac' => 'NR_MAC', 'android' => 'NR_ANDROID', 'ios' => 'NR_IOS', 'windows' => 'NR_WINDOWS', 'blackberry' => 'NR_BLACKBERRY', 'chromeos' => 'NR_CHROMEOS' ); protected function getOptions() { asort($this->options); foreach ($this->options as $key => $option) { $options[] = JHTML::_('select.option', $key, JText::_($option)); } return array_merge(parent::getOptions(), $options); } }PK!f=F331system/nrframework/fields/nrgridboxcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRGridboxCategories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = true; /** * Get a list of all Gridbox Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('id as value, title as text, parent as parent, IF (published=1, 0, 1) as disable') ->from('#__gridbox_categories'); $db->setQuery($query); return $db->loadObjectList(); } } PK!r@4system/nrframework/fields/nrdjcatalog2categories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRDJCatalog2Categories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = true; /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { $db = $this->db; $query = $db->getQuery(true) ->select('id as value, name as text, parent_id as parent, IF (published=1, 0, 1) as disable') ->from('#__djc2_categories'); $db->setQuery($query); return $db->loadObjectList(); } } PK!tF (system/nrframework/fields/treeselect.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ use \NRFramework\HTML; defined('_JEXEC') or die; abstract class JFormFieldNRTreeSelect extends JFormField { /** * Database object * * @var object */ public $db; /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = false; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = false; /** * Increase the value(ID) of the category by one. * This happens because we have a parent category "Bussiness Directory" that pushes-in the indentation * and we reset it by decreasing the value, level and parent. * * @var boolean */ protected $increaseValue = false; /** * Output the HTML for the field */ protected function getInput() { $this->db = JFactory::getDbo(); $options = $this->getOptions(); if ($this->sortTree) { $options = $this->sortTreeSelectOptions($options); } if ($this->fixLevels) { $options = $this->fixLevels($options); } if ($this->increaseValue) { // Increase by 1 the value(ID) of the category foreach ($options as $key => $value) { $options[$key]->value+=1; } } return HTML::treeselect($options, $this->name, $this->value, $this->id); } /** * Sorts treeselect options * * @param array $options * @param int $parent_id * * @return array */ protected function sortTreeSelectOptions($options, $parent_id = 0) { if (empty($options)) { return []; } $result = []; $sub_options = array_filter($options, function($option) use($parent_id) { return $option->parent == $parent_id; }); foreach ($sub_options as $option) { $result[] = $option; $result = array_merge($result, $this->sortTreeSelectOptions($options, $option->value)); } return $result; } /** * Fixes the levels of the categories * * @param array $categories * * @return array */ protected function fixLevels($cats) { // new categories $categories = []; // get category levels foreach ($cats as $c) { $level = 0; $parent_id = (int)$c->parent; while ($parent_id) { $level++; $parent_id = $this->getNextParentId($cats, $parent_id); } $c->level = $level; $categories[] = $c; } return $categories; } /** * Returns the next parent id * Helper method for getCategories * * @return int */ protected function getNextParentId($categories, $current_pid) { foreach($categories as $c) { if ((int)$c->value === $current_pid) { return (int)$c->parent; } } } /** * Get tree options as an Array of objects * Each object should have the attributes: value, text, parent, level, disable * * @return object */ abstract protected function getOptions(); }PK! &system/nrframework/fields/nrtoggle.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use NRFramework\HTML; JFormHelper::loadFieldClass('checkbox'); /** * Pure CSS iOS-like Toggle Button based on the Checkbox field. * * This field also fixes the Unchecked checkbox value using a hidden field. * Credits: http://mistercameron.com/2008/01/unchecked-checkbox-values/ */ class JFormFieldNRToggle extends JFormFieldCheckbox { /** * On state value * * @var int */ protected $on_value = 1; /** * Off state value * * @var int */ protected $off_value = 0; /** * Method to get the field input markup. * * @return string */ public function getInput() { HTML::stylesheet('plg_system_nrframework/toggle.css'); $required = $this->required ? ' required aria-required="true"' : ''; $checked = $this->checked ? ' checked' : ''; $class = !empty($this->class) ? ' ' . $this->class : ''; // Fix bug inherited from the Checkbox field where the input remains checked even if save it unchecked. if ($this->checked && (string) $this->value == (string) $this->off_value) { $checked = ''; } return ' '; } }PK!fS%zz(system/nrframework/fields/akeebasubs.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file // defined('_JEXEC') or die; jimport('joomla.form.helper'); JFormHelper::loadFieldClass('list'); class JFormFieldAkeebaSubs extends JFormFieldList { /** * Method to get a list of options for a list input. * * @return array An array of JHtml options. */ protected function getOptions() { if (!NRFramework\Extension::isInstalled('akeebasubs')) { return; } $lists = $this->getLevels(); if (!count($lists)) { return; } $options = array(); foreach ($lists as $option) { $options[] = JHTML::_('select.option', $option->id, $option->name); } return array_merge(parent::getOptions(), $options); } /** * Retrieve all Akeeba Subscription Levels * * @return array Subscription Levels */ private function getLevels() { // Get a db connection. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('l.akeebasubs_level_id as id, l.title AS name, l.enabled as published') ->from('#__akeebasubs_levels AS l') ->where('l.enabled > -1') ->order('l.title, l.akeebasubs_level_id'); $db->setQuery($query); return $db->loadObjectList(); } }PK!ibb3system/nrframework/fields/nrjshoppingcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRJShoppingCategories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = true; /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select($db->quoteName('name_' . $this->getLanguage(), 'text')) ->select('category_id as value, category_parent_id as parent, IF (category_publish=1, 0, 1) as disable') ->from('#__jshopping_categories'); $db->setQuery($query); return $db->loadObjectList(); } /** * JoomShopping is using different columns per language. Therefore, we need to use their API to get the default language code. * * @return string */ private function getLanguage($default = 'en-GB') { // Silent inclusion. @include_once JPATH_SITE . '/components/com_jshopping/lib/factory.php'; if (!class_exists('JSFactory')) { return $default; } return JSFactory::getConfig()->defaultLanguage; } } PK! ~^^&system/nrframework/fields/nrdevice.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once JPATH_PLUGINS . '/system/nrframework/helpers/fieldlist.php'; class JFormFieldNRDevice extends NRFormFieldList { /** * Browsers List * * @var array */ public $options = array( 'desktop' => 'NR_DESKTOPS', 'mobile' => 'NR_MOBILES', 'tablet' => 'NR_TABLETS' ); protected function getOptions() { asort($this->options); foreach ($this->options as $key => $option) { $options[] = JHTML::_('select.option', $key, JText::_($option)); } return array_merge(parent::getOptions(), $options); } }PK!+3̼(system/nrframework/fields/comparator.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); JFormHelper::loadFieldClass('list'); class JFormFieldComparator extends JFormFieldList { private $defaults = [ 'includes' => 'NR_IS', 'not_includes' => 'NR_IS_NOT' ]; /** * Method to get the field input markup for a generic list. * Use the multiple attribute to enable multiselect. * * @return string The field input markup. */ protected function getInput() { $this->required = true; $this->class .= ' comparator'; return parent::getInput(); } /** * Return the label. * * @return string */ protected function getLabel() { if (!isset($this->element['label'])) { $this->element['label'] = 'NR_MATCH'; } return parent::getLabel(); } /** * Return the options. * * @return string */ protected function getOptions() { if (!$options = parent::getOptions()) { $options = $this->defaults; foreach ($options as $key => &$value) { $value = JText::_($value); } } return $options; } } PK!Yj  1system/nrframework/fields/nrjcalprocategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRJCalProCategories extends JFormFieldNRTreeSelect { /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.id as value, a.title as text, COUNT(DISTINCT b.id) AS level, a.parent_id as parent, IF (a.published=1, 0, 1) as disable') ->from('#__categories as a') ->join('LEFT', '#__categories AS b on a.lft > b.lft AND a.rgt < b.rgt') ->where('a.extension = "com_jcalpro"') ->group('a.id, a.title, a.lft') ->order('a.lft ASC'); $db->setQuery($query); return $db->loadObjectList(); } } PK!*ii5system/nrframework/fields/jshoppingcomponentitems.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use Joomla\Registry\Registry; require_once __DIR__ . '/componentitems.php'; class JFormFieldJShoppingComponentItems extends JFormFieldComponentItems { public function init() { // Get default language $this->element['column_title'] = 'name_' . $this->getLanguage(); parent::init(); } /** * JoomShopping is using different columns per language. Therefore, we need to use their API to get the default language code. * * @return string */ private function getLanguage($default = 'en-GB') { // Silent inclusion. @include_once JPATH_SITE . '/components/com_jshopping/lib/factory.php'; if (!class_exists('JSFactory')) { return $default; } return JSFactory::getConfig()->defaultLanguage; } }PK!Gn "system/nrframework/fields/gmap.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use NRFramework\HTML; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNR_Gmap extends NRFormField { /** * The default Google Maps API Key * * @var string */ public $defaultAPIKey = 'AIzaSyAPgVu1A9L7_q0gtYToFeJiUHDSCCXYZKI'; /** * Method to get the field input markup. * * @return string The field input markup. */ public function getInput() { // Setup properties $this->width = $this->get('width', '500px'); $this->height = $this->get('height', '400px'); $this->zoom = $this->get('zoom', '10'); $this->margin = $this->get('margin', '0 0 10px 0'); $this->readonly = $this->get('readonly', false) ? 'readonly' : ''; $this->value = $this->checkCoordinates($this->value, null) ? $this->value : $this->get('default', '36.892587, 27.287793'); $this->hint = $this->prepareText($this->get('hint', 'NR_ENTER_COORDINATES')); // Add scripts to DOM JHtml::_('jquery.framework'); JFactory::getDocument()->addScript('//maps.googleapis.com/maps/api/js?key=' . $this->getAPIKey()); HTML::script('plg_system_nrframework/field.gmap.js'); Jtext::script('NR_WRONG_COORDINATES'); // Add styles to DOM $this->doc->addStyleDeclaration(' #' . $this->id . '_map { height: ' . $this->height . '; width: ' . $this->width . '; margin: ' . $this->margin . '; } '); return '
readonly . '/>'; } /** * Checks the validity of the coordinates */ private function checkCoordinates($coordinates) { return (preg_match("/^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/", $coordinates)); } /** * Get the Google Maps API Key. * If no key is found in the framework options then the default API Key will be used instead. * * We should update the default API Key once a while. * * @return string */ private function getAPIKey() { if (!$framework = JPluginHelper::getPlugin('system', 'nrframework')) { return $this->defaultAPIKey; } // Get plugin params $params = new JRegistry($framework->params); return $params->get('gmapkey', $this->defaultAPIKey); } }PK! KAA&system/nrframework/fields/password.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; JFormHelper::loadFieldClass('password'); class JFormFieldNR_Password extends JFormFieldPassword { /** * Method to get the field input markup. * * @return string The field input markup. */ public function getInput() { if (defined('nrJ4')) { return parent::getInput(); } $id = $this->id . '_btn'; $doc = JFactory::getDocument(); JHtml::stylesheet('plg_system_nrframework/fields.css', false, true); $doc->addStyleDeclaration(' .nr-pass-btn { display:flex; align-items:center; } .nr-pass-btn > * { margin:0 !important; padding:0 !important; } .nr-pass-btn label { margin-left:5px !important; user-select: none; } '); $doc->addScriptDeclaration(' jQuery(function($) { $("#' . $id . '").change(function() { var type = $(this).is(":checked") ? "text" : "password"; $(this).closest(".nr-pass").find(".nr-pass-input input").attr("type", type); }) }) '); return '
'. parent::getInput() .'
'; } }PK!eѮ0system/nrframework/fields/nrrsblogcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRRSBlogCategories extends JFormFieldNRTreeSelect { /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.id as value, a.title as text, (COUNT(DISTINCT b.id) - 1) AS level, a.parent_id as parent, IF (a.published=1, 0, 1) as disable') ->from('#__rsblog_categories as a') ->where('a.parent_id > 0') ->join('LEFT', '#__rsblog_categories AS b on a.lft > b.lft AND a.rgt < b.rgt') ->group('a.id, a.title, a.lft') ->order('a.lft ASC'); $db->setQuery($query); return $db->loadObjectList(); } } PK!?ѻ<<1system/nrframework/fields/nrsobiprocategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRSobiProCategories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = true; /** * Increase the value(ID) of the category by one. * This happens because we have a parent category "Bussiness Directory" that pushes-in the indentation * and we reset it by decreasing the value, level and parent. * * @var boolean */ protected $increaseValue = true; /** * Get a list of all SobiPro Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('(a.id - 1) as value, b.sValue as text, (a.parent - 1) as level, (a.parent - 1) as parent, IF (a.state=1, 0, 1) as disable') ->from('#__sobipro_object as a') ->join('LEFT', "#__sobipro_language AS b on a.id = b.id AND b.sKey = 'name'") ->where($db->quoteName('a.oType') . ' = '. $db->quote('category')); $db->setQuery($query); $result = $db->loadObjectList(); return $result; } } PK!j:%system/nrframework/fields/nrfonts.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); JFormHelper::loadFieldClass('groupedlist'); class JFormFieldNRFonts extends JFormFieldGroupedList { /** * Method to get the field option groups. * * @return array The field option objects as a nested array in groups. * * @since 1.6 */ protected function getGroups() { $groups = array(); foreach (NRFramework\Fonts::getFontGroups() as $name => $fontGroup) { // Initialize the group if necessary. if (!isset($groups[$name])) { $groups[$name] = array(); } foreach ($fontGroup as $font) { $groups[$name][] = JHtml::_('select.option', $font, $font); } } // Merge any additional groups in the XML definition. return array_merge(parent::getGroups(), $groups); } }PK!:*system/nrframework/fields/nrgrouplevel.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRGroupLevel extends JFormFieldNRTreeSelect { /** * A helper to get the list of user groups. * Logic from administrator\components\com_config\model\field\filters.php@getUserGroups * * @return object */ protected function getOptions() { // Get a database object. $db = $this->db; // Get the user groups from the database. $query = $db->getQuery(true) ->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level') ->from('#__usergroups AS a') ->join('LEFT', '#__usergroups AS b on a.lft > b.lft AND a.rgt < b.rgt') ->group('a.id, a.title, a.lft') ->order('a.lft ASC'); $db->setQuery($query); return $db->loadObjectList(); } }PK!,X -system/nrframework/fields/tfinputrepeater.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); JFormHelper::loadFieldClass('subform'); class JFormFieldTFInputRepeater extends JFormFieldSubform { /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. * * @return boolean True on success. * * @since 3.6 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $element->addAttribute('multiple', true); // By default initialize the field with an empty item. if (empty($value)) { $value = [0 => '']; } // In case we have provided a default value in the XML in JSON format if ($value && is_string($value)) { // Attempt to decode as JSON $value_ = json_decode($value, true); // If JSON decode fails, expect comma-separated or newline-separated values if (is_null($value_)) { $value = NRFramework\Functions::makeArray($value); $new_value = []; foreach ($value as $key => $val) { $new_value['value' . $key] = [ 'value' => $val ]; } $value = $new_value; } else { $value = $value_; } } parent::setup($element, $value, $group); return true; } /** * Method to get a list of options for a list input. * @return array An array of JHtml options. */ protected function getInput() { $this->layout = 'joomla.form.field.subform.repeatable-table'; $this->assets(); return '
' . parent::getInput() . '
'; } /** * Load field assets. * * @return void */ private function assets() { JHtml::stylesheet('plg_system_nrframework/tfinputrepeater.css', ['relative' => true, 'versioning' => 'auto']); JHtml::script('plg_system_nrframework/tfinputrepeater.js', ['relative' => true, 'version' => true]); } }PK!``1system/nrframework/fields/assignmentselection.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('JPATH_PLATFORM') or die; use NRFramework\HTML; JFormHelper::loadFieldClass('list'); class JFormFieldAssignmentSelection extends JFormFieldList { /** * Assignment options * * @var array */ protected $options = array( 0 => 'JDISABLED', 1 => 'NR_INCLUDE', 2 => 'NR_EXCLUDE' ); /** * Return options list to field * * @return array */ protected function getOptions() { foreach ($this->options as $key => $value) { $options[] = JHTML::_('select.option', $key, JText::_($value)); } return array_merge(parent::getOptions(), $options); } /** * Setup field with predefined classes and load its media files * * @param SimpleXMLElement $element * @param String $value * @param String $group * * @return SimpleXMLElement */ public function setup(SimpleXMLElement $element, $value, $group = NULL) { $return = parent::setup($element, $value, $group); JHtml::_('jquery.framework'); HTML::script('plg_system_nrframework/assignmentselection.js'); HTML::stylesheet('plg_system_nrframework/assignmentselection.css'); $this->class = 'assignmentselection chzn-color-state'; return $return; } }PK!C H1system/nrframework/fields/nrresponsivecontrol.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; JFormHelper::loadFieldClass('text'); use Joomla\Registry\Registry; class JFormFieldNRResponsiveControl extends JFormFieldText { /** * Method to render the input field * * @return string */ function getInput() { return $this->getLayout(); } /** * Returns html for all devices * * @return array */ private function getFieldsData() { if (!$fieldsList = $this->getSubformFieldsList()) { return []; } $html = [ 'desktop' => '', 'tablet' => '', 'mobile' => '' ]; $base_name = $fieldsList['base_name']; // loop for all devices foreach ($html as $key => $value) { $device_output = ''; // loop all fields foreach ($fieldsList['fields'] as $fieldName) { $name = $fieldName; $field_data = $this->getFieldInputByDevice($name, $key); $field_html = $field_data['html']; $field_html = str_replace( [ '[' . $this->group . '][' . $name . ']', '_' . $this->group . '_' . $name ], [ '[' . $this->group . '][' . $base_name . '][' . $name . '][' . $key . ']', '_' . $this->group . '_' . $base_name . '_' . $name . '_' . $key ], $field_html ); // Render layout $payload = [ 'label' => $field_data['label'], 'data' => $field_html ]; $layout = new JLayoutFile('responsive_control_item', JPATH_PLUGINS . '/system/nrframework/layouts'); $device_output .= $layout->render($payload); } $html[$key] = $device_output; } return $html; } /** * Returns the field layout * * @return string */ private function getLayout() { JHtml::stylesheet('plg_system_nrframework/responsive_control.css', ['relative' => true, 'version' => 'auto']); JHtml::script('plg_system_nrframework/responsive_control.js', ['relative' => true, 'version' => 'auto']); $width = isset($this->element['width']) ? (string) $this->element['width'] : '300px'; $title = isset($this->element['title']) ? (string) $this->element['title'] : ''; $class = isset($this->element['class']) ? ' ' . (string) $this->element['class'] : ''; if (defined('nrJ4')) { $class .= ' isJ4'; } $data = [ 'title' => JText::_($title), 'width' => $width, 'class' => $class, 'fields' => $this->getFieldsData() ]; // Render layout $layout = new JLayoutFile('responsive_control', JPATH_PLUGINS . '/system/nrframework/layouts'); return $layout->render($data); } /** * Returns the list of added fields * * @return array */ private function getSubformFieldsList() { $el = $this->element; if (empty(count($el->subform))) { return []; } $data = [ 'base_name' => $el->attributes()->name, 'fields' => [] ]; foreach ($el->subform->field as $key => $field) { $data['fields'][] = (string) $field->attributes()->name; } return $data; } /** * Returns the field's title and value * * @param string $field_name * @param string $device * * @return array */ private function getFieldInputByDevice($field_name, $device) { $el = $this->element; $data = []; foreach ($el->subform->field as $key => $field) { $name = $field->attributes()->name; if ($name != $field_name) { continue; } $data = [ 'label' => JText::_($field->attributes()->label), 'html' => $this->form->getInput($name, $this->group, $this->getFieldInputValue($field_name, $device)) ]; } return $data; } /** * Finds the field input value * * @param string $field_name * @param string $device * * @return string */ private function getFieldInputValue($field_name, $device) { $values = $this->getValue(); $values = new Registry($values); return $values->get($field_name . '.' . $device); } /** * Returns the field value * * @return mixed */ private function getValue() { if (empty($this->value)) { return; } return $this->value; } } PK!o>(system/nrframework/fields/currencies.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once JPATH_PLUGINS . '/system/nrframework/helpers/fieldlist.php'; class JFormFieldNR_Currencies extends NRFormFieldList { public $currencies = array( "AED" => "United Arab Emirates Dirham", "AFN" => "Afghan Afghani", "ALL" => "Albanian Lek", "AMD" => "Armenian Dram", "ANG" => "Netherlands Antillean Guilder", "AOA" => "Angolan Kwanza", "ARS" => "Argentine Peso", "AUD" => "Australian Dollar", "AWG" => "Aruban Florin", "AZN" => "Azerbaijani Manat", "BAM" => "Bosnia-Herzegovina Convertible Mark", "BBD" => "Barbadian Dollar", "BDT" => "Bangladeshi Taka", "BGN" => "Bulgarian Lev", "BHD" => "Bahraini Dinar", "BIF" => "Burundian Franc", "BMD" => "Bermudan Dollar", "BND" => "Brunei Dollar", "BOB" => "Bolivian Boliviano", "BRL" => "Brazilian Real", "BSD" => "Bahamian Dollar", "BTC" => "Bitcoin", "BTN" => "Bhutanese Ngultrum", "BWP" => "Botswanan Pula", "BYN" => "Belarusian Ruble", "BYR" => "Belarusian Ruble (pre-2016)", "BZD" => "Belize Dollar", "CAD" => "Canadian Dollar", "CDF" => "Congolese Franc", "CHF" => "Swiss Franc", "CLF" => "Chilean Unit of Account (UF)", "CLP" => "Chilean Peso", "CNY" => "Chinese Yuan", "COP" => "Colombian Peso", "CRC" => "Costa Rican Colón", "CUC" => "Cuban Convertible Peso", "CUP" => "Cuban Peso", "CVE" => "Cape Verdean Escudo", "CZK" => "Czech Republic Koruna", "DJF" => "Djiboutian Franc", "DKK" => "Danish Krone", "DOP" => "Dominican Peso", "DZD" => "Algerian Dinar", "EEK" => "Estonian Kroon", "EGP" => "Egyptian Pound", "ERN" => "Eritrean Nakfa", "ETB" => "Ethiopian Birr", "EUR" => "Euro", "FJD" => "Fijian Dollar", "FKP" => "Falkland Islands Pound", "GBP" => "British Pound Sterling", "GEL" => "Georgian Lari", "GGP" => "Guernsey Pound", "GHS" => "Ghanaian Cedi", "GIP" => "Gibraltar Pound", "GMD" => "Gambian Dalasi", "GNF" => "Guinean Franc", "GTQ" => "Guatemalan Quetzal", "GYD" => "Guyanaese Dollar", "HKD" => "Hong Kong Dollar", "HNL" => "Honduran Lempira", "HRK" => "Croatian Kuna", "HTG" => "Haitian Gourde", "HUF" => "Hungarian Forint", "IDR" => "Indonesian Rupiah", "ILS" => "Israeli New Sheqel", "IMP" => "Manx pound", "INR" => "Indian Rupee", "IQD" => "Iraqi Dinar", "IRR" => "Iranian Rial", "ISK" => "Icelandic Króna", "JEP" => "Jersey Pound", "JMD" => "Jamaican Dollar", "JOD" => "Jordanian Dinar", "JPY" => "Japanese Yen", "KES" => "Kenyan Shilling", "KGS" => "Kyrgystani Som", "KHR" => "Cambodian Riel", "KMF" => "Comorian Franc", "KPW" => "North Korean Won", "KRW" => "South Korean Won", "KWD" => "Kuwaiti Dinar", "KYD" => "Cayman Islands Dollar", "KZT" => "Kazakhstani Tenge", "LAK" => "Laotian Kip", "LBP" => "Lebanese Pound", "LKR" => "Sri Lankan Rupee", "LRD" => "Liberian Dollar", "LSL" => "Lesotho Loti", "LTL" => "Lithuanian Litas", "LVL" => "Latvian Lats", "LYD" => "Libyan Dinar", "MAD" => "Moroccan Dirham", "MDL" => "Moldovan Leu", "MGA" => "Malagasy Ariary", "MKD" => "Macedonian Denar", "MMK" => "Myanma Kyat", "MNT" => "Mongolian Tugrik", "MOP" => "Macanese Pataca", "MRO" => "Mauritanian Ouguiya", "MTL" => "Maltese Lira", "MUR" => "Mauritian Rupee", "MVR" => "Maldivian Rufiyaa", "MWK" => "Malawian Kwacha", "MXN" => "Mexican Peso", "MYR" => "Malaysian Ringgit", "MZN" => "Mozambican Metical", "NAD" => "Namibian Dollar", "NGN" => "Nigerian Naira", "NIO" => "Nicaraguan Córdoba", "NOK" => "Norwegian Krone", "NPR" => "Nepalese Rupee", "NZD" => "New Zealand Dollar", "OMR" => "Omani Rial", "PAB" => "Panamanian Balboa", "PEN" => "Peruvian Nuevo Sol", "PGK" => "Papua New Guinean Kina", "PHP" => "Philippine Peso", "PKR" => "Pakistani Rupee", "PLN" => "Polish Zloty", "PYG" => "Paraguayan Guarani", "QAR" => "Qatari Rial", "RON" => "Romanian Leu", "RSD" => "Serbian Dinar", "RUB" => "Russian Ruble", "RWF" => "Rwandan Franc", "SAR" => "Saudi Riyal", "SBD" => "Solomon Islands Dollar", "SCR" => "Seychellois Rupee", "SDG" => "Sudanese Pound", "SEK" => "Swedish Krona", "SGD" => "Singapore Dollar", "SHP" => "Saint Helena Pound", "SLL" => "Sierra Leonean Leone", "SOS" => "Somali Shilling", "SRD" => "Surinamese Dollar", "STD" => "São Tomé and Príncipe Dobra", "SVC" => "Salvadoran Colón", "SYP" => "Syrian Pound", "SZL" => "Swazi Lilangeni", "THB" => "Thai Baht", "TJS" => "Tajikistani Somoni", "TMT" => "Turkmenistani Manat", "TND" => "Tunisian Dinar", "TOP" => "Tongan Pa?anga", "TRY" => "Turkish Lira", "TTD" => "Trinidad and Tobago Dollar", "TWD" => "New Taiwan Dollar", "TZS" => "Tanzanian Shilling", "UAH" => "Ukrainian Hryvnia", "UGX" => "Ugandan Shilling", "USD" => "United States Dollar", "UYU" => "Uruguayan Peso", "UZS" => "Uzbekistan Som", "VEF" => "Venezuelan Bolívar Fuerte", "VND" => "Vietnamese Dong", "VUV" => "Vanuatu Vatu", "WST" => "Samoan Tala", "XAF" => "CFA Franc BEAC", "XAG" => "Silver Ounce", "XAU" => "Gold Ounce", "XCD" => "East Caribbean Dollar", "XDR" => "Special Drawing Rights", "XOF" => "CFA Franc BCEAO", "XPD" => "Palladium Ounce", "XPF" => "CFP Franc", "XPT" => "Platinum Ounce", "YER" => "Yemeni Rial", "ZAR" => "South African Rand", "ZMK" => "Zambian Kwacha (pre-2013)", "ZMW" => "Zambian Kwacha", "ZWL" => "Zimbabwean Dollar", ); protected function getOptions() { $options = array(); if ($this->showSelect()) { $options[] = JHTML::_('select.option', "", "- " . JText::_("NR_SELECT_CURRENCY"). " -"); } asort($this->currencies); foreach ($this->currencies as $key => $value) { $options[] = JHTML::_('select.option', $key, $key . " (" . $value . ")"); } return array_merge(parent::getOptions(), $options); } }PK!f6system/nrframework/fields/virtuemartcomponentitems.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use Joomla\Registry\Registry; require_once __DIR__ . '/componentitems.php'; class JFormFieldVirtueMartComponentItems extends JFormFieldComponentItems { public function init() { // Get default language $this->element['table'] = 'virtuemart_products_' . $this->getLanguage(); parent::init(); } /** * VirtueMart is using different tables per language. Therefore, we need to use their API to get the default language code * * @return string */ private function getLanguage($default = 'en_gb') { // Silent inclusion. @include_once JPATH_ADMINISTRATOR . '/components/com_virtuemart/helpers/config.php'; if (!class_exists('VmConfig')) { return $default; } // Init configuration VmConfig::loadConfig(); return VmConfig::$jDefLang; } }PK!J]/system/nrframework/fields/nreshopcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNREShopCategories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = true; /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.id as value, b.category_name as text, a.category_parent_id as parent, IF (a.published=1, 0, 1) as disable') ->from('#__eshop_categories as a') ->join('LEFT', '#__eshop_categorydetails AS b on a.id=b.category_id'); $db->setQuery($query); return $db->loadObjectList(); } } PK!!<system/nrframework/fields/nrjbusinessdirectorycategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRJBusinessDirectoryCategories extends JFormFieldNRTreeSelect { /** * Get a list of all J-BusinessDirectory Categories * * @return void */ protected function getOptions() { $filter_type = isset($this->element['filter_type']) ? (string) $this->element['filter_type'] : 1; // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.id as value, a.name as text, a.level AS level, a.parent_id as parent, IF (a.published=1, 0, 1) as disable') ->from('#__jbusinessdirectory_categories as a') ->join('LEFT', '#__jbusinessdirectory_categories AS b on a.lft > b.lft AND a.rgt < b.rgt') ->where($db->quoteName('a.type') . ' = ' . $db->q($filter_type)) ->group('a.id, a.name, a.lft') ->order('a.lft ASC'); $db->setQuery($query); return $db->loadObjectList(); } } PK!\[ (system/nrframework/fields/acymailing.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use NRFramework\Extension; JFormHelper::loadFieldClass('groupedlist'); class JFormFieldAcymailing extends JFormFieldGroupedList { /** * Method to get the field option groups. * * @return array The field option objects as a nested array in groups. * * @since 1.6 */ protected function getGroups() { $groups = []; $lists = []; if ($acymailing_5_is_installed = Extension::isInstalled('com_acymailing')) { $lists['5'] = $this->getAcym5Lists(); } if ($acymailing_6_is_installed = Extension::isInstalled('com_acym')) { $lists['6'] = $this->getAcym6Lists(); } foreach ($lists as $group_key => $group) { if (!is_array($group)) { continue; } foreach ($group as $list) { $groups['AcyMailing ' . $group_key][] = JHtml::_('select.option', $list->id, $list->name); } } return $groups; } /** * Get AcyMailing 6 lists * * @return mixed Array on success, null on failure */ private function getAcym6Lists() { if (!@include_once(JPATH_ADMINISTRATOR . '/components/com_acym/helpers/helper.php')) { return; } $lists = acym_get('class.list')->getAll(); if (!is_array($lists)) { return; } // Add 6: prefix to each list id. foreach ($lists as $key => &$list) { $list->id = '6:' . $list->id; } return $lists; } /** * Get AcyMailing 5 lists * * @return mixed Array on success, null on failure */ private function getAcym5Lists() { if (!@include_once(JPATH_ADMINISTRATOR . '/components/com_acymailing/helpers/helper.php')) { return; } $lists = acymailing_get('class.list')->getLists(); if (!is_array($lists)) { return; } // The getGroups method expects the id property foreach ($lists as $key => $list) { $list->id = $list->listid; } return $lists; } }PK!4system/nrframework/fields/nrvirtuemartcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRVirtueMartCategories extends JFormFieldNRTreeSelect { /** * Indicates whether the options array should be sorted before render. * * @var boolean */ protected $sortTree = true; /** * Indicates whether the options array should have the levels re-calculated * * @var boolean */ protected $fixLevels = true; /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.virtuemart_category_id as value, b.category_name as text, c.category_parent_id as parent, IF (a.published=1, 0, 1) as disable') ->from('#__virtuemart_categories as a') ->join('LEFT', '#__virtuemart_categories_' . $this->getLanguage() . ' AS b on a.virtuemart_category_id = b.virtuemart_category_id') ->join('LEFT', '#__virtuemart_category_categories AS c on a.virtuemart_category_id = c.id') ->order('c.id desc'); $db->setQuery($query); return $db->loadObjectList(); } /** * VirtueMart is using different tables per language. Therefore, we need to use their API to get the default language code * * @return string */ private function getLanguage($default = 'en_gb') { // Silent inclusion. @include_once JPATH_ADMINISTRATOR . '/components/com_virtuemart/helpers/config.php'; if (!class_exists('VmConfig')) { return $default; } // Init configuration VmConfig::loadConfig(); return VmConfig::$jDefLang; } } PK!#system/nrframework/fields/nrurl.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNRURL extends NRFormField { /** * Method to render the input field * * @return string */ function getInput() { $url = $this->get("url", "#"); $target = $this->get("target", "_blank"); $text = $this->get("text"); $class = $this->get("class"); $icon = $this->get("icon", null); $url = str_replace("{{base}}", JURI::base(), $url); $url = str_replace("{{root}}", JURI::root(), $url); $html[] = ''; if ($icon) { $html[] = ''; } $html[] = $this->prepareText($text); $html[] = ''; // Add CSS to the page $run = false; if (!$run) { JFactory::getDocument()->addStyleDeclaration(' .nrurl.disabled { pointer-events: none; } '); $run = true; } return implode(" ", $html); } }PK!DYU``$system/nrframework/fields/inline.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNR_Inline extends NRFormField { /** * Method to render the input field * * @return string */ protected function getInput() { JHtml::stylesheet('plg_system_nrframework/inline-control-group.css', ['relative' => true, 'version' => 'auto']); $start = $this->get('start', 1); $end = $this->get('end', 0); if ($start && !$end) { return '
'; } return '
'; } }PK! *system/nrframework/fields/smarttagsbox.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); use NRFramework\SmartTags; class JFormFieldSmartTagsBox extends JFormField { /** * Undocumented variable * * @var string */ public $input_selector = '.show-smart-tags'; /** * Disable field label * * @return boolean */ protected function getLabel() { return false; } /** * Method to get a list of options for a list input. * * @return array An array of JHtml options. */ protected function getInput() { JHtml::_('script', 'plg_system_nrframework/smarttagsbox.js', ['version' => 'auto', 'relative' => true]); JHtml::_('stylesheet', 'plg_system_nrframework/smarttagsbox.css', ['version' => 'auto', 'relative' => true]); JText::script('NR_SMARTTAGS_NOTFOUND'); JText::script('NR_SMARTTAGS_SHOW'); JFactory::getDocument()->addScriptOptions('SmartTagsBox', [ 'selector' => $this->input_selector, 'tags' => [ 'Joomla' => [ '{page.title}' => 'Page Title', '{url}' => 'Page URL', '{url.path}' => 'Page Path', '{page.lang}' => 'Page Language Code', '{page.langurl}' => 'Page Language URL', '{page.desc}' => 'Page Meta Description', '{site.name}' => 'Site Name', '{site.url}' => 'Site URL', '{site.email}' => 'Site Email', '{user.id}' => 'User ID', '{user.username}' => 'User Username', '{user.email}' => 'User Email', '{user.name}' => 'User Full name', '{user.firstname}' => 'User First name', '{user.lastname}' => 'User Last name', '{user.groups}' => 'User Group IDs', '{user.registerdate}' => 'User Registration Date', ], 'Visitor' => [ '{client.device}' => 'Visitor Device Type', '{ip}' => 'Visitor IP Address', '{client.browser}' => 'Visitor Browser', '{client.os}' => 'Visitor Operating System', '{client.useragent}' => 'Visitor User Agent String' ], 'Other' => [ '{date}' => 'Date', '{time}' => 'Time', '{day}' => 'Day', '{month}' => 'Month', '{year}' => 'Year', '{referrer}' => 'Referrer URL', '{randomid}' => 'Random ID', '{querystring.YOUR_KEY}' => 'Query String', '{language.YOUR_KEY}' => 'Language String' ] ] ]); // Render box layout $layout = new JLayoutFile('smarttagsbox', JPATH_PLUGINS . '/system/nrframework/layouts'); return $layout->render(); } }PK!8*system/nrframework/fields/nrconditions.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); use NRFramework\Extension; JFormHelper::loadFieldClass('groupedlist'); class JFormFieldNRConditions extends JFormFieldGroupedList { /** * List of available conditions * * @var array */ public static $conditions = [ 'NR_DATETIME' => [ 'Date\Date' => 'NR_DATE', 'Date\Day' => 'NR_WEEKDAY', 'Date\Month' => 'NR_MONTH', 'Date\Time' => 'NR_TIME' ], 'Joomla' => [ 'com_content#Component\ContentArticle' => 'NR_CONTENT_ARTICLE', 'com_content#Component\ContentCategory' => 'NR_CONTENT_CATEGORY', 'com_content#Component\ContentView' => 'NR_CONTENT_VIEW', 'Joomla\UserID' => 'NR_ASSIGN_USER_ID', 'Joomla\UserGroup' => 'NR_USERGROUP', 'Joomla\AccessLevel' => 'NR_USERACCESSLEVEL', 'Joomla\Menu' => 'NR_MENU', 'Joomla\Component' => 'NR_ASSIGN_COMPONENTS', 'Joomla\Language' => 'NR_ASSIGN_LANGS' ], 'NR_TECHNOLOGY' => [ 'Device' => 'NR_ASSIGN_DEVICES', 'Browser' => 'NR_ASSIGN_BROWSERS', 'OS' => 'NR_ASSIGN_OS' ], 'NR_GEOLOCATION' => [ 'Geo\City' => 'NR_CITY', 'Geo\Country' => 'NR_ASSIGN_COUNTRIES', 'Geo\Region' => 'NR_REGION', 'Geo\Continent' => 'NR_CONTINENT' ], 'NR_INTEGRATIONS' => [ 'com_rstbox#EngageBox'=> 'NR_VIEWED_ANOTHER_BOX', 'com_convertforms#ConvertForms'=> 'NR_CONVERT_FORMS_CAMPAIGN', 'com_k2#Component\K2Item' => 'NR_K2_ITEM', 'com_k2#Component\K2Category' => 'NR_K2_CATEGORY', 'com_k2#Component\K2Tag' => 'NR_K2_TAG', 'com_k2#Component\K2Pagetype' => 'NR_K2_PAGE_TYPE', 'com_acymailing#AcyMailing|com_acym#AcyMailing' => 'NR_ACYMAILING_LIST', 'com_akeebasubs#AkeebaSubs' => 'NR_AKEEBASUBS_LEVEL' ], 'NR_ADVANCED' => [ 'URL' => 'NR_URL', 'Referrer' => 'NR_ASSIGN_REFERRER', 'IP' => 'NR_IPADDRESS', 'Pageviews' => 'NR_ASSIGN_PAGEVIEWS_VIEWS', 'Cookie' => 'NR_COOKIE', 'PHP' => 'NR_ASSIGN_PHP', 'TimeOnSite' => 'NR_ASSIGN_TIMEONSITE' ] ]; /** * Method to get the field option groups. * * @return array The field option objects as a nested array in groups. */ protected function getGroups() { $include_rules = empty($this->element['include_rules']) ? [] : explode(',', $this->element['include_rules']); $exclude_rules = empty($this->element['exclude_rules']) ? [] : explode(',', $this->element['exclude_rules']); $groups[''][] = JHtml::_('select.option', null, JText::_('NR_CB_SELECT_CONDITION')); foreach (self::$conditions as $conditionGroup => $conditions) { foreach ($conditions as $conditionName => $condition) { $skip_condition = false; /** * Checks conditions that have multiple components as dependency. * Check for multiple given components for a particular condition, i.e. acymailing can be loaded via com_acymailing or com_acym */ $multiple_components = explode('|', $conditionName); if (count($multiple_components) >= 2) { foreach ($multiple_components as $component) { $skip_condition = false; if (!$conditionName = $this->getConditionName($component)) { $skip_condition = true; continue; } } } // If the condition must be skipped, skip it if ($skip_condition) { continue; } // Checks for a single condition whether its component exists and can be used. if (!$conditionName = $this->getConditionName($conditionName)) { continue; } // If its excluded, skip it if (!empty($exclude_rules) && in_array($conditionName, $exclude_rules)) { continue; } // If its not included, skip it if (!empty($include_rules) && !in_array($conditionName, $include_rules)) { continue; } // Add condition to the group $groups[JText::_($conditionGroup)][] = JHtml::_('select.option', $conditionName, JText::_($condition), 'value', 'text'); } } // Merge any additional groups in the XML definition. return array_merge(parent::getGroups(), $groups); } /** * Returns the parsed condition name. * * i.e. $condition: com_k2#Component\K2Item * will return: Component\K2Item * * @param string $condition * * @return mixed */ private function getConditionName($condition) { $conditionNameParts = explode('#', $condition); if (count($conditionNameParts) >= 2 && !Extension::isEnabled($conditionNameParts[0])) { return false; } return isset($conditionNameParts[1]) ? $conditionNameParts[1] : $conditionNameParts[0]; } }PK!='system/nrframework/fields/nrbrowser.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once JPATH_PLUGINS . '/system/nrframework/helpers/fieldlist.php'; class JFormFieldNRBrowser extends NRFormFieldList { /** * Browsers List * * @var array */ public $options = array( 'chrome' => 'NR_CHROME', 'firefox' => 'NR_FIREFOX', 'edge' => 'NR_EDGE', 'ie' => 'NR_IE', 'safari' => 'NR_SAFARI', 'opera' => 'NR_OPERA' ); protected function getOptions() { asort($this->options); foreach ($this->options as $key => $option) { $options[] = JHTML::_('select.option', $key, JText::_($option)); } return array_merge(parent::getOptions(), $options); } }PK! $system/nrframework/fields/nrtext.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; JFormHelper::loadFieldClass('text'); class JFormFieldNRText extends JFormFieldText { /** * Method to render the input field * * @return string */ public function getInput() { // This line added to help us support the K2 Items and Joomla! Articles dropdown listbox array values $this->value = is_array($this->value) ? implode(',', $this->value) : $this->value; // Adds an extra info label next to input $addon = (string) $this->element['addon']; $parent = parent::getInput(); if (!empty($addon)) { $html[] = '
' . $parent . ' ' . JText::_($addon) . '
'; } else { $html[] = parent::getInput(); } // Adds a link next to input $url = $this->element['url']; $text = $this->element['urltext']; $target = $this->element['urltarget'] ? $this->element['urltarget'] : "_blank"; $class = $this->element['urlclass'] ? $this->element['urlclass'] : ""; $attributes = ""; // Popup mode if ($this->element["urlpopup"]) { $class .= " nrPopup"; $attributes = 'data-width="600" data-height="600"'; $this->addPopupScript(); } if ($url && $text) { $html[] = '' . JText::_($text) . ''; } return implode('', $html); } private function addPopupScript() { static $run; if ($run) { return; } $run = true; JFactory::getDocument()->addScriptDeclaration(' jQuery(function($) { $(".nrPopup").click(function() { url = $(this).attr("href"); width = $(this).data("width"); height = $(this).data("height"); window.open(""+url+"", "nrPopup", "width=" + width + ", height=" + height + ""); return false; }) }) '); } }PK!]<2system/nrframework/fields/nreasyblogcategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNREasyBlogCategories extends JFormFieldNRTreeSelect { /** * Get a list of all EventBooking Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.id as value, a.title as text, COUNT(DISTINCT b.id) AS level, a.parent_id as parent, IF (a.published=1, 0, 1) as disable') ->from('#__easyblog_category as a') ->join('LEFT', '#__easyblog_category AS b on a.lft > b.lft AND a.rgt < b.rgt') ->group('a.id, a.title, a.lft') ->order('a.lft ASC'); $db->setQuery($query); return $db->loadObjectList(); } } PK!jȻ]%system/nrframework/fields/content.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once dirname(__DIR__) . '/helpers/groupfield.php'; class JFormFieldNR_Content extends NRFormGroupField { public $type = 'Content'; public function getCategories() { $query = $this->db->getQuery(true) ->select('COUNT(c.id)') ->from('#__categories AS c') ->where('c.extension = ' . $this->db->quote('com_content')) ->where('c.parent_id > 0') ->where('c.published > -1'); $this->db->setQuery($query); $total = $this->db->loadResult(); $options = array(); if ($this->get('show_ignore')) { if (in_array('-1', $this->value)) { $this->value = array('-1'); } $options[] = JHtml::_('select.option', '-1', '- ' . JText::_('NR_IGNORE') . ' -', 'value', 'text', 0); $options[] = JHtml::_('select.option', '-', ' ', 'value', 'text', 1); } $query->clear('select') ->select('c.id, c.title as name, c.level, c.published, c.language') ->order('c.lft'); $this->db->setQuery($query); $list = $this->db->loadObjectList(); $options = array_merge($options, $this->getOptionsByList($list, array('language'), -1)); return $options; } public function getItems() { $query = $this->db->getQuery(true) ->select('COUNT(i.id)') ->from('#__content AS i') ->where('i.access > -1'); $this->db->setQuery($query); $total = $this->db->loadResult(); $query->clear('select') ->select('i.id, i.title as name, i.language, c.title as cat, i.access as published') ->join('LEFT', '#__categories AS c ON c.id = i.catid') ->order('i.title, i.ordering, i.id'); $this->db->setQuery($query); $list = $this->db->loadObjectList(); return $this->getOptionsByList($list, array('language', 'cat', 'id')); } } PK!;r, , .system/nrframework/fields/nrimagesselector.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); JFormHelper::loadFieldClass('text'); class JFormFieldNRImagesSelector extends JFormFieldText { /** * Renders the Images Selector * * @return string The field input markup. */ protected function getInput() { $field_attributes = (array) $this->element->attributes(); $attributes = isset($field_attributes["@attributes"]) ? $field_attributes["@attributes"] : null; $field_attributes = new JRegistry($attributes); $columns = $field_attributes->get('columns', 6); $width = $field_attributes->get('width', '100%'); $height = $field_attributes->get('height', ''); if (!$images = $field_attributes->get('images', '')) { return; } $paths = explode(',', $images); $images = []; foreach ($paths as $key => $path) { // skip empty paths if (empty(rtrim(ltrim($path, ' '), ' '))) { continue; } if ($imgs = $this->getImagesFromPath($path)) { // add new images to array of images $images = array_merge($images, $imgs); } else { // check if image exist if (file_exists(JPATH_ROOT . '/' . ltrim($path, ' /'))) { // add new image to array of images $images[] = ltrim($path, ' /'); } } } // load CSS JHtml::stylesheet('plg_system_nrframework/images-selector-field.css', ['relative' => true, 'version' => true]); $layout = new \JLayoutFile('imagesselector', JPATH_PLUGINS . '/system/nrframework/layouts'); $data = [ 'value' => !empty($this->value) ? $this->value : $this->default, 'name' => $this->name, 'images' => $images, 'columns' => $columns, 'width' => $width, 'height' => $height ]; return $layout->render($data); } /** * Returns all images in path * * @return mixed */ private function getImagesFromPath($path) { $folder = JPATH_ROOT . '/' . ltrim($path, ' /'); if (!is_dir($folder) || !$folder_files = scandir($folder)) { return false; } $images = array_diff($folder_files, array('.', '..', '.DS_Store')); $images = array_values($images); // prepend path to image file names array_walk($images, function(&$value, $key) use ($path) { $value = ltrim($path, ' /') . '/' . $value; } ); return $images; } } PK!,BCC2system/nrframework/fields/nrdjeventscategories.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/treeselect.php'; class JFormFieldNRDJEventsCategories extends JFormFieldNRTreeSelect { /** * Get a list of all DJ Events Categories * * @return void */ protected function getOptions() { // Get a database object. $db = $this->db; $query = $db->getQuery(true) ->select('a.id as value, a.name as text, 0 AS level, 0 as parent, 0 as disable') ->from('#__djev_cats as a') ->group('a.id, a.name') ->order('a.id ASC'); $db->setQuery($query); return $db->loadObjectList(); } } PK!YY*system/nrframework/fields/nrcomponents.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); class JFormFieldNRComponents extends JFormFieldList { protected function getOptions() { return array_merge(parent::getOptions(), $this->getInstalledComponents()); } /** * Method to get field parameters * * @param string $val Field parameter * @param string $default The default value * * @return string */ public function get($val, $default = '') { return (isset($this->element[$val]) && (string) $this->element[$val] != '') ? (string) $this->element[$val] : $default; } /** * Creates a list of installed components * * @return array */ protected function getInstalledComponents() { $lang = JFactory::getLanguage(); $db = JFactory::getDbo(); $components = $db->setQuery( $db->getQuery(true) ->select('name, element') ->from('#__extensions') ->where('type = ' . $db->quote('component')) ->where('name != ""') ->where('element != ""') ->where('enabled = 1') ->order('element, name') )->loadObjectList(); $comps = array(); foreach ($components as $component) { // Make sure we have a valid element if (empty($component->element)) { continue; } // Skip backend-based only components if ($this->get('frontend', false)) { $component_folder = JPATH_SITE . '/components/' . $component->element; if (!\JFolder::exists($component_folder)) { continue; } if (!\JFolder::exists($component_folder . '/views') && !\JFolder::exists($component_folder . '/View') && !\JFolder::exists($component_folder . '/view')) { continue; } } // Try loading component's system language file in order to display a user friendly component name // Runs only if the component's name is not translated already. if (strpos($component->name, ' ') === false) { $filenames = [ $component->element . '.sys', $component->element ]; $paths = [ JPATH_ADMINISTRATOR, JPATH_ADMINISTRATOR . '/components/' . $component->element, JPATH_SITE, JPATH_SITE . '/components/' . $component->element ]; foreach ($filenames as $key => $filename) { foreach ($paths as $key => $path) { $loaded = $lang->load($filename, $path, null) || $lang->load($filename, $path, $lang->getDefault()); if ($loaded) { break 2; } } } // Translate component's name $component->name = JText::_(strtoupper($component->name)); } $comps[strtolower($component->element)] = $component->name; } asort($comps); $options = array(); foreach ($comps as $key => $name) { $options[] = JHtml::_('select.option', $key, $name); } return $options; } }PK!a#system/nrframework/fields/block.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once dirname(__DIR__) . '/helpers/field.php'; ###### Note ###### # This field is deprecated. Use NR_Well instead ###### Note ###### class JFormFieldNR_Block extends NRFormField { /** * The field type. * * @var string */ public $type = 'nr_block'; protected function getLabel() { return ''; } /** * Method to render the input field * * @return string */ protected function getInput() { JHtml::stylesheet('plg_system_nrframework/fields.css', false, true); $title = $this->get('label'); $description = $this->get('description'); $class = $this->get('class'); $showclose = $this->get('showclose', 0); $start = $this->get('start', 0); $end = $this->get('end', 0); $info = $this->get("html", null); if ($info) { $info = str_replace("{{", "<", $info); $info = str_replace("}}", ">", $info); } $html = array(); if ($start || !$end) { $html[] = ''; if (strpos($class, 'alert') !== false) { $html[] = '
'; } else { $html[] = '
'; } if ($title) { $html[] = '

' . $this->prepareText($title) . '

'; } if ($description) { $html[] = '
' . $this->prepareText($description) . $info . '
'; } $html[] = '
'; } if (!$start && !$end) { $html[] = '
'; } return '
' . implode('', $html); } }PK!K"K[A A .system/nrframework/fields/conditionbuilder.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use NRFramework\Conditions\ConditionBuilder; use NRFramework\Extension; JFormHelper::loadFieldClass('hidden'); class JFormFieldConditionBuilder extends JFormFieldHidden { /** * Method to render the input field * * @return string */ protected function getInput() { // Condition Builder relies on com_ajax for AJAX requests. if (!Extension::componentIsEnabled('ajax')) { \JFactory::getApplication()->enqueueMessage(\JText::_('AJAX Component is not enabled.'), 'error'); return; } // This is required on views we don't control such as the Fields or the Modules view page. JHtml::_('formbehavior.chosen', '.hasChosen'); JHtml::stylesheet('plg_system_nrframework/fields.css', ['relative' => true, 'version' => 'auto']); JHtml::stylesheet('plg_system_nrframework/joomla' . (defined('nrJ4') ? '4' : '3') . '.css', ['relative' => true, 'version' => 'auto']); \JText::script('NR_CB_SELECT_CONDITION_GET_STARTED'); \JText::script('NR_ARE_YOU_SURE_YOU_WANT_TO_DELETE_THIS_ITEM'); // Value must be always be a JSON string. if (is_array($this->value)) { $this->value = json_encode($this->value); } // If field is empty, initialize it with an empty Condition Group $payload = [ 'include_rules' => isset($this->getOptions()['include_rules']) ? ConditionBuilder::prepareXmlRulesList($this->getOptions()['include_rules']) : '', 'exclude_rules' => isset($this->getOptions()['exclude_rules']) ? ConditionBuilder::prepareXmlRulesList($this->getOptions()['exclude_rules']) : '', 'geo_modal' => ConditionBuilder::getGeoModal() // Out of context ]; return '
' . parent::getInput() . ConditionBuilder::getLayout('conditionbuilder', $payload) . '
'; } /** * Returns the field options. * * @return array */ protected function getOptions() { $options = [ 'include_rules' => (string) $this->element['include_rules'], 'exclude_rules' => (string) $this->element['exclude_rules'] ]; return $options; } }PK!n/system/nrframework/fields/nrmodulepositions.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2019 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; require_once JPATH_PLUGINS . '/system/nrframework/helpers/fieldlist.php'; class JFormFieldNRModulePositions extends NRFormFieldList { /** * Method to get a list of options for a list input. * * @return array An array of JHtml options. */ protected function getOptions() { // get templates $templates = $this->getTemplates(); require_once JPATH_ADMINISTRATOR . '/components/com_templates/helpers/templates.php'; // get all position options $options = []; $options[] = JHTML::_('select.option', '', \JText::_('NR_NONE_SELECTED')); foreach ($templates as $template) { $options[] = JHTML::_('select.option', '', $template->name); // find all positions for template $positions = TemplatesHelper::getPositions(0, $template->element); foreach ($positions as $position) { $options[] = JHTML::_('select.option', $position, $position); } $options[] = JHTML::_('select.option', ''); } return array_merge(parent::getOptions(), $options); } /** * Returns all enabled templates * * @return object */ private function getTemplates() { $db = $this->db; $query = $db->getQuery(true); $query->select('element, name, enabled'); $query->from('#__extensions'); $query->where('client_id = 0'); $query->where('type = '.$db->quote('template')); $query->where('enabled = 1'); $db->setQuery($query); return $db->loadObjectList(); } }PK!~_rr,system/nrframework/fields/componentitems.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use Joomla\Registry\Registry; require_once __DIR__ . '/ajaxify.php'; /* * Creates an AJAX-based dropdown * https://select2.org/ */ class JFormFieldComponentItems extends JFormFieldAjaxify { /** * Single items table name * * @var string */ protected $table = 'content'; /** * Primary key column of the single items table * * @var string */ protected $column_id = 'id'; /** * The title column of the single items table * * @var string */ protected $column_title = 'title'; /** * The state column of the single items table * * @var string */ protected $column_state = 'state'; /** * Pass extra where SQL statement * * @var string */ protected $where; /** * The Joomla database object * * @var object */ protected $db; /** * Method to attach a JForm object to the field. * * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @since 3.2 */ public function setup(SimpleXMLElement $element, $value, $group = null) { if ($return = parent::setup($element, $value, $group)) { $this->init(); } return $return; } public function init() { $this->table = isset($this->element['table']) ? (string) $this->element['table'] : $this->table; $this->column_id = isset($this->element['column_id']) ? (string) $this->element['column_id'] : $this->column_id; $this->column_id = $this->prefix($this->column_id); $this->column_title = isset($this->element['column_title']) ? (string) $this->element['column_title'] : $this->column_title; $this->column_title = $this->prefix($this->column_title); $this->column_state = isset($this->element['column_state']) ? (string) $this->element['column_state'] : $this->column_state; $this->column_state = $this->prefix($this->column_state); $this->where = isset($this->element['where']) ? (string) $this->element['where'] : null; $this->join = isset($this->element['join']) ? (string) $this->element['join'] : null; if (!isset($this->element['placeholder'])) { $this->placeholder = (string) $this->element['description']; } // Initialize database Object $this->db = JFactory::getDbo(); } private function prefix($string) { if (strpos($string, '.') === false) { $string = 'i.' . $string; } return $string; } protected function getTemplateResult() { return '\' + state.text + \'\' + state.id + \''; } protected function getItemsQuery() { $db = $this->db; $query = $this->getQuery() ->order($db->quoteName($this->column_id) . ' DESC'); if ($this->limit > 0) { // Joomla uses offset $page = $this->page - 1; $query->setLimit($this->limit, $page * $this->limit); } return $query; } protected function getItems() { $db = $this->db; $db->setQuery($this->getItemsQuery()); return $db->loadObjectList(); } protected function getItemsTotal() { $db = $this->db; $query = $this->getQuery() ->clear('select') ->select('count(*)'); $db->setQuery($query); return (int) $db->loadResult(); } protected function getQuery() { $db = $this->db; $query = $db->getQuery(true) ->select([ $db->quoteName($this->column_id, 'id'), $db->quoteName($this->column_title, 'text'), $db->quoteName($this->column_state, 'state') ]) ->from($db->quoteName('#__' . $this->table, 'i')); if (!empty($this->search_term)) { $query->where($db->quoteName($this->column_title) . ' LIKE ' . $db->quote('%' . $this->search_term . '%')); } if ($this->join) { $query->join('INNER', $this->join); } if ($this->where) { $query->where($this->where); } return $query; } protected function validateOptions($options) { $db = $this->db; $query = $this->getQuery() ->where($db->quoteName($this->column_id) . ' IN (' . implode(',', $options) . ')'); $db->setQuery($query); return $db->loadAssocList('id', 'text'); } }PK!+& )system/nrframework/fields/nrmenuitems.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; use \NRFramework\HTML; require_once dirname(__DIR__) . '/helpers/field.php'; class JFormFieldNRMenuItems extends NRFormField { /** * Output the HTML for the field * Example of usage: */ protected function getInput() { $size = $this->get('size', 300); $options = $this->getMenuItems(); return HTML::treeselect($options, $this->name, $this->value, $this->id, $size); } /** * Get a list of menu links for one or all menus. * Logic from administrator\components\com_menus\helpers\menus.php@getMenuLinks() */ public function getMenuItems() { NRFramework\Functions::loadLanguage('com_menus', JPATH_ADMINISTRATOR); $db = $this->db; // Prevent the "The SELECT would examine more than MAX_JOIN_SIZE rows; " MySQL error // on websites with a big number of menu items in the db. $db->setQuery('SET SQL_BIG_SELECTS = 1')->execute(); $query = $db->getQuery(true) ->select('a.id AS value, a.title AS text, a.alias, a.level, a.menutype, a.type, a.template_style_id, a.checked_out, a.language') ->from('#__menu AS a') ->join('LEFT', $db->quoteName('#__menu') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt') ->where('a.published != -2') ->group('a.id, a.alias, a.title, a.level, a.menutype, a.type, a.template_style_id, a.checked_out, a.lft, a.language') ->order('a.lft ASC'); // Get the options. $db->setQuery($query); try { $links = $db->loadObjectList(); } catch (RuntimeException $e) { JFactory::getApplication()->enqueueMessage($e->getMessage()); return false; } // Group the items by menutype. $query->clear() ->select('*') ->from('#__menu_types') ->where('menutype <> ' . $db->quote('')) ->order('title, menutype'); $db->setQuery($query); try { $menuTypes = $db->loadObjectList(); } catch (RuntimeException $e) { JFactory::getApplication()->enqueueMessage($e->getMessage()); return false; } // Create a reverse lookup and aggregate the links. $rlu = array(); foreach ($menuTypes as &$type) { $type->value = 'type.' . $type->menutype; $type->text = $type->title; $type->level = 0; $type->class = 'hidechildren'; $type->labelclass = 'nav-header'; $rlu[$type->menutype] = &$type; $type->links = array(); } foreach ($links as &$link) { if (isset($rlu[$link->menutype])) { if (preg_replace('#[^a-z0-9]#', '', strtolower($link->text)) !== preg_replace('#[^a-z0-9]#', '', $link->alias)) { $link->text .= ' [' . $link->alias . ']'; } if ($link->language && $link->language != '*') { $link->text .= ' (' . $link->language . ')'; } if ($link->type == 'alias') { $link->text .= ' (' . JText::_('COM_MENUS_TYPE_ALIAS') . ')'; $link->disable = 1; } $rlu[$link->menutype]->links[] = &$link; unset($link->menutype); } } return $menuTypes; } } PK!2Dss!system/nrframework/fields/pro.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; class JFormFieldNR_PRO extends JFormField { /** * Method to render the input field * * @return string */ protected function getInput() { $label = (string) $this->element['label']; $isFeatureMode = !is_null($label) && !empty($label); $buttonText = $isFeatureMode ? 'NR_UNLOCK_PRO_FEATURE' : 'NR_UPGRADE_TO_PRO'; NRFramework\HTML::renderProOnlyModal(); $html = ''; if (defined('nrJ4')) { $html .= ' '; } else { if ($isFeatureMode) { $html .= ' '; } else { $html .= ' '; } } $html .= JText::_($buttonText) . ''; return $html; } }PK!\L+|9|9,system/nrframework/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgSystemNrframeworkInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!5system/nrframework/layouts/conditionbuilder_group.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); ?>
'); $field->setup($element, null); echo $field->__get('input'); ?>
$condition) { echo \NRFramework\Conditions\ConditionBuilder::add($name, $groupKey, $conditionKey, (array) $condition, $include_rules, $exclude_rules); } } ?>
PK!:??6system/nrframework/layouts/responsive_control_item.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); ?>
PK!>9771system/nrframework/layouts/outdated_extension.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (defined('nrJ4')) { // Include the Bootstrap component \JFactory::getApplication() ->getDocument() ->getWebAssetManager() ->useScript('bootstrap.alert'); } ?> PK!qž1system/nrframework/layouts/responsive_control.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (!is_array($fields) || empty($fields)) { return; } ?>
PK! #system/nrframework/layouts/well.phpnu[ ') { ?>
> PK!||-system/nrframework/layouts/imagesselector.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (empty($images)) { return; } $value = !empty($value) ? $value : $images[0]; $heightAtt = !empty($height) ? ' style="height:' . $height . ';"' : ''; ?>
> />
PK!)k,system/nrframework/layouts/updatechecker.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); ?> PK!p2+system/nrframework/layouts/smarttagsbox.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); ?>
PK!NO O 3system/nrframework/layouts/conditionbuilder_row.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); ?>
renderFieldset('base'); ?>
'); $field->setup($element, null); echo $field->__get('input'); ?>
' . JText::_('NR_CB_SELECT_CONDITION_GET_STARTED') . '
'; ?>
PK!U̱YY+system/nrframework/layouts/proonlymodal.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (defined('nrJ4')) { JFactory::getDocument()->addScriptDeclaration(' document.addEventListener("DOMContentLoaded", function() { var proOnlyEl = document.getElementById("proOnlyModal"); document.body.appendChild(proOnlyEl); var proOnlyModal = new bootstrap.Modal(proOnlyEl); document.addEventListener("click", function(e) { var proFeature = e.target.dataset.proOnly; if (proFeature === undefined) { return; } event.preventDefault(); if (proFeature) { proOnlyEl.querySelectorAll("em").forEach(function(el) { el.innerHTML = proFeature; }); proOnlyEl.querySelector(".po-upgrade").style.display = "none"; proOnlyEl.querySelector(".po-feature").style.display = "block"; } else { proOnlyEl.querySelector(".po-upgrade").style.display = "block"; proOnlyEl.querySelector(".po-feature").style.display = "none"; } proOnlyModal.show(); }); }); '); } else { JFactory::getDocument()->addScriptDeclaration(' jQuery(function($) { var $proOnlyModal = $("#proOnlyModal"); // Move to body so it can be accessible by all buttons $proOnlyModal.appendTo("body"); $(document).on("click", "*[data-pro-only]", function() { event.preventDefault(); var $el = $(this) feature_name = $el.data("pro-only"); if (feature_name) { $proOnlyModal.find("em").html(feature_name); $proOnlyModal.find(".po-upgrade").hide().end().find(".po-feature").show(); } else { $proOnlyModal.find(".po-feature").hide().end().find(".po-upgrade").show(); } $proOnlyModal.modal("show"); }); }); '); } JHtml::stylesheet('plg_system_nrframework/proonlymodal.css', ['relative' => true, 'version' => 'auto']); ?>

Pro

PK!e/system/nrframework/layouts/conditionbuilder.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); JHtml::stylesheet('plg_system_nrframework/conditionbuilder.css', ['relative' => true, 'version' => 'auto']); JHtml::script('plg_system_nrframework/helper.js', ['relative' => true, 'version' => 'auto']); JHtml::script('plg_system_nrframework/conditionbuilder.js', ['relative' => true, 'version' => 'auto']); extract($displayData); ?> PK! :&&=system/nrframework/layouts/widgets/gallerymanager/default.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Component\ComponentHelper; if (!$disabled) { if (strpos($css_class, 'ordering-default') !== false) { JHtml::script('https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js'); } // Required in the front-end for the media manager to work if (!defined('nrJ4')) { JHtml::_('behavior.modal'); // Front-end editing: The below script is required for front-end media library selection to work as its missing from parent window when called if (JFactory::getApplication()->isClient('site')) { ?> getDocument(); $doc->addScriptOptions('media-picker', [ 'images' => array_map( 'trim', explode( ',', ComponentHelper::getParams('com_media')->get( 'image_extensions', 'bmp,gif,jpg,jpeg,png' ) ) ) ]); $wam = $doc->getWebAssetManager(); $wam->useScript('webcomponent.media-select'); Text::script('JFIELD_MEDIA_LAZY_LABEL'); Text::script('JFIELD_MEDIA_ALT_LABEL'); Text::script('JFIELD_MEDIA_ALT_CHECK_LABEL'); Text::script('JFIELD_MEDIA_ALT_CHECK_DESC_LABEL'); Text::script('JFIELD_MEDIA_CLASS_LABEL'); Text::script('JFIELD_MEDIA_FIGURE_CLASS_LABEL'); Text::script('JFIELD_MEDIA_FIGURE_CAPTION_LABEL'); Text::script('JFIELD_MEDIA_LAZY_LABEL'); Text::script('JFIELD_MEDIA_SUMMARY_LABEL'); } } // Use admin gallery manager path if browsing via backend $gallery_manager_path = JFactory::getApplication()->isClient('administrator') ? 'administrator/' : ''; // Javascript files should always load as they are used to populate the Gallery Manager via Dropzone JHtml::script('plg_system_nrframework/dropzone.min.js', ['relative' => true, 'version' => 'auto']); JHtml::script('plg_system_nrframework/widgets/gallery/manager_init.js', ['relative' => true, 'version' => 'auto']); JHtml::script('plg_system_nrframework/widgets/gallery/manager.js', ['relative' => true, 'version' => 'auto']); if ($load_stylesheet) { JHtml::stylesheet('plg_system_nrframework/widgets/gallerymanager.css', ['relative' => true, 'version' => 'auto']); } ?> PK!u5system/nrframework/layouts/widgets/rating/default.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (!$readonly && !$disabled) { JHtml::script('plg_system_nrframework/widgets/rating.js', ['relative' => true, 'version' => 'auto']); } if ($load_stylesheet) { JHtml::stylesheet('plg_system_nrframework/widgets/rating.css', ['relative' => true, 'version' => 'auto']); } if ($load_css_vars) { JFactory::getDocument()->addStyleDeclaration(' .nrf-rating-wrapper.' . $id . ' { --rating-selected-color: ' . $selected_color . '; --rating-unselected-color: ' . $unselected_color . '; --rating-size: ' . $size . 'px; } '); } echo $this->sublayout($half_ratings ? 'half' : 'full', $displayData);PK!- * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); $css_class .= ' ' . $size; ?>
checked disabled />
PK! :system/nrframework/layouts/widgets/rating/default/full.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); ?>
checked disabled />
PK!fBV V 8system/nrframework/layouts/widgets/signature/default.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); \JHtml::script('https://cdn.jsdelivr.net/npm/signature_pad@4.0.1/dist/signature_pad.umd.min.js'); \JHtml::script('plg_system_nrframework/widgets/signature.js', ['relative' => true, 'version' => 'auto']); if ($load_stylesheet) { \JHtml::stylesheet('plg_system_nrframework/widgets/signature.css', ['relative' => true, 'version' => 'auto']); } if ($load_css_vars) { JFactory::getDocument()->addStyleDeclaration(' .nrf-widget.signature.' . $id . ' { --width: ' . $width . '; --height: ' . $height . '; --input-border-width: ' . $border_width . '; --input-border-color: ' . $border_color . '; --input-border-radius: ' . $border_radius . '; --input-background-color: ' . $background_color . '; --line-color: ' . (is_null($line_color) ? $border_color : $line_color) . '; } '); } ?>
PK!b >:system/nrframework/layouts/widgets/colorpicker/default.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (!$readonly && !$disabled) { \JHtml::script('plg_system_nrframework/widgets/colorpicker.js', ['relative' => true, 'version' => 'auto']); } if ($load_stylesheet) { \JHtml::stylesheet('plg_system_nrframework/widgets/colorpicker.css', ['relative' => true, 'version' => 'auto']); } if ($load_css_vars) { JFactory::getDocument()->addStyleDeclaration(' .nrf-colorpicker-wrapper.' . $id . ' { --input-background-color: ' . $input_bg_color . '; --input-border-color: ' . $input_border_color . '; --input-border-color-focus: ' . $input_border_color_focus . '; --input-text-color: ' . $input_text_color . '; } '); } ?>
disabled /> required readonly />
PK!~u u <system/nrframework/layouts/widgets/openstreetmap/default.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; extract($displayData); $options = isset($options) ? $options : $displayData; if ($load_css_vars) { JFactory::getDocument()->addStyleDeclaration(' .nrf-widget.osm.' . $id . ' { --width: ' . $options['width'] . '; --height: ' . $options['height'] . '; } '); } ?>
/>
/>
PK! * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if ($countdown_type === 'static' && (empty($value) || $value === '0000-00-00 00:00:00')) { return; } if ($load_stylesheet) { if ($theme !== 'custom') { \JHtml::stylesheet('plg_system_nrframework/widgets/countdown.css', ['relative' => true, 'version' => 'auto']); } else { \JHtml::stylesheet('plg_system_nrframework/widgets/widget.css', ['relative' => true, 'version' => 'auto']); } } if ($load_css_vars && !empty($css_vars)) { JFactory::getDocument()->addStyleDeclaration($css_vars); } \JHtml::script('plg_system_nrframework/widgets/countdown.js', ['relative' => true, 'version' => 'auto']); ?>
>
PK!d{\:system/nrframework/layouts/widgets/rangeslider/default.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (!$readonly && !$disabled) { JHtml::script('plg_system_nrframework/widgets/slider.js', ['relative' => true, 'version' => 'auto']); } if ($load_stylesheet) { JHtml::stylesheet('plg_system_nrframework/widgets/slider.css', ['relative' => true, 'version' => 'auto']); } if ($load_css_vars) { JFactory::getDocument()->addStyleDeclaration(' .nrf-slider-wrapper.' . $id . ' { --base-color: ' . $base_color . '; --progress-color: ' . $color . '; --input-bg-color: ' . $input_bg_color . '; --input-border-color: ' . $input_border_color . '; --thumb-shadow-color: ' . $color . '26' . '; } '); } ?>
data-base-color="" data-progress-color="" style="background: linear-gradient(to right, 0%, %, %, 100%)" disabled /> readonly />
PK!ǤCC6system/nrframework/layouts/widgets/gallery/default.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (!$items || !is_array($items) || !count($items)) { return; } if (!$readonly && !$disabled && $lightbox) { JHtml::script('plg_system_nrframework/widgets/gallery/gallery.js', ['relative' => true, 'version' => 'auto']); } if ($load_stylesheet) { JHtml::stylesheet('plg_system_nrframework/widgets/gallery.css', ['relative' => true, 'version' => 'auto']); } ?> PK! gM{{@system/nrframework/layouts/widgets/gallery/default/glightbox.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); if (!$readonly && !$disabled) { JHtml::stylesheet('https://cdn.jsdelivr.net/npm/glightbox@3.1.0/dist/css/glightbox.min.css'); JHtml::script('https://cdn.jsdelivr.net/gh/mcstudios/glightbox@3.1.0/dist/js/glightbox.min.js'); } ?>PK!;system/nrframework/layouts/widgets/gallery/default/item.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); extract($displayData); use NRFramework\Helpers\Widgets\Gallery as GalleryHelper; ?>
alt="" />
PK!%?)system/nrframework/helpers/urls/bitly.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; class nrURLShortBitly extends NRURLShortener { function baseURL() { return 'http://api.bit.ly/v3/shorten?login='.$this->service->login.'&apiKey='.$this->service->api.'&format=txt&uri='.urlencode($this->url); } } PK!< -system/nrframework/helpers/urls/shortener.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; /** * Novarain Framework URL Shortening Class * Should be extended. The get() method is required. */ class NRURLShortener { /** * The Shortener Service * * @var object */ protected $service; /** * The URL to be shortened * * @var string */ protected $url; /** * Sets if the service needs a valid login name * * @var boolean */ protected $needsLogin = true; /** * Sets if the service needs a valid API Key * * @var boolean */ protected $needsKey = true; /** * Constructor of class * * @param object $service The Shortener service information * @param string $url The URL to be shortened */ public function __construct($service, $url) { $this->service = $service; $this->url = $url; } /** * Throws an exception * * @param string $msg * * @return void */ protected function throwError($msg) { throw new Exception(JText::sprintf('NR_URL_SHORTENING_FAILED', $this->url, $this->service->name, $msg)); } /** * Checks if credentials are set * * @return boolean Returns true if credentials are set */ protected function validateCredentials() { if ($this->needsKey && !isset($this->service->api)) { $this->throwError("API Key not set"); return false; } if ($this->needsLogin && !isset($this->service->login)) { $this->throwError("Login not set"); return false; } return true; } /** * Shortens the URL * * @return string On success returns the shortened URL */ public function get() { if (!$this->validateCredentials()) { return false; } $baseURL = $this->baseURL(); if (!$baseURL) { return false; } try { $response = JHttpFactory::getHttp()->get($baseURL, null, 5); if ($response === null || $response->code !== 200) { $this->throwError($response->body); return false; } } catch (RuntimeException $e) { $this->throwError($e->getMessage()); return false; } return trim($response->body); } } ?>PK!G (system/nrframework/helpers/urls/urls.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; use \NRFramework\Cache; class NRURLs { private $url; private $shortener; private $cache; function __construct($url = null) { if (isset($url)) { $this->set($url); } $this->setCache(true); } public function set($url) { $url = trim(filter_var($url, FILTER_SANITIZE_URL)); return ($this->url = $url); } public function setCache($state) { $this->cache = (bool) $state; } public function setShortener($service) { $this->shortener = $service; } public function get() { return $this->url; } public function validate($url_ = null) { $url = isset($url_) ? $url_ : $this->url; if (!$url) { return false; } // Remove all illegal characters from the URL $url = filter_var($url, FILTER_SANITIZE_URL); // Validate URL if (!filter_var($url, FILTER_VALIDATE_URL) === false) { return true; } return false; } public function getShort() { if (!$this->validate() || !isset($this->shortener)) { return false; } $hash = MD5($this->shortener->name . $this->url); $cache = Cache::read($hash, true); if ($cache) { return $cache; } // Load Shorten Service Class $file = __DIR__ . "/" . strtolower($this->shortener->name) . '.php'; $class = 'nrURLShort' . $this->shortener->name; $method = "get"; require_once(__DIR__ . "/shortener.php"); if (!class_exists($class) && JFile::exists($file)) { require_once($file); } if (!class_exists($class) || !method_exists($class, $method)) { return false; } $class_ = new $class($this->shortener, $this->url); $data = $class_->$method(); // Return the original URL if we don't have a valid short URL if (!$this->validate($data)) { return false; } Cache::set($hash, $data); // Store to cache if ($this->cache) { Cache::write($hash, $data); } return $data; } /** * Appends extra parameters to the end of the URL * * @param String $url Pass URL * @param String $params String of parameters (param=1¶m=2) * * @return string Returns new url */ public function appendParams($params) { if (!$params) { return $this; } $url = $this->url; $query = parse_url($url, PHP_URL_QUERY); $params = trim($params, "?"); $params = trim($params, "&"); if ($query) { $url .= '&' . $params; } else { $url .= '?' . $params; } $this->set($url); return $this; } } ?>PK! *system/nrframework/helpers/urls/google.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; class nrURLShortGoogle extends NRURLShortener { function get() { if (!$this->validateCredentials()) { return false; } $baseURL = "https://www.googleapis.com/urlshortener/v1/url?key=".$this->service->api; $data = '{ "longUrl": "'.$this->url.'" }'; $headers['Content-Type'] = 'application/json'; try { $response = JHttpFactory::getHttp()->post($baseURL, $data, $headers, 5); if ($response === null || $response->code !== 200) { $result = json_decode($response->body); $this->throwError($result->error->message); return false; } } catch (RuntimeException $e) { $this->throwError($e->getMessage()); return false; } $data = json_decode($response->body); if (!isset($data->id)) { return false; } return $data->id; } } PK!ǂ  +system/nrframework/helpers/urls/tinyurl.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; class nrURLShortTinyURL extends NRURLShortener { protected $needsKey = false; protected $needsLogin = false; function baseURL() { return "http://tinyurl.com/api-create.php?url=".urlencode($this->url); } } PK! )system/nrframework/helpers/groupfield.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; use \NRFramework\HTML; require_once __DIR__ . '/field.php'; class NRFormGroupField extends NRFormField { public $type = 'Field'; public $default_group = 'Categories'; protected function getInput() { $this->params = $this->element->attributes(); return $this->getSelectList(); } public function getGroup() { $this->params = $this->element->attributes(); return $this->get('group', $this->default_group ?: $this->type); } public function getOptions() { $group = $this->getGroup(); $id = $this->type . '_' . $group; $data[$id] = $this->{'get' . $group}(); return $data[$id]; } public function getSelectList($group = '') { if (!is_array($this->value)) { $this->value = explode(',', $this->value); } $size = (int) $this->get('size', 300); $group = $group ?: $this->getGroup(); $options = $this->getOptions(); switch ($group) { case 'categories': return HTML::treeselect($options, $this->name, $this->value, $this->id, $size, 0, $this->class); default: return HTML::treeselectSimple($options, $this->name, $this->value, $this->id, $size, $this->class); } } }PK!*HH*system/nrframework/helpers/imageresize.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // no direct access defined('_JEXEC') or die; class NRFrameworkImage { /** * @var */ private $image; /** * @var array */ private $variables; /** * @param $image */ function __construct($image) { $this->image = str_replace(JURI::root(true), '', $image); if (substr($this->image, 0, 1) == "/") { $this->image = substr($this->image, 1); } // Default values $this->variables = array ( 'height' => '100', 'width' => '100', 'ratio' => '1', 'crop' => true, 'quality' => 100, 'cache' => true, 'filename' => 'img_' ); } /** * @param $width * @param $height */ public function setSize($width, $height) { $this->variables['width'] = (int) $width; $this->variables['height'] = (int) $height; $this->variables['ratio'] = ((int) $width / (int) $height); } /** * @param $crop */ public function setCrop($crop) { $this->variables['crop'] = (bool) $crop; } /** * @param $quality */ public function setQuality($quality) { $this->variables['quality'] = (int) $quality; } /** * @param $cache */ public function setCache($cache) { $this->variables['cache'] = (bool) $cache; } /** * Get some basic information from the source image * @return array */ private function imageInfo() { $image = getimagesize($this->image); $info = array(); $info['width'] = $image[0]; $info['height'] = $image[1]; $info['ratio'] = $image[0]/$image[1]; $info['mime'] = $image['mime']; return $info; } /** * @return resource * Loads the image */ private function openImage() { switch ($this->imageInfo()['mime']) { case 'image/jpeg': $image = imagecreatefromjpeg ($this->image); break; case 'image/png': $image = imagecreatefrompng ($this->image); imagealphablending( $image, true ); imagesavealpha( $image, true ); break; case 'image/gif': $image = imagecreatefromgif ($this->image); break; default: throw new RuntimeException('Unknown file type'); } return $image; } /** * @param $image * @return resource * Does the actual image resize */ private function resizeImage($image) { if (!is_resource($image)) { throw new RuntimeException('Wrong path or this is not an image'); } $newImage = imagecreatetruecolor($this->variables['width'], $this->variables['height']); if (($this->variables['crop'] == true) and ($this->imageInfo()['ratio'] != $this->variables['ratio'])) { $src_x = $src_y = 0; $src_w = $this->imageInfo()['width']; $src_h = $this->imageInfo()['height']; $cmp_x = $src_w / $this->variables['width']; $cmp_y = $src_h / $this->variables['height']; // calculate x or y coordinate and width or height of source if ($cmp_x > $cmp_y) { $src_w = round ($src_w / $cmp_x * $cmp_y); $src_x = round (($src_w - ($src_w / $cmp_x * $cmp_y)) / 2); } else if ($cmp_y > $cmp_x) { $src_h = round ($src_h / $cmp_y * $cmp_x); $src_y = round (($src_h - ($src_h / $cmp_y * $cmp_x)) / 2); } imagecopyresampled($newImage, $image, 0, 0, $src_x, $src_y, $this->variables['width'], $this->variables['height'], $src_w, $src_h); return $newImage; } else { imagecopyresampled($newImage, $image, 0, 0, 0, 0, $this->variables['width'], $this->variables['height'], $this->imageInfo()['width'], $this->imageInfo()['height']); } return $newImage; } /** * @return string * Generate the filename for the image, based on original name, width, height and quality */ private function createFilename() { return $this->variables['filename'].md5($this->image.$this->variables['width'].$this->variables['height'].$this->variables['quality']).'.jpg'; } /** * @return bool * Check if an image exists in the cache */ private function checkCache() { return file_exists(JPATH_SITE.'/cache/images/'.$this->createFilename()); } /** * Checks if the cache folder exists, and if not, it creates it * */ private function cacheFolder() { if (!JFolder::exists(JPATH_SITE.'/cache/images')) { try { JFolder::create(JPATH_SITE.'/cache/images'); } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } } } /** * @param $image * Saves the image * @throws ErrorException */ private function saveImage($image) { $this->cacheFolder(); imageinterlace($image, true); $saved = imagejpeg($image, JPATH_SITE . '/cache/images/' . $this->createFilename(), $this->variables['quality']); if ($saved == false) { throw new ErrorException('Cannot save file, please check directory and permissions'); } imagedestroy($image); } /** * @param $image * Processes the image, unless it is already in the cache * @throws ErrorException * @returns string */ private function processImage($image) { if (($this->variables['cache'] == true) and $this->checkCache()) { return false; } else { try { $newImage = $this->openImage($image); $newImage = $this->resizeImage($newImage); $this->saveImage($newImage); } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } } } /** * Method to process the image and get the new image's URL */ public function get() { $this->processImage($this->image); return JURI::root(true).'/cache/images/'.$this->createFilename(); } }PK!lJ#system/nrframework/helpers/text.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die; class NRText { public static function prepareSelectItem($string, $published = 1, $type = '', $remove_first = 0) { if (empty($string)) { return ''; } $string = str_replace(array(' ', ' '), ' ', $string); $string = preg_replace('#- #', ' ', $string); for ($i = 0; $remove_first > $i; $i++) { $string = preg_replace('#^ #', '', $string); } if (preg_match('#^( *)(.*)$#', $string, $match)) { list($string, $pre, $name) = $match; $pre = preg_replace('# #', ' · ', $pre); $pre = preg_replace('#(( · )*) · #', '\1 » ', $pre); $pre = str_replace(' ', '   ', $pre); $string = $pre . $name; } switch (true) { case ($type == 'separator'): $string = $string; break; case (!$published): $string = $string . ' [' . JText::_('JUNPUBLISHED') . ']'; break; case ($published == 2): $string = $string . ' [' . JText::_('JARCHIVED') . ']'; break; } return $string; } }PK!7system/nrframework/helpers/wrappers/campaignmonitor.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\CampaignMonitor instead. */ // No direct access defined('_JEXEC') or die;PK!ꐗ,system/nrframework/helpers/wrappers/drip.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\Drip instead. */ // No direct access defined('_JEXEC') or die;PK!18nb,system/nrframework/helpers/wrappers/zoho.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\ZoHo instead. */ // No direct access defined('_JEXEC') or die;PK!hC2system/nrframework/helpers/wrappers/convertkit.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\ConvertKit instead. */ // No direct access defined('_JEXEC') or die;PK!T1system/nrframework/helpers/wrappers/recaptcha.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\ReCaptcha instead. */ // No direct access defined('_JEXEC') or die;PK!>!3system/nrframework/helpers/wrappers/getresponse.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\GetResponse instead. */ // No direct access defined('_JEXEC') or die;PK!!4system/nrframework/helpers/wrappers/elasticemail.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\ElasticEmail instead. */ // No direct access defined('_JEXEC') or die;PK!5V%1system/nrframework/helpers/wrappers/mailchimp.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\MailChimp instead. */ // No direct access defined('_JEXEC') or die;PK![.0system/nrframework/helpers/wrappers/icontact.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\iContact instead. */ // No direct access defined('_JEXEC') or die;PK!;7system/nrframework/helpers/wrappers/constantcontact.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\ConstantContact instead. */ // No direct access defined('_JEXEC') or die;PK!kى2system/nrframework/helpers/wrappers/salesforce.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\SalesForce instead. */ // No direct access defined('_JEXEC') or die;PK!VÆ/system/nrframework/helpers/wrappers/zohocrm.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\ZohoCRM instead. */ // No direct access defined('_JEXEC') or die;PK!E2system/nrframework/helpers/wrappers/sendinblue.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\SendInBlue instead. */ // No direct access defined('_JEXEC') or die;PK!G*6system/nrframework/helpers/wrappers/activecampaign.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\ActiveCampaign instead. */ // No direct access defined('_JEXEC') or die;PK!g认/system/nrframework/helpers/wrappers/hubspot.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\Integrations\HubSpot instead. */ // No direct access defined('_JEXEC') or die;PK!hLZ Z $system/nrframework/helpers/field.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; JFormHelper::loadFieldClass('text'); class NRFormField extends JFormFieldText { public $type = 'Field'; /** * Document object * * @var object */ public $doc; /** * Database object * * @var object */ public $db; /** * Application Object * * @var object */ protected $app; /** * Class constructor */ function __construct() { $this->doc = JFactory::getDocument(); $this->app = JFactory::getApplication(); $this->db = JFactory::getDbo(); parent::__construct(); } /** * Method to get the field label markup. * * @return string The field label markup. */ protected function getLabel() { $label = $this->get("label"); if (empty($label)) { return ""; } return parent::getLabel(); } /** * Prepares string through JText * * @param string $string * * @return string */ public function prepareText($string = '') { $string = trim($string); if ($string == '') { return ''; } return JText::_($string); } /** * Method to get field parameters * * @param string $val Field parameter * @param string $default The default value * * @return string */ public function get($val, $default = '') { return (isset($this->element[$val]) && (string) $this->element[$val] != '') ? (string) $this->element[$val] : $default; } public function getOptionsByList($list, $extras = array(), $levelOffset = 0) { $options = array(); foreach ($list as $item) { $options[] = $this->getOptionByListItem($item, $extras, $levelOffset); } return $options; } public function getOptionByListItem($item, $extras = array(), $levelOffset = 0) { $name = trim($item->name); foreach ($extras as $key => $extra) { if (empty($item->{$extra})) { continue; } if ($extra == 'language' && $item->{$extra} == '*') { continue; } if (in_array($extra, array('id', 'alias')) && $item->{$extra} == $item->name) { continue; } $name .= ' [' . $item->{$extra} . ']'; } require_once __DIR__ . '/text.php'; $name = NRText::prepareSelectItem($name, isset($item->published) ? $item->published : 1); $option = JHtml::_('select.option', $item->id, $name, 'value', 'text', 0); if (isset($item->level)) { $option->level = $item->level + $levelOffset; } return $option; } }PK!D看(system/nrframework/helpers/fieldlist.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; jimport('joomla.form.helper'); JFormHelper::loadFieldClass('list'); class NRFormFieldList extends JFormFieldList { /** * Document object * * @var object */ public $doc; /** * Database object * * @var object */ public $db; /** * Application Object * * @var object */ protected $app; /** * Class constructor */ function __construct() { $this->doc = JFactory::getDocument(); $this->app = JFactory::getApplication(); $this->db = JFactory::getDbo(); parent::__construct(); } /** * Method to get the field label markup. * * @return string The field label markup. */ protected function getLabel() { $label = $this->get("label"); if (empty($label)) { return ""; } return parent::getLabel(); } protected function showSelect($default = "true") { return $this->get("showselect", $default) == "true" ? true : false; } /** * Method to get field parameters * * @param string $val Field parameter * @param string $default The default value * * @return string */ public function get($val, $default = '') { return (isset($this->element[$val]) && (string) $this->element[$val] != '') ? (string) $this->element[$val] : $default; } }PK!kˋ==4system/nrframework/helpers/vendors/Mobile_Detect.phpnu[ * Nick Ilyin * * Original author: Victor Stanciu * * @license Code and contributions have 'MIT License' * More details: https://github.com/serbanghita/Mobile-Detect/blob/master/LICENSE.txt * * @link Homepage: http://mobiledetect.net * GitHub Repo: https://github.com/serbanghita/Mobile-Detect * Google Code: http://code.google.com/p/php-mobile-detect/ * README: https://github.com/serbanghita/Mobile-Detect/blob/master/README.md * HOWTO: https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples * * @version 2.8.25 */ defined('_JEXEC') or die; class Mobile_Detect { /** * Mobile detection type. * * @deprecated since version 2.6.9 */ const DETECTION_TYPE_MOBILE = 'mobile'; /** * Extended detection type. * * @deprecated since version 2.6.9 */ const DETECTION_TYPE_EXTENDED = 'extended'; /** * A frequently used regular expression to extract version #s. * * @deprecated since version 2.6.9 */ const VER = '([\w._\+]+)'; /** * Top-level device. */ const MOBILE_GRADE_A = 'A'; /** * Mid-level device. */ const MOBILE_GRADE_B = 'B'; /** * Low-level device. */ const MOBILE_GRADE_C = 'C'; /** * Stores the version number of the current release. */ const VERSION = '2.8.25'; /** * A type for the version() method indicating a string return value. */ const VERSION_TYPE_STRING = 'text'; /** * A type for the version() method indicating a float return value. */ const VERSION_TYPE_FLOAT = 'float'; /** * A cache for resolved matches * @var array */ protected $cache = array(); /** * The User-Agent HTTP header is stored in here. * @var string */ protected $userAgent = null; /** * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE. * @var array */ protected $httpHeaders = array(); /** * CloudFront headers. E.g. CloudFront-Is-Desktop-Viewer, CloudFront-Is-Mobile-Viewer & CloudFront-Is-Tablet-Viewer. * @var array */ protected $cloudfrontHeaders = array(); /** * The matching Regex. * This is good for debug. * @var string */ protected $matchingRegex = null; /** * The matches extracted from the regex expression. * This is good for debug. * @var string */ protected $matchesArray = null; /** * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED. * * @deprecated since version 2.6.9 * * @var string */ protected $detectionType = self::DETECTION_TYPE_MOBILE; /** * HTTP headers that trigger the 'isMobile' detection * to be true. * * @var array */ protected static $mobileHeaders = array( 'HTTP_ACCEPT' => array('matches' => array( // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/ 'application/x-obml2d', // BlackBerry devices. 'application/vnd.rim.html', 'text/vnd.wap.wml', 'application/vnd.wap.xhtml+xml' )), 'HTTP_X_WAP_PROFILE' => null, 'HTTP_X_WAP_CLIENTID' => null, 'HTTP_WAP_CONNECTION' => null, 'HTTP_PROFILE' => null, // Reported by Opera on Nokia devices (eg. C3). 'HTTP_X_OPERAMINI_PHONE_UA' => null, 'HTTP_X_NOKIA_GATEWAY_ID' => null, 'HTTP_X_ORANGE_ID' => null, 'HTTP_X_VODAFONE_3GPDPCONTEXT' => null, 'HTTP_X_HUAWEI_USERID' => null, // Reported by Windows Smartphones. 'HTTP_UA_OS' => null, // Reported by Verizon, Vodafone proxy system. 'HTTP_X_MOBILE_GATEWAY' => null, // Seen this on HTC Sensation. SensationXE_Beats_Z715e. 'HTTP_X_ATT_DEVICEID' => null, // Seen this on a HTC. 'HTTP_UA_CPU' => array('matches' => array('ARM')), ); /** * List of mobile devices (phones). * * @var array */ protected static $phoneDevices = array( 'iPhone' => '\biPhone\b|\biPod\b', // |\biTunes 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+', 'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1|Z520m', 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6', // @todo: Is 'Dell Streak' a tablet or a phone? ;) 'Dell' => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b', 'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\bMoto E\b', 'Samsung' => '\bSamsung\b|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C', 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323)', 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533', 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile', 'NokiaLumia' => 'Lumia [0-9]{3,4}', // http://www.micromaxinfo.com/mobiles/smartphones // Added because the codes might conflict with Acer Tablets. 'Micromax' => 'Micromax.*\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\b', // @todo Complete the regex. 'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;) // http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH) // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android. 'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790', // http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones. 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250', // http://fr.wikomobile.com 'Wiko' => 'KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM', 'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)', // Added simvalley mobile just for fun. They have some interesting devices. // http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html 'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b', // Wolfgang - a brand that is sold by Aldi supermarkets. // http://www.wolfgangmobile.com/ 'Wolfgang' => 'AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q', 'Alcatel' => 'Alcatel', 'Nintendo' => 'Nintendo 3DS', // http://en.wikipedia.org/wiki/Amoi 'Amoi' => 'Amoi', // http://en.wikipedia.org/wiki/INQ 'INQ' => 'INQ', // @Tapatalk is a mobile app; http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039 'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser', ); /** * List of tablet devices. * * @var array */ protected static $tabletDevices = array( // @todo: check for mobile friendly emails topic. 'iPad' => 'iPad|iPad.*Mobile', // Removed |^.*Android.*Nexus(?!(?:Mobile).)*$ // @see #442 'NexusTablet' => 'Android.*Nexus[\s]+(7|9|10)', 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587', // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone. // http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\b|Android.*Silk/[0-9.]+ like Chrome/[0-9.]+ (?!Mobile)', // Only the Surface tablets with Windows RT are considered mobile. // http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)', // http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT 'HPTablet' => 'HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10', // Watch out for PadFone, see #132. // http://www.asus.com/de/Tablets_Mobile/Memo_Pad_Products/ 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|\bK00C\b|\bK00E\b|\bK00L\b|TX201LA|ME176C|ME102A|\bM80TA\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\bME70C\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z', 'BlackBerryTablet' => 'PlayBook|RIM Tablet', 'HTCtablet' => 'HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410', 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617', 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2', // http://www.acer.ro/ac/ro/RO/content/drivers // http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer) // http://us.acer.com/ac/en/US/content/group/tablets // http://www.acer.de/ac/de/DE/content/models/tablets/ // Can conflict with Micromax and Motorola phones codes. 'AcerTablet' => 'Android.*; \b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\b|W3-810|\bA3-A10\b|\bA3-A11\b|\bA3-A20\b|\bA3-A30', // http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/ // http://us.toshiba.com/tablets/tablet-finder // http://www.toshiba.co.jp/regza/tablet/ 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO', // http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html // http://www.lg.com/us/tablets 'LGTablet' => '\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\b', 'FujitsuTablet' => 'Android.*\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\b', // Prestigio Tablets http://www.prestigio.com/support 'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002', // http://support.lenovo.com/en_GB/downloads/default.page?# 'LenovoTablet' => 'Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)', // http://www.dell.com/support/home/us/en/04/Products/tab_mob/tablets 'DellTablet' => 'Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7', // http://www.yarvik.com/en/matrix/tablets/ 'YarvikTablet' => 'Android.*\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\b', 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB', 'ArnovaTablet' => '97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2', // http://www.intenso.de/kategorie_en.php?kategorie=33 // @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate 'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004', // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/ 'IRUTablet' => 'M702pro', 'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b', // http://www.e-boda.ro/tablete-pc.html 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)', // http://www.allview.ro/produse/droseries/lista-tablete-pc/ 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)', // http://wiki.archosfans.com/index.php?title=Main_Page // @note Rewrite the regex format after we add more UAs. 'ArchosTablet' => '\b(101G9|80G9|A101IT)\b|Qilive 97R|Archos5|\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\b', // http://www.ainol.com/plugin.php?identifier=ainol&module=product 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark', 'NokiaLumiaTablet' => 'Lumia 2520', // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER // Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser // http://www.sony.jp/support/tablet/ 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP612|SOT31', // http://www.support.philips.com/support/catalog/worldproducts.jsp?userLanguage=en&userCountry=cn&categoryid=3G_LTE_TABLET_SU_CN_CARE&title=3G%20tablets%20/%20LTE%20range&_dyncharset=UTF-8 'PhilipsTablet' => '\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\b', // db + http://www.cube-tablet.com/buy-products.html 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT', // http://www.cobyusa.com/?p=pcat&pcat_id=3001 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010', // http://www.match.net.cn/products.asp 'MIDTablet' => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10', // http://www.msi.com/support // @todo Research the Windows Tablets. 'MSITablet' => 'MSI \b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\b', // @todo http://www.kyoceramobile.com/support/drivers/ // 'KyoceraTablet' => null, // @todo http://intexuae.com/index.php/category/mobile-devices/tablets-products/ // 'IntextTablet' => null, // http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets) // http://www.imp3.net/14/show.php?itemid=20454 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)', // http://www.rock-chips.com/index.php?do=prod&pid=2 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A', // http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/ 'FlyTablet' => 'IQ310|Fly Vision', // http://www.bqreaders.com/gb/tablets-prices-sale.html 'bqTablet' => 'Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris [E|M]10)|Maxwell.*Lite|Maxwell.*Plus', // http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290 // http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets) 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim', // Nec or Medias Tab 'NecTablet' => '\bN-06D|\bN-08D', // Pantech Tablets: http://www.pantechusa.com/phones/ 'PantechTablet' => 'Pantech.*P4100', // Broncho Tablets: http://www.broncho.cn/ (hard to find) 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)', // http://versusuk.com/support.html 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b', // http://www.zync.in/index.php/our-products/tablet-phablets 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900', // http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/ 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA', // https://www.nabitablet.com/ 'NabiTablet' => 'Android.*\bNabi', 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build', // French Danew Tablets http://www.danew.com/produits-tablette.php 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b', // Texet Tablets and Readers http://www.texet.ru/tablet/ 'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE', // Avoid detecting 'PLAYSTATION 3' as mobile. 'PlaystationTablet' => 'Playstation.*(Portable|Vita)', // http://www.trekstor.de/surftabs.html 'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab', // http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets 'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b', // http://www.advandigital.com/index.php?link=content-product&jns=JP001 // because of the short codenames we have to include whitespaces to reduce the possible conflicts. 'AdvanTablet' => 'Android.* \b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\b ', // http://www.danytech.com/category/tablet-pc 'DanyTechTablet' => 'Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1', // http://www.galapad.net/product.html 'GalapadTablet' => 'Android.*\bG1\b', // http://www.micromaxinfo.com/tablet/funbook 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b', // http://www.karbonnmobiles.com/products_tablet.php 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b', // http://www.myallfine.com/Products.asp 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide', // http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr= 'PROSCANTablet' => '\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\b', // http://www.yonesnav.com/products/products.php 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026', // http://www.cjshowroom.com/eproducts.aspx?classcode=004001001 // China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html) 'ChangJiaTablet' => 'TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503', // http://www.gloryunion.cn/products.asp // http://www.allwinnertech.com/en/apply/mobile.html // http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB) // @todo: Softwiner tablets? // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions. 'GUTablet' => 'TX-A1301|TX-M9002|Q702|kf026', // A12R|D75A|D77|D79|R83|A95|A106C|R15|A75|A76|D71|D72|R71|R73|R77|D82|R85|D92|A97|D92|R91|A10F|A77F|W71F|A78F|W78F|W81F|A97F|W91F|W97F|R16G|C72|C73E|K72|K73|R96G // http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118 'PointOfViewTablet' => 'TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10', // http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/ // @todo: add more tests. 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)', // http://hclmetablet.com/India/index.php 'HCLTablet' => 'HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync', // http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html 'DPSTablet' => 'DPS Dream 9|DPS Dual 7', // http://www.visture.com/index.asp 'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10', // http://www.mijncresta.nl/tablet 'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989', // MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309 'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b', // Concorde tab 'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan', // GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/ 'GoCleverTablet' => 'GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042', // Modecom Tablets - http://www.modecom.eu/tablets/portal/ 'ModecomTablet' => 'FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003', // Vonino Tablets - http://www.vonino.eu/tablets 'VoninoTablet' => '\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\bQ8\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\b', // ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0 'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1', // Storex Tablets - http://storex.fr/espace_client/support.html // @note: no need to add all the tablet codes since they are guided by the first regex. 'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab', // Generic Vodafone tablets. 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497', // French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb // Aka: http://www.essentielb.fr/ 'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2', // Ross & Moor - http://ross-moor.ru/ 'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711', // i-mobile http://product.i-mobilephone.com/Mobile_Device 'iMobileTablet' => 'i-mobile i-note', // http://www.tolino.de/de/vergleichen/ 'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine', // AudioSonic - a Kmart brand // http://www.kmart.com.au/webapp/wcs/stores/servlet/Search?langId=-1&storeId=10701&catalogId=10001&categoryId=193001&pageSize=72¤tPage=1&searchCategory=193001%2b4294965664&sortBy=p_MaxPrice%7c1 'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b', // AMPE Tablets - http://www.ampe.com.my/product-category/tablets/ // @todo: add them gradually to avoid conflicts. 'AMPETablet' => 'Android.* A78 ', // Skk Mobile - http://skkmobile.com.ph/product_tablets.php 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)', // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1 'TecnoTablet' => 'TECNO P9', // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3 'JXDTablet' => 'Android.* \b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\b', // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/ 'iJoyTablet' => 'Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)', // http://www.intracon.eu/tablet 'FX2Tablet' => 'FX2 PAD7|FX2 PAD10', // http://www.xoro.de/produkte/ // @note: Might be the same brand with 'Simply tablets' 'XoroTablet' => 'KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151', // http://www1.viewsonic.com/products/computing/tablets/ 'ViewsonicTablet' => 'ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a', // http://www.odys.de/web/internet-tablet_en.html 'OdysTablet' => 'LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\bXELIO\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10', // http://www.captiva-power.de/products.html#tablets-en 'CaptivaTablet' => 'CAPTIVA PAD', // IconBIT - http://www.iconbit.com/products/tablets/ 'IconbitTablet' => 'NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S', // http://www.teclast.com/topic.php?channelID=70&topicID=140&pid=63 'TeclastTablet' => 'T98 4G|\bP80\b|\bX90HD\b|X98 Air|X98 Air 3G|\bX89\b|P80 3G|\bX80h\b|P98 Air|\bX89HD\b|P98 3G|\bP90HD\b|P89 3G|X98 3G|\bP70h\b|P79HD 3G|G18d 3G|\bP79HD\b|\bP89s\b|\bA88\b|\bP10HD\b|\bP19HD\b|G18 3G|\bP78HD\b|\bA78\b|\bP75\b|G17s 3G|G17h 3G|\bP85t\b|\bP90\b|\bP11\b|\bP98t\b|\bP98HD\b|\bG18d\b|\bP85s\b|\bP11HD\b|\bP88s\b|\bA80HD\b|\bA80se\b|\bA10h\b|\bP89\b|\bP78s\b|\bG18\b|\bP85\b|\bA70h\b|\bA70\b|\bG17\b|\bP18\b|\bA80s\b|\bA11s\b|\bP88HD\b|\bA80h\b|\bP76s\b|\bP76h\b|\bP98\b|\bA10HD\b|\bP78\b|\bP88\b|\bA11\b|\bA10t\b|\bP76a\b|\bP76t\b|\bP76e\b|\bP85HD\b|\bP85a\b|\bP86\b|\bP75HD\b|\bP76v\b|\bA12\b|\bP75a\b|\bA15\b|\bP76Ti\b|\bP81HD\b|\bA10\b|\bT760VE\b|\bT720HD\b|\bP76\b|\bP73\b|\bP71\b|\bP72\b|\bT720SE\b|\bC520Ti\b|\bT760\b|\bT720VE\b|T720-3GE|T720-WiFi', // Onda - http://www.onda-tablet.com/buy-android-onda.html?dir=desc&limit=all&order=price 'OndaTablet' => '\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\b[\s]+', 'JaytechTablet' => 'TPC-PA762', 'BlaupunktTablet' => 'Endeavour 800NG|Endeavour 1010', // http://www.digma.ru/support/download/ // @todo: Ebooks also (if requested) 'DigmaTablet' => '\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\b', // http://www.evolioshop.com/ro/tablete-pc.html // http://www.evolio.ro/support/downloads_static.html?cat=2 // @todo: Research some more 'EvolioTablet' => 'ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\bEvotab\b|\bNeura\b', // @todo http://www.lavamobiles.com/tablets-data-cards 'LavaTablet' => 'QPAD E704|\bIvoryS\b|E-TAB IVORY|\bE-TAB\b', // http://www.breezetablet.com/ 'AocTablet' => 'MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712', // http://www.mpmaneurope.com/en/products/internet-tablets-14/android-tablets-14/ 'MpmanTablet' => 'MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\bMPG7\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010', // https://www.celkonmobiles.com/?_a=categoryphones&sid=2 'CelkonTablet' => 'CT695|CT888|CT[\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\bCT-1\b', // http://www.wolderelectronics.com/productos/manuales-y-guias-rapidas/categoria-2-miTab 'WolderTablet' => 'miTab \b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\b', // http://www.mi.com/en 'MiTablet' => '\bMI PAD\b|\bHM NOTE 1W\b', // http://www.nbru.cn/index.html 'NibiruTablet' => 'Nibiru M1|Nibiru Jupiter One', // http://navroad.com/products/produkty/tablety/ 'NexoTablet' => 'NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI', // http://leader-online.com/new_site/product-category/tablets/ // http://www.leader-online.net.au/List/Tablet 'LeaderTablet' => 'TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100', // http://www.datawind.com/ubislate/ 'UbislateTablet' => 'UbiSlate[\s]?7C', // http://www.pocketbook-int.com/ru/support 'PocketBookTablet' => 'Pocketbook', // http://www.kocaso.com/product_tablet.html 'KocasoTablet' => '\b(TB-1207)\b', // http://global.hisense.com/product/asia/tablet/Sero7/201412/t20141215_91832.htm 'HisenseTablet' => '\b(F5281|E2371)\b', // http://www.tesco.com/direct/hudl/ 'Hudl' => 'Hudl HT7S3|Hudl 2', // http://www.telstra.com.au/home-phone/thub-2/ 'TelstraTablet' => 'T-Hub2', 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\bM6pro\b|CT1020W|arc 10HD|\bTP750\b' ); /** * List of mobile Operating Systems. * * @var array */ protected static $operatingSystems = array( 'AndroidOS' => 'Android', 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os', 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino', 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b', // @reference: http://en.wikipedia.org/wiki/Windows_Mobile 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;', // @reference: http://en.wikipedia.org/wiki/Windows_Phone // http://wifeng.cn/?r=blog&a=view&id=106 // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx // http://msdn.microsoft.com/library/ms537503.aspx // https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx 'WindowsPhoneOS' => 'Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;', 'iOS' => '\biPhone.*Mobile|\biPod|\biPad', // http://en.wikipedia.org/wiki/MeeGo // @todo: research MeeGo in UAs 'MeeGoOS' => 'MeeGo', // http://en.wikipedia.org/wiki/Maemo // @todo: research Maemo in UAs 'MaemoOS' => 'Maemo', 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135 'webOS' => 'webOS|hpwOS', 'badaOS' => '\bBada\b', 'BREWOS' => 'BREW', ); /** * List of mobile User Agents. * * IMPORTANT: This is a list of only mobile browsers. * Mobile Detect 2.x supports only mobile browsers, * it was never designed to detect all browsers. * The change will come in 2017 in the 3.x release for PHP7. * * @var array */ protected static $browsers = array( //'Vivaldi' => 'Vivaldi', // @reference: https://developers.google.com/chrome/mobile/docs/user-agent 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?', 'Dolfin' => '\bDolfin\b', 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+', 'Skyfire' => 'Skyfire', 'Edge' => 'Mobile Safari/[.0-9]* Edge', 'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+ 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS', 'Bolt' => 'bolt', 'TeaShark' => 'teashark', 'Blazer' => 'Blazer', // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3 'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari', // http://en.wikipedia.org/wiki/Midori_(web_browser) //'Midori' => 'midori', //'Tizen' => 'Tizen', 'UCBrowser' => 'UC.*Browser|UCWEB', 'baiduboxapp' => 'baiduboxapp', 'baidubrowser' => 'baidubrowser', // https://github.com/serbanghita/Mobile-Detect/issues/7 'DiigoBrowser' => 'DiigoBrowser', // http://www.puffinbrowser.com/index.php 'Puffin' => 'Puffin', // http://mercury-browser.com/index.html 'Mercury' => '\bMercury\b', // http://en.wikipedia.org/wiki/Obigo_Browser 'ObigoBrowser' => 'Obigo', // http://en.wikipedia.org/wiki/NetFront 'NetFront' => 'NF-Browser', // @reference: http://en.wikipedia.org/wiki/Minimo // http://en.wikipedia.org/wiki/Vision_Mobile_Browser 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger', // @reference: https://en.wikipedia.org/wiki/Pale_Moon_(web_browser) 'PaleMoon' => 'Android.*PaleMoon|Mobile.*PaleMoon', ); /** * Utilities. * * @var array */ protected static $utilities = array( // Experimental. When a mobile device wants to switch to 'Desktop Mode'. // http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/ // https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011 // https://developers.facebook.com/docs/sharing/best-practices 'Bot' => 'Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom', 'MobileBot' => 'Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2', 'DesktopMode' => 'WPDesktop', 'TV' => 'SonyDTV|HbbTV', // experimental 'WebKit' => '(webkit)[ /]([\w.]+)', // @todo: Include JXD consoles. 'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\b', 'Watch' => 'SM-V700', ); /** * All possible HTTP headers that represent the * User-Agent string. * * @var array */ protected static $uaHttpHeaders = array( // The default User-Agent string. 'HTTP_USER_AGENT', // Header can occur on devices using Opera Mini. 'HTTP_X_OPERAMINI_PHONE_UA', // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/ 'HTTP_X_DEVICE_USER_AGENT', 'HTTP_X_ORIGINAL_USER_AGENT', 'HTTP_X_SKYFIRE_PHONE', 'HTTP_X_BOLT_PHONE_UA', 'HTTP_DEVICE_STOCK_UA', 'HTTP_X_UCBROWSER_DEVICE_UA' ); /** * The individual segments that could exist in a User-Agent string. VER refers to the regular * expression defined in the constant self::VER. * * @var array */ protected static $properties = array( // Build 'Mobile' => 'Mobile/[VER]', 'Build' => 'Build/[VER]', 'Version' => 'Version/[VER]', 'VendorID' => 'VendorID/[VER]', // Devices 'iPad' => 'iPad.*CPU[a-z ]+[VER]', 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]', 'iPod' => 'iPod.*CPU[a-z ]+[VER]', //'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'), 'Kindle' => 'Kindle/[VER]', // Browser 'Chrome' => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'), 'Coast' => array('Coast/[VER]'), 'Dolfin' => 'Dolfin/[VER]', // @reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox 'Firefox' => array('Firefox/[VER]', 'FxiOS/[VER]'), 'Fennec' => 'Fennec/[VER]', // http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx 'Edge' => 'Edge/[VER]', 'IE' => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];', 'Trident/[0-9.]+;.*rv:[VER]'), // http://en.wikipedia.org/wiki/NetFront 'NetFront' => 'NetFront/[VER]', 'NokiaBrowser' => 'NokiaBrowser/[VER]', 'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ), 'Opera Mini' => 'Opera Mini/[VER]', 'Opera Mobi' => 'Version/[VER]', 'UC Browser' => 'UC Browser[VER]', 'MQQBrowser' => 'MQQBrowser/[VER]', 'MicroMessenger' => 'MicroMessenger/[VER]', 'baiduboxapp' => 'baiduboxapp/[VER]', 'baidubrowser' => 'baidubrowser/[VER]', 'SamsungBrowser' => 'SamsungBrowser/[VER]', 'Iron' => 'Iron/[VER]', // @note: Safari 7534.48.3 is actually Version 5.1. // @note: On BlackBerry the Version is overwriten by the OS. 'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ), 'Skyfire' => 'Skyfire/[VER]', 'Tizen' => 'Tizen/[VER]', 'Webkit' => 'webkit[ /][VER]', 'PaleMoon' => 'PaleMoon/[VER]', // Engine 'Gecko' => 'Gecko/[VER]', 'Trident' => 'Trident/[VER]', 'Presto' => 'Presto/[VER]', 'Goanna' => 'Goanna/[VER]', // OS 'iOS' => ' \bi?OS\b [VER][ ;]{1}', 'Android' => 'Android [VER]', 'BlackBerry' => array('BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'), 'BREW' => 'BREW [VER]', 'Java' => 'Java/[VER]', // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases 'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'), 'Windows Phone' => 'Windows Phone [VER]', 'Windows CE' => 'Windows CE/[VER]', // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd 'Windows NT' => 'Windows NT [VER]', 'Symbian' => array('SymbianOS/[VER]', 'Symbian/[VER]'), 'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'), ); /** * Construct an instance of this class. * * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored. * If left empty, will use the global _SERVER['HTTP_*'] vars instead. * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT * from the $headers array instead. */ public function __construct( array $headers = null, $userAgent = null ) { $this->setHttpHeaders($headers); $this->setUserAgent($userAgent); } /** * Get the current script version. * This is useful for the demo.php file, * so people can check on what version they are testing * for mobile devices. * * @return string The version number in semantic version format. */ public static function getScriptVersion() { return self::VERSION; } /** * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers. * * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract * the headers. The default null is left for backwards compatibility. */ public function setHttpHeaders($httpHeaders = null) { // use global _SERVER if $httpHeaders aren't defined if (!is_array($httpHeaders) || !count($httpHeaders)) { $httpHeaders = $_SERVER; } // clear existing headers $this->httpHeaders = array(); // Only save HTTP headers. In PHP land, that means only _SERVER vars that // start with HTTP_. foreach ($httpHeaders as $key => $value) { if (substr($key, 0, 5) === 'HTTP_') { $this->httpHeaders[$key] = $value; } } // In case we're dealing with CloudFront, we need to know. $this->setCfHeaders($httpHeaders); } /** * Retrieves the HTTP headers. * * @return array */ public function getHttpHeaders() { return $this->httpHeaders; } /** * Retrieves a particular header. If it doesn't exist, no exception/error is caused. * Simply null is returned. * * @param string $header The name of the header to retrieve. Can be HTTP compliant such as * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the * all-caps, HTTP_ prefixed, underscore seperated awesomeness. * * @return string|null The value of the header. */ public function getHttpHeader($header) { // are we using PHP-flavored headers? if (strpos($header, '_') === false) { $header = str_replace('-', '_', $header); $header = strtoupper($header); } // test the alternate, too $altHeader = 'HTTP_' . $header; //Test both the regular and the HTTP_ prefix if (isset($this->httpHeaders[$header])) { return $this->httpHeaders[$header]; } elseif (isset($this->httpHeaders[$altHeader])) { return $this->httpHeaders[$altHeader]; } return null; } public function getMobileHeaders() { return self::$mobileHeaders; } /** * Get all possible HTTP headers that * can contain the User-Agent string. * * @return array List of HTTP headers. */ public function getUaHttpHeaders() { return self::$uaHttpHeaders; } /** * Set CloudFront headers * http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device * * @param array $cfHeaders List of HTTP headers * * @return boolean If there were CloudFront headers to be set */ public function setCfHeaders($cfHeaders = null) { // use global _SERVER if $cfHeaders aren't defined if (!is_array($cfHeaders) || !count($cfHeaders)) { $cfHeaders = $_SERVER; } // clear existing headers $this->cloudfrontHeaders = array(); // Only save CLOUDFRONT headers. In PHP land, that means only _SERVER vars that // start with cloudfront-. $response = false; foreach ($cfHeaders as $key => $value) { if (substr(strtolower($key), 0, 16) === 'http_cloudfront_') { $this->cloudfrontHeaders[strtoupper($key)] = $value; $response = true; } } return $response; } /** * Retrieves the cloudfront headers. * * @return array */ public function getCfHeaders() { return $this->cloudfrontHeaders; } /** * Set the User-Agent to be used. * * @param string $userAgent The user agent string to set. * * @return string|null */ public function setUserAgent($userAgent = null) { // Invalidate cache due to #375 $this->cache = array(); if (false === empty($userAgent)) { return $this->userAgent = $userAgent; } else { $this->userAgent = null; foreach ($this->getUaHttpHeaders() as $altHeader) { if (false === empty($this->httpHeaders[$altHeader])) { // @todo: should use getHttpHeader(), but it would be slow. (Serban) $this->userAgent .= $this->httpHeaders[$altHeader] . " "; } } if (!empty($this->userAgent)) { return $this->userAgent = trim($this->userAgent); } } if (count($this->getCfHeaders()) > 0) { return $this->userAgent = 'Amazon CloudFront'; } return $this->userAgent = null; } /** * Retrieve the User-Agent. * * @return string|null The user agent if it's set. */ public function getUserAgent() { return $this->userAgent; } /** * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set. * * @deprecated since version 2.6.9 * * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default * parameter is null which will default to self::DETECTION_TYPE_MOBILE. */ public function setDetectionType($type = null) { if ($type === null) { $type = self::DETECTION_TYPE_MOBILE; } if ($type !== self::DETECTION_TYPE_MOBILE && $type !== self::DETECTION_TYPE_EXTENDED) { return; } $this->detectionType = $type; } public function getMatchingRegex() { return $this->matchingRegex; } public function getMatchesArray() { return $this->matchesArray; } /** * Retrieve the list of known phone devices. * * @return array List of phone devices. */ public static function getPhoneDevices() { return self::$phoneDevices; } /** * Retrieve the list of known tablet devices. * * @return array List of tablet devices. */ public static function getTabletDevices() { return self::$tabletDevices; } /** * Alias for getBrowsers() method. * * @return array List of user agents. */ public static function getUserAgents() { return self::getBrowsers(); } /** * Retrieve the list of known browsers. Specifically, the user agents. * * @return array List of browsers / user agents. */ public static function getBrowsers() { return self::$browsers; } /** * Retrieve the list of known utilities. * * @return array List of utilities. */ public static function getUtilities() { return self::$utilities; } /** * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*(). * * @deprecated since version 2.6.9 * * @return array All the rules (but not extended). */ public static function getMobileDetectionRules() { static $rules; if (!$rules) { $rules = array_merge( self::$phoneDevices, self::$tabletDevices, self::$operatingSystems, self::$browsers ); } return $rules; } /** * Method gets the mobile detection rules + utilities. * The reason this is separate is because utilities rules * don't necessary imply mobile. This method is used inside * the new $detect->is('stuff') method. * * @deprecated since version 2.6.9 * * @return array All the rules + extended. */ public function getMobileDetectionRulesExtended() { static $rules; if (!$rules) { // Merge all rules together. $rules = array_merge( self::$phoneDevices, self::$tabletDevices, self::$operatingSystems, self::$browsers, self::$utilities ); } return $rules; } /** * Retrieve the current set of rules. * * @deprecated since version 2.6.9 * * @return array */ public function getRules() { if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) { return self::getMobileDetectionRulesExtended(); } else { return self::getMobileDetectionRules(); } } /** * Retrieve the list of mobile operating systems. * * @return array The list of mobile operating systems. */ public static function getOperatingSystems() { return self::$operatingSystems; } /** * Check the HTTP headers for signs of mobile. * This is the fastest mobile check possible; it's used * inside isMobile() method. * * @return bool */ public function checkHttpHeadersForMobile() { foreach ($this->getMobileHeaders() as $mobileHeader => $matchType) { if (isset($this->httpHeaders[$mobileHeader])) { if (is_array($matchType['matches'])) { foreach ($matchType['matches'] as $_match) { if (strpos($this->httpHeaders[$mobileHeader], $_match) !== false) { return true; } } return false; } else { return true; } } } return false; } /** * Magic overloading method. * * @method boolean is[...]() * @param string $name * @param array $arguments * @return mixed * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is' */ public function __call($name, $arguments) { // make sure the name starts with 'is', otherwise if (substr($name, 0, 2) !== 'is') { throw new BadMethodCallException("No such method exists: $name"); } $this->setDetectionType(self::DETECTION_TYPE_MOBILE); $key = substr($name, 2); return $this->matchUAAgainstKey($key); } /** * Find a detection rule that matches the current User-agent. * * @param null $userAgent deprecated * @return boolean */ protected function matchDetectionRulesAgainstUA($userAgent = null) { // Begin general search. foreach ($this->getRules() as $_regex) { if (empty($_regex)) { continue; } if ($this->match($_regex, $userAgent)) { return true; } } return false; } /** * Search for a certain key in the rules array. * If the key is found then try to match the corresponding * regex against the User-Agent. * * @param string $key * * @return boolean */ protected function matchUAAgainstKey($key) { // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc. $key = strtolower($key); if (false === isset($this->cache[$key])) { // change the keys to lower case $_rules = array_change_key_case($this->getRules()); if (false === empty($_rules[$key])) { $this->cache[$key] = $this->match($_rules[$key]); } if (false === isset($this->cache[$key])) { $this->cache[$key] = false; } } return $this->cache[$key]; } /** * Check if the device is mobile. * Returns true if any type of mobile device detected, including special ones * @param null $userAgent deprecated * @param null $httpHeaders deprecated * @return bool */ public function isMobile($userAgent = null, $httpHeaders = null) { if ($httpHeaders) { $this->setHttpHeaders($httpHeaders); } if ($userAgent) { $this->setUserAgent($userAgent); } // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront' if ($this->getUserAgent() === 'Amazon CloudFront') { $cfHeaders = $this->getCfHeaders(); if(array_key_exists('HTTP_CLOUDFRONT_IS_MOBILE_VIEWER', $cfHeaders) && $cfHeaders['HTTP_CLOUDFRONT_IS_MOBILE_VIEWER'] === 'true') { return true; } } $this->setDetectionType(self::DETECTION_TYPE_MOBILE); if ($this->checkHttpHeadersForMobile()) { return true; } else { return $this->matchDetectionRulesAgainstUA(); } } /** * Check if the device is a tablet. * Return true if any type of tablet device is detected. * * @param string $userAgent deprecated * @param array $httpHeaders deprecated * @return bool */ public function isTablet($userAgent = null, $httpHeaders = null) { // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront' if ($this->getUserAgent() === 'Amazon CloudFront') { $cfHeaders = $this->getCfHeaders(); if(array_key_exists('HTTP_CLOUDFRONT_IS_TABLET_VIEWER', $cfHeaders) && $cfHeaders['HTTP_CLOUDFRONT_IS_TABLET_VIEWER'] === 'true') { return true; } } $this->setDetectionType(self::DETECTION_TYPE_MOBILE); foreach (self::$tabletDevices as $_regex) { if ($this->match($_regex, $userAgent)) { return true; } } return false; } /** * This method checks for a certain property in the * userAgent. * @todo: The httpHeaders part is not yet used. * * @param string $key * @param string $userAgent deprecated * @param string $httpHeaders deprecated * @return bool|int|null */ public function is($key, $userAgent = null, $httpHeaders = null) { // Set the UA and HTTP headers only if needed (eg. batch mode). if ($httpHeaders) { $this->setHttpHeaders($httpHeaders); } if ($userAgent) { $this->setUserAgent($userAgent); } $this->setDetectionType(self::DETECTION_TYPE_EXTENDED); return $this->matchUAAgainstKey($key); } /** * Some detection rules are relative (not standard), * because of the diversity of devices, vendors and * their conventions in representing the User-Agent or * the HTTP headers. * * This method will be used to check custom regexes against * the User-Agent string. * * @param $regex * @param string $userAgent * @return bool * * @todo: search in the HTTP headers too. */ public function match($regex, $userAgent = null) { $match = (bool) preg_match(sprintf('#%s#is', $regex), (false === empty($userAgent) ? $userAgent : $this->userAgent), $matches); // If positive match is found, store the results for debug. if ($match) { $this->matchingRegex = $regex; $this->matchesArray = $matches; } return $match; } /** * Get the properties array. * * @return array */ public static function getProperties() { return self::$properties; } /** * Prepare the version number. * * @todo Remove the error supression from str_replace() call. * * @param string $ver The string version, like "2.6.21.2152"; * * @return float */ public function prepareVersionNo($ver) { $ver = str_replace(array('_', ' ', '/'), '.', $ver); $arrVer = explode('.', $ver, 2); if (isset($arrVer[1])) { $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions. } return (float) implode('.', $arrVer); } /** * Check the version of the given property in the User-Agent. * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31) * * @param string $propertyName The name of the property. See self::getProperties() array * keys for all possible properties. * @param string $type Either self::VERSION_TYPE_STRING to get a string value or * self::VERSION_TYPE_FLOAT indicating a float value. This parameter * is optional and defaults to self::VERSION_TYPE_STRING. Passing an * invalid parameter will default to the this type as well. * * @return string|float The version of the property we are trying to extract. */ public function version($propertyName, $type = self::VERSION_TYPE_STRING) { if (empty($propertyName)) { return false; } // set the $type to the default if we don't recognize the type if ($type !== self::VERSION_TYPE_STRING && $type !== self::VERSION_TYPE_FLOAT) { $type = self::VERSION_TYPE_STRING; } $properties = self::getProperties(); // Check if the property exists in the properties array. if (true === isset($properties[$propertyName])) { // Prepare the pattern to be matched. // Make sure we always deal with an array (string is converted). $properties[$propertyName] = (array) $properties[$propertyName]; foreach ($properties[$propertyName] as $propertyMatchString) { $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString); // Identify and extract the version. preg_match(sprintf('#%s#is', $propertyPattern), $this->userAgent, $match); if (false === empty($match[1])) { $version = ($type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1]); return $version; } } } return false; } /** * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants. * * @return string One of the self::MOBILE_GRADE_* constants. */ public function mobileGrade() { $isMobile = $this->isMobile(); if ( // Apple iOS 4-7.0 – Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3 / 5.1 / 6.1), iPad 3 (5.1 / 6.0), iPad Mini (6.1), iPad Retina (7.0), iPhone 3GS (4.3), iPhone 4 (4.3 / 5.1), iPhone 4S (5.1 / 6.0), iPhone 5 (6.0), and iPhone 5S (7.0) $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT) >= 4.3 || $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT) >= 4.3 || $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT) >= 4.3 || // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5) // Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM // Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices // Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7 ( $this->version('Android', self::VERSION_TYPE_FLOAT)>2.1 && $this->is('Webkit') ) || // Windows Phone 7.5-8 - Tested on the HTC Surround (7.5), HTC Trophy (7.5), LG-E900 (7.5), Nokia 800 (7.8), HTC Mazaa (7.8), Nokia Lumia 520 (8), Nokia Lumia 920 (8), HTC 8x (8) $this->version('Windows Phone OS', self::VERSION_TYPE_FLOAT) >= 7.5 || // Tested on the Torch 9800 (6) and Style 9670 (6), BlackBerry® Torch 9810 (7), BlackBerry Z10 (10) $this->is('BlackBerry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) >= 6.0 || // Blackberry Playbook (1.0-2.0) - Tested on PlayBook $this->match('Playbook.*Tablet') || // Palm WebOS (1.4-3.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0), HP TouchPad (3.0) ( $this->version('webOS', self::VERSION_TYPE_FLOAT) >= 1.4 && $this->match('Palm|Pre|Pixi') ) || // Palm WebOS 3.0 - Tested on HP TouchPad $this->match('hp.*TouchPad') || // Firefox Mobile 18 - Tested on Android 2.3 and 4.1 devices ( $this->is('Firefox') && $this->version('Firefox', self::VERSION_TYPE_FLOAT) >= 18 ) || // Chrome for Android - Tested on Android 4.0, 4.1 device ( $this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 4.0 ) || // Skyfire 4.1 - Tested on Android 2.3 device ( $this->is('Skyfire') && $this->version('Skyfire', self::VERSION_TYPE_FLOAT) >= 4.1 && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3 ) || // Opera Mobile 11.5-12: Tested on Android 2.3 ( $this->is('Opera') && $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT) >= 11.5 && $this->is('AndroidOS') ) || // Meego 1.2 - Tested on Nokia 950 and N9 $this->is('MeeGoOS') || // Tizen (pre-release) - Tested on early hardware $this->is('Tizen') || // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser // @todo: more tests here! $this->is('Dolfin') && $this->version('Bada', self::VERSION_TYPE_FLOAT) >= 2.0 || // UC Browser - Tested on Android 2.3 device ( ($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3 ) || // Kindle 3 and Fire - Tested on the built-in WebKit browser for each ( $this->match('Kindle Fire') || $this->is('Kindle') && $this->version('Kindle', self::VERSION_TYPE_FLOAT) >= 3.0 ) || // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet $this->is('AndroidOS') && $this->is('NookTablet') || // Chrome Desktop 16-24 - Tested on OS X 10.7 and Windows 7 $this->version('Chrome', self::VERSION_TYPE_FLOAT) >= 16 && !$isMobile || // Safari Desktop 5-6 - Tested on OS X 10.7 and Windows 7 $this->version('Safari', self::VERSION_TYPE_FLOAT) >= 5.0 && !$isMobile || // Firefox Desktop 10-18 - Tested on OS X 10.7 and Windows 7 $this->version('Firefox', self::VERSION_TYPE_FLOAT) >= 10.0 && !$isMobile || // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7 $this->version('IE', self::VERSION_TYPE_FLOAT) >= 7.0 && !$isMobile || // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7 $this->version('Opera', self::VERSION_TYPE_FLOAT) >= 10 && !$isMobile ){ return self::MOBILE_GRADE_A; } if ( $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT)<4.3 || $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT)<4.3 || $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT)<4.3 || // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770 $this->is('Blackberry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) >= 5 && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<6 || //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3 ($this->version('Opera Mini', self::VERSION_TYPE_FLOAT) >= 5.0 && $this->version('Opera Mini', self::VERSION_TYPE_FLOAT) <= 7.0 && ($this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3 || $this->is('iOS')) ) || // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1) $this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') || // @todo: report this (tested on Nokia N71) $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT) >= 11 && $this->is('SymbianOS') ){ return self::MOBILE_GRADE_B; } if ( // Blackberry 4.x - Tested on the Curve 8330 $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) <= 5.0 || // Windows Mobile - Tested on the HTC Leo (WinMo 5.2) $this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', self::VERSION_TYPE_FLOAT) <= 5.2 || // Tested on original iPhone (3.1), iPhone 3 (3.2) $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT) <= 3.2 || $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT) <= 3.2 || $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT) <= 3.2 || // Internet Explorer 7 and older - Tested on Windows XP $this->version('IE', self::VERSION_TYPE_FLOAT) <= 7.0 && !$isMobile ){ return self::MOBILE_GRADE_C; } // All older smartphone platforms and featurephones - Any device that doesn't support media queries // will receive the basic, C grade experience. return self::MOBILE_GRADE_C; } }PK!tU+system/nrframework/NRFramework/Executer.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; use Joomla\Registry\Registry; defined('_JEXEC') or die; /** * Cleverly evaluate php code using a temporary file and without using the evil eval() PHP method */ class Executer { /** * The php code is going to be executed * * @var string */ private $php_code; /** * The data object passed as argument to function * * @var mixed */ private $payload; /** * Executer configuration * * @var object */ private $options; /** * Class constructor * * @param string $php_code The php code is going to be executed */ public function __construct($php_code = null, &$payload = null, $options = array()) { $this->setPhpCode($php_code); $this->setPayload($payload); // Default options $defaults = [ 'forbidden_php_functions' => [ 'fopen', 'popen', 'unlink', 'rmdir', 'dl', 'escapeshellarg', 'escapeshellcmd', 'exec', 'passthru', 'proc_close', 'proc_open', 'shell_exec', 'symlink', 'system', 'pcntl_exec', 'eval', 'create_function' ] ]; $options = array_merge($defaults, $options); $this->options = new Registry($options); } /** * Payload contains the variables passed as argumentse into the PHP code * * @param mixed $data * * @return void */ public function setPayload(&$data) { $this->payload = &$data; return $this; } /** * Set forbidden PHP functions. If any found, the whole PHP block won't run. * * @param array $functions * * @return void */ public function setForbiddenPHPFunctions($functions) { if (empty($functions)) { return $this; } if (is_string($functions)) { $functions = explode(',', $functions); } $this->options->set('forbidden_php_functions', $functions); return $this; } /** * Helper method to set the php code is about to be executed * * @param string $php_code * * @return void */ public function setPhpCode($php_code) { $this->php_code = $php_code; return $this; } /** * Checks if given PHP code is valid and it's allowed to run. * * @return bool */ private function allowedToRun() { // Check for forbidden PHP functions $re = '/(' . implode('|', $this->options->get('forbidden_php_functions')) . ')(\s*\(|\s+[\'"])/mi'; preg_match_all($re, $this->php_code, $matches); if (!empty($matches[0])) { return false; } // Check for backticks `` if ($has_back_ticks = preg_match('/`(.*?)`/s', $this->php_code)) { return false; } return true; } /** * Run function * * @return function */ public function run() { if (!$this->allowedToRun()) { return; } $function_name = $this->getFunctionName(); // Function doesn't exist. Let's create it. if (!function_exists($function_name)) { if (!$this->createFunction()) { return; } } return $function_name($this->payload); } /** * Creates a temporary function in memory * * @return void */ private function createFunction() { $function_name = $this->getFunctionName(); $function_content = $this->getFunctionContent(); $temp_file = $this->getTempPath() . '/' . $function_name; // Write function's content to a temporary file \JFile::write($temp_file, $function_content); // Include file include_once $temp_file; // Delete file if (!defined('JDEBUG') || !JDEBUG) { @chmod($temp_file, 0777); @unlink($temp_file); } return function_exists($function_name); } /** * Get temporary file content * * @return string */ private function getFunctionContent() { $function_name = $this->getFunctionName(); $variables = $this->getFunctionVariables(); $contents = [ 'php_code, ';return true;}' ]; $contents = implode("\n", $contents); // Remove Zero Width spaces / (non-)joiners $contents = str_replace( [ "\xE2\x80\x8B", "\xE2\x80\x8C", "\xE2\x80\x8D", ], '', $contents ); return $contents; } /** * Make user's life easier by initializing some Joomla helpful variables * * @return array */ protected function getFunctionVariables() { return [ '$app = $mainframe = JFactory::getApplication();', '$document = $doc = JFactory::getDocument();', '$database = $db = JFactory::getDbo();', '$user = JFactory::getUser();', '$Itemid = $app->input->getInt(\'Itemid\');' ]; } /** * Construct a temporary function name * * @return string */ private function getFunctionName() { return 'tassos_php_' . md5($this->php_code); } /** * Return Joomla temporary path * * @return void */ private function getTempPath() { return \JFactory::getConfig()->get('tmp_path', JPATH_ROOT . '/tmp'); } }PK!A_}::(system/nrframework/NRFramework/Mimes.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later * @credits https://github.com/codeigniter4/CodeIgniter4/blob/develop/app/Config/Mimes.php */ namespace NRFramework; // No direct access defined('_JEXEC') or die; class Mimes { /** * Map of extensions to mime types. * * @var array */ public static $mimes = [ 'hqx' => [ 'application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40', ], 'cpt' => 'application/mac-compactpro', 'csv' => [ 'text/csv', 'text/x-comma-separated-values', 'text/comma-separated-values', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain', ], 'bin' => [ 'application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary', ], 'dms' => 'application/octet-stream', 'lha' => 'application/octet-stream', 'lzh' => 'application/octet-stream', 'exe' => [ 'application/octet-stream', 'application/x-msdownload', ], 'class' => 'application/octet-stream', 'psd' => [ 'application/x-photoshop', 'image/vnd.adobe.photoshop', ], 'so' => 'application/octet-stream', 'sea' => 'application/octet-stream', 'dll' => 'application/octet-stream', 'oda' => 'application/oda', 'pdf' => [ 'application/pdf', 'application/force-download', 'application/x-download', ], 'ai' => [ 'application/pdf', 'application/postscript', ], 'eps' => 'application/postscript', 'ps' => 'application/postscript', 'smi' => 'application/smil', 'smil' => 'application/smil', 'mif' => 'application/vnd.mif', 'xls' => [ 'application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword', ], 'ppt' => [ 'application/vnd.ms-powerpoint', 'application/powerpoint', 'application/vnd.ms-office', 'application/msword', ], 'pptx' => [ 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip', ], 'wbxml' => 'application/wbxml', 'wmlc' => 'application/wmlc', 'dcr' => 'application/x-director', 'dir' => 'application/x-director', 'dxr' => 'application/x-director', 'dvi' => 'application/x-dvi', 'gtar' => 'application/x-gtar', 'gz' => 'application/x-gzip', 'gzip' => 'application/x-gzip', 'php' => [ 'application/x-php', 'application/x-httpd-php', 'application/php', 'text/php', 'text/x-php', 'application/x-httpd-php-source', ], 'php4' => 'application/x-httpd-php', 'php3' => 'application/x-httpd-php', 'phtml' => 'application/x-httpd-php', 'phps' => 'application/x-httpd-php-source', 'js' => [ 'application/x-javascript', 'text/plain', ], 'swf' => 'application/x-shockwave-flash', 'sit' => 'application/x-stuffit', 'tar' => 'application/x-tar', 'tgz' => [ 'application/x-tar', 'application/x-gzip-compressed', ], 'z' => 'application/x-compress', 'xhtml' => 'application/xhtml+xml', 'xht' => 'application/xhtml+xml', 'zip' => [ 'application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip', ], 'rar' => [ 'application/vnd.rar', 'application/x-rar', 'application/rar', 'application/x-rar-compressed', ], 'mid' => 'audio/midi', 'midi' => 'audio/midi', 'mpga' => 'audio/mpeg', 'mp2' => 'audio/mpeg', 'mp3' => [ 'audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3', ], 'aif' => [ 'audio/x-aiff', 'audio/aiff', ], 'aiff' => [ 'audio/x-aiff', 'audio/aiff', ], 'aifc' => 'audio/x-aiff', 'ram' => 'audio/x-pn-realaudio', 'rm' => 'audio/x-pn-realaudio', 'rpm' => 'audio/x-pn-realaudio-plugin', 'ra' => 'audio/x-realaudio', 'rv' => 'video/vnd.rn-realvideo', 'wav' => [ 'audio/x-wav', 'audio/wave', 'audio/wav', ], 'bmp' => [ 'image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap', ], 'gif' => 'image/gif', 'jpg' => [ 'image/jpeg', 'image/pjpeg', ], 'jpeg' => [ 'image/jpeg', 'image/pjpeg', ], 'jpe' => [ 'image/jpeg', 'image/pjpeg', ], 'jp2' => [ 'image/jp2', 'video/mj2', 'image/jpx', 'image/jpm', ], 'j2k' => [ 'image/jp2', 'video/mj2', 'image/jpx', 'image/jpm', ], 'jpf' => [ 'image/jp2', 'video/mj2', 'image/jpx', 'image/jpm', ], 'jpg2' => [ 'image/jp2', 'video/mj2', 'image/jpx', 'image/jpm', ], 'jpx' => [ 'image/jp2', 'video/mj2', 'image/jpx', 'image/jpm', ], 'jpm' => [ 'image/jp2', 'video/mj2', 'image/jpx', 'image/jpm', ], 'mj2' => [ 'image/jp2', 'video/mj2', 'image/jpx', 'image/jpm', ], 'mjp2' => [ 'image/jp2', 'video/mj2', 'image/jpx', 'image/jpm', ], 'png' => [ 'image/png', 'image/x-png', ], 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'css' => [ 'text/css', 'text/plain', ], 'html' => [ 'text/html', 'text/plain', ], 'htm' => [ 'text/html', 'text/plain', ], 'shtml' => [ 'text/html', 'text/plain', ], 'txt' => 'text/plain', 'text' => 'text/plain', 'log' => [ 'text/plain', 'text/x-log', ], 'rtx' => 'text/richtext', 'rtf' => 'text/rtf', 'xml' => [ 'application/xml', 'text/xml', 'text/plain', ], 'xsl' => [ 'application/xml', 'text/xsl', 'text/xml', ], 'mpeg' => 'video/mpeg', 'mpg' => 'video/mpeg', 'mpe' => 'video/mpeg', 'qt' => 'video/quicktime', 'mov' => 'video/quicktime', 'avi' => [ 'video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo', ], 'movie' => 'video/x-sgi-movie', 'doc' => [ 'application/msword', 'application/vnd.ms-office', ], 'docx' => [ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip', ], 'dot' => [ 'application/msword', 'application/vnd.ms-office', ], 'dotx' => [ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', ], 'xlsx' => [ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip', ], 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', 'word' => [ 'application/msword', 'application/octet-stream', ], 'xl' => 'application/excel', 'eml' => 'message/rfc822', 'json' => [ 'application/json', 'text/json', ], 'pem' => [ 'application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream', ], 'p10' => [ 'application/x-pkcs10', 'application/pkcs10', ], 'p12' => 'application/x-pkcs12', 'p7a' => 'application/x-pkcs7-signature', 'p7c' => [ 'application/pkcs7-mime', 'application/x-pkcs7-mime', ], 'p7m' => [ 'application/pkcs7-mime', 'application/x-pkcs7-mime', ], 'p7r' => 'application/x-pkcs7-certreqresp', 'p7s' => 'application/pkcs7-signature', 'crt' => [ 'application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert', ], 'crl' => [ 'application/pkix-crl', 'application/pkcs-crl', ], 'der' => 'application/x-x509-ca-cert', 'kdb' => 'application/octet-stream', 'pgp' => 'application/pgp', 'gpg' => 'application/gpg-keys', 'sst' => 'application/octet-stream', 'csr' => 'application/octet-stream', 'rsa' => 'application/x-pkcs7', 'cer' => [ 'application/pkix-cert', 'application/x-x509-ca-cert', ], '3g2' => 'video/3gpp2', '3gp' => [ 'video/3gp', 'video/3gpp', ], 'mp4' => 'video/mp4', 'm4a' => 'audio/x-m4a', 'f4v' => [ 'video/mp4', 'video/x-f4v', ], 'flv' => 'video/x-flv', 'webm' => 'video/webm', 'aac' => 'audio/x-acc', 'm4u' => 'application/vnd.mpegurl', 'm3u' => 'text/plain', 'xspf' => 'application/xspf+xml', 'vlc' => 'application/videolan', 'wmv' => [ 'video/x-ms-wmv', 'video/x-ms-asf', ], 'au' => 'audio/x-au', 'ac3' => 'audio/ac3', 'flac' => 'audio/x-flac', 'ogg' => [ 'audio/ogg', 'video/ogg', 'application/ogg', ], 'kmz' => [ 'application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip', ], 'kml' => [ 'application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml', ], 'ics' => 'text/calendar', 'ical' => 'text/calendar', 'zsh' => 'text/x-scriptzsh', '7zip' => [ 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip', ], 'cdr' => [ 'application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr', ], 'wma' => [ 'audio/x-ms-wma', 'video/x-ms-asf', ], 'jar' => [ 'application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed', ], 'svg' => [ 'image/svg+xml', 'image/svg', 'application/xml', 'text/xml', ], 'vcf' => 'text/x-vcard', 'srt' => [ 'text/srt', 'text/plain', ], 'vtt' => [ 'text/vtt', 'text/plain', ], 'ico' => [ 'image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon', ], 'stl' => [ 'application/sla', 'application/vnd.ms-pki.stl', 'application/x-navistyle', ], ]; /** * Attempts to determine the best mime type for the given file extension. * * @param string $extension * * @return string|null The mime type found, or none if unable to determine. */ public static function getTypesFromExtension($extension) { $extension = trim(strtolower($extension), '. '); if (!array_key_exists($extension, static::$mimes)) { return null; } return (array) static::$mimes[$extension]; } /** * Attempts to determine the best file extension for a given mime type. * * @param string $type * @param string|null $proposedExtension - default extension (in case there is more than one with the same mime type) * * @return string|null The extension determined, or null if unable to match. */ public static function guessExtensionFromType($type, $proposedExtension = null) { $type = trim(strtolower($type), '. '); $proposedExtension = trim(strtolower($proposedExtension)); if ($proposedExtension !== '') { if (array_key_exists($proposedExtension, static::$mimes) && in_array($type, is_string(static::$mimes[$proposedExtension]) ? [static::$mimes[$proposedExtension]] : static::$mimes[$proposedExtension], true)) { // The detected mime type matches with the proposed extension. return $proposedExtension; } // An extension was proposed, but the media type does not match the mime type list. return null; } // Reverse check the mime type list if no extension was proposed. // This search is order sensitive! foreach (static::$mimes as $ext => $types) { if ((is_string($types) && $types === $type) || (is_array($types) && in_array($type, $types, true))) { return $ext; } } return null; } /** * Test whether the given mime type is in the allowed file types. * * @param mixed $allowed_types Can be a list of comma separated types or an array of types. Types can be either an extension (.jpg) or a mime type (application/zip) * @param string $mime The mime type to check * * @return mixed Null on failure, true on success */ public static function check($allowed_types, $detected_mime) { if (!$allowed_types || !$detected_mime) { return false; } $allowed_types = self::toSafeArray($allowed_types); foreach ($allowed_types as $allowed_type) { // Check whether we have a mime type or a file extension. A Mime type is supposed to have a forward slash character. // If we have a file extension (.jpg, .zip), convert it to a Mime type. $allowed_mime_types = strpos($allowed_type, '/') === false ? self::getTypesFromExtension($allowed_type) : $allowed_type; if (self::typeIsInTypes($detected_mime, $allowed_mime_types)) { return true; } } } /** * Test whether the given detected mime type is in allowed mime types * * @param string $detected_type The mime type to check Eg: application/zip * @param array $allowed_types A list of allowed mime types Eg: ['application/zip', 'images/jpg'] * * @return bool True on success */ public static function typeIsInTypes($detected_type, $allowed_types) { if (!$detected_type || !$allowed_types) { return; } $allowed_types = self::toSafeArray($allowed_types); $detected_type = strtolower($detected_type); foreach ($allowed_types as $allowed_type) { // Special case: Allow to use wildcard in mime types like: image/* - This requires to convert the asterisk character to regex pattern. $allowed_type = str_replace('*', '.*', $allowed_type); if (preg_match('#' . $allowed_type . '#', $detected_type)) { return true; } } } /** * Detect the filename's Mime type * * @param string $file The path to the file to be checked * * @return mixed the mime type detected false on error */ public static function detectFileType($file) { // If we can't detect anything mime is false $mime = false; try { if (function_exists('mime_content_type')) { $mime = mime_content_type($file); } elseif (function_exists('finfo_open')) { $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $file); finfo_close($finfo); } } catch (\Exception $e) { } return $mime; } private static function toSafeArray($subject) { if (!is_array($subject)) { $subject = explode(',', $subject); } $subject = array_map('trim', $subject); $subject = array_map('strtolower', $subject); $subject = array_unique($subject); $subject = array_filter($subject); return $subject; } }PK! )Q Q &system/nrframework/NRFramework/URL.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; use NRFramework\Factory; defined('_JEXEC') or die('Restricted access'); class URL { /** * Class constructor */ public function __construct($path, $factory = null) { $this->path = trim($path); $this->factory = $factory ? $factory : new Factory(); } public function getInstance() { return clone \JUri::getInstance($this->path); } public function getDomainName() { return strtolower(str_ireplace('www.', '', $this->getInstance()->getHost())); } public function isAbsolute() { return !is_null($this->getInstance()->getScheme()); } public function isInternal() { if (!$this->path) { return false; } $host = $this->getInstance()->getHost(); if (is_null($host)) { return true; } $siteHost = $this->factory->getURI()->getHost(); return preg_match('#' . preg_quote($siteHost, '#') . '#', $host) ? true : false; } /** * Transform a relative path to absolute URL * * @return string */ public function toAbsolute() { if (empty($this->path)) { return; } // Check if it's already absolute URL if ($this->isAbsolute()) { return $this->path; } $basePath = \parse_url(\JURI::root()); $parse_path = $this->getInstance(); $parse_path->setScheme($basePath['scheme']); $parse_path->setHost($basePath['host']); $parse_path->setPath($basePath['path'] . $parse_path->getPath()); return $parse_path->toString(); } /** * CDNify a resource * * @param string $host The hostname of the CDN to be used * @param string $scheme * * @return string */ public function cdnify($host, $scheme = 'https') { // Allow only internal URLs if (!$this->isInternal()) { return $this->path; } // Allow only resource files $path = $this->getInstance()->getPath(); if (strpos($path, '.') === false) { return $this->path; } return $this->setHost($host, $scheme); } public function setHost($domain, $scheme = 'https') { if (empty($this->path)) { return; } $url_new = $this->getInstance(); $url_new->setScheme($scheme); $url_new->setHost($domain); // Path should always start with a slash if ($url_new->getPath()) { $url_new->setPath('/' . ltrim($url_new->getPath(), '/')); } $result = $url_new->toString(); if ($scheme == '//') { $result = str_replace('://', '', $result); } return $result; } }PK!nY.Y..system/nrframework/NRFramework/Assignments.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; use NRFramework\Factory; use NRFramework\Conditions\ConditionsHelper; defined('_JEXEC') or die; // @deprecated - Use \NRFramework\Condnitions\ConditionsHelper; class Assignments { /** * Assignment Type Aliases * * @var array * * @deprecated To be removed on Jan 1st 2023. */ public $typeAliases = array( 'device|devices' => 'Device', 'urls|url' => 'URL', 'os' => 'OS', 'browsers|browser' => 'Browser', 'referrer' => 'Referrer', 'php' => 'PHP', 'timeonsite' => 'TimeOnSite', 'pageviews|user_pageviews' => 'Pageviews', 'lang|language|languages' => 'Joomla\Language', 'usergroups|usergroup|user_groups' => 'Joomla\UserGroup', 'user_id|userid' => 'Joomla\UserID', 'menu' => 'Joomla\Menu', 'components|component' => 'Joomla\Component', 'datetime|daterange|date' => 'Date\Date', 'weekday|days|day' => 'Date\Day', 'months|month' => 'Date\Month', 'timerange|time' => 'Date\Time', 'acymailing' => 'AcyMailing', 'akeebasubs' => 'AkeebaSubs', 'engagebox|onotherbox' => 'EngageBox', 'convertforms' => 'ConvertForms', 'geo_country|country|countries' => 'Geo\Country', 'geo_continent|continent|continents' => 'Geo\Continent', 'geo_city|city|cities' => 'Geo\City', 'geo_region|region|regions' => 'Geo\Region', 'cookiename|cookie' => 'Cookie', 'ip_addresses|iprange|ip' => 'IP', 'k2_items|k2item' => 'Component\K2Item', 'k2_cats|k2category' => 'Component\K2Category', 'k2_tags|k2tag' => 'Component\K2Tag', 'k2_pagetypes|k2pagetype' => 'Component\K2Pagetype', 'contentcats|category' => 'Component\ContentCategory', 'contentarticles|article' => 'Component\ContentArticle', 'contentview' => 'Component\ContentView', 'eventbookingsingle' => 'Component\EventBookingSingle', 'eventbookingcategory' => 'Component\EventBookingCategory', 'j2storesingle' => 'Component\J2StoreSingle', 'j2storecategory' => 'Component\J2StoreCategory', 'hikashopsingle' => 'Component\HikashopSingle', 'hikashopcategory' => 'Component\HikashopCategory', 'sppagebuildersingle' => 'Component\SPPageBuilderSingle', 'sppagebuildercategory' => 'Component\SPPageBuilderCategory', 'virtuemartcategory' => 'Component\VirtueMartCategory', 'virtuemartsingle' => 'Component\VirtueMartSingle', 'jshoppingsingle' => 'Component\JShoppingSingle', 'jshoppingcategory' => 'Component\JShoppingCategory', 'rsblogsingle' => 'Component\RSBlogSingle', 'rsblogcategory' => 'Component\RSBlogCategory', 'easyblogcategory' => 'Component\EasyBlogCategory', 'easyblogsingle' => 'Component\EasyBlogSingle', 'zoosingle' => 'Component\ZooSingle', 'zoocategory' => 'Component\ZooCategory', 'eshopcategory' => 'Component\EshopCategory', 'eshopsingle' => 'Component\EshopSingle', 'djcatalog2category' => 'Component\DJCatalog2Category', 'djcatalog2single' => 'Component\DJCatalog2Single', 'quixsingle' => 'Component\QuixSingle', 'djclassifiedssingle' => 'Component\DJClassifiedsSingle', 'djclassifiedscategory' => 'Component\DJClassifiedsCategory', 'sobiprocategory' => 'Component\SobiProCategory', 'sobiprosingle' => 'Component\SobiProSingle', 'gridboxcategory' => 'Component\GridboxCategory', 'gridboxsingle' => 'Component\GridboxSingle', 'djeventscategory' => 'Component\DJEventsCategory', 'djeventssingle' => 'Component\DJEventsSingle', 'jcalprocategory' => 'Component\JCalProCategory', 'jcalprosingle' => 'Component\JCalProSingle', 'jbusinessdirectorybusinesscategory' => 'Component\JBusinessDirectoryBusinessCategory', 'jbusinessdirectorybusinesssingle' => 'Component\JBusinessDirectoryBusinessSingle', 'jbusinessdirectoryeventcategory' => 'Component\JBusinessDirectoryEventCategory', 'jbusinessdirectoryeventsingle' => 'Component\JBusinessDirectoryEventSingle', 'jbusinessdirectoryoffercategory' => 'Component\JBusinessDirectoryOfferCategory', 'jbusinessdirectoryoffersingle' => 'Component\JBusinessDirectoryOfferSingle' ); /** * Factory object * * @var \NRFramework\Factory */ protected $factory; /** * Class constructor */ public function __construct($factory = null) { $this->factory = is_null($factory) ? new Factory() : $factory; } /** * Legacy method to check a set of rules. * * At the moment of writing this and the moment we're going to release a new version for EngageBox * which is going to introduce the new ConditionBuilder field, ACF and GSD will still be using the passAll() method. * * This forces us to keep this method for backwards compatibiliy reasons. * Additionally, it helps us to catch a special case where both ACF and GSD expect to pass all rules even if the array passed is null. * * @param array|object $assignments_info Array/Object containing assignment info * @param string $match_method The matching method (and|or) - Deprecated * @param bool $debug Set to true to request additional debug information about assignments * * @deprecated Use passSets() instead. To be removed on Jan 1st 2023 */ public function passAll($assignments_info, $match_method = 'and') { $assignments = $this->prepareAssignments($assignments_info, $match_method); $ch = new ConditionsHelper($this->factory); $pass = $ch->passSets($assignments); // If the checks return null, consider this as Success. This is required for both ACF and GSD. return is_null($pass) ? true : $pass; } /** * Returns the classname for a given assignment alias * * @param string $alias * @return string|void * * @deprecated To be removed on Jan 1st 2023 */ public function aliasToClassname($alias) { $alias = strtolower($alias); foreach ($this->typeAliases as $aliases => $type) { if (strtolower($type) == $alias) { return $type; } $aliases = explode('|', strtolower($aliases)); if (in_array($alias, $aliases)) { return $type; } } return null; } /** * Checks and prepares the given array of assignment information * * @param array $assignments_info * @return array * * @deprecated To be removed on Jan 1st 2023 */ protected function prepareAssignments($data, $matching_method = 'all') { if (is_object($data)) { return $this->prepareAssignmentsFromObject($data, $matching_method); } if (!is_array($data) OR empty($data)) { return; } $rules = array_pop($data); if (!is_array($rules) OR empty($rules)) { return; } foreach ($rules as &$rule) { if (is_array($rule)) { foreach ($rule as &$_rule) { $_rule = $this->prepareAssignmentRule($_rule); } } else { $rule = $this->prepareAssignmentRule($rule); } } $data = [ [ 'matching_method' => $matching_method == 'and' ? 'all' : 'any', 'rules' => $rules ] ]; return $data; } /** * Prepares the assignment rule. * * @param object $rule * * @return object */ private function prepareAssignmentRule($rule) { return [ 'name' => $this->aliasToClassname($rule->alias), 'operator' => (int) $rule->assignment_state == 1 ? 'includes' : 'not_includes', 'value' => isset($rule->value) ? $rule->value : null, 'params' => isset($rule->params) ? $rule->params : null, ]; } /** * Converts an object of assignment information to an array of groups * Used by existing extensions * * @param object $assignments_info * @param string $matching_method * * @deprecated To be removed on Jan 1st 2023 */ public function prepareAssignmentsFromObject($assignments_info, $matching_method) { if (!isset($assignments_info->params)) { return []; } $params = json_decode($assignments_info->params); if (!is_object($params)) { return []; } $assignments_info = []; foreach ($this->typeAliases as $aliases => $type) { $aliases = explode('|', $aliases); foreach ($aliases as $alias) { if (!isset($params->{'assign_' . $alias}) || !$params->{'assign_' . $alias}) { continue; } // Discover assignment params $assignment_params = new \stdClass(); foreach ($params as $key => $value) { if (strpos($key, "assign_" . $alias . "_param") !== false) { $key = str_replace("assign_" . $alias . "_param_", "", $key); $assignment_params->$key = $value; } } $assignments_info[] = [ 'name' => $this->aliasToClassname($alias), 'operator' => (int) $params->{'assign_' . $alias} == 1 ? 'includes' : 'not_includes', 'value' => isset($params->{'assign_' . $alias . '_list'}) ? $params->{'assign_' . $alias . '_list'} : [], 'params' => $assignment_params ]; } } $data = [ [ 'matching_method' => $matching_method == 'and' ? 'all' : 'any', 'rules' => $assignments_info ] ]; return $data; } }PK!7 /system/nrframework/NRFramework/VisitorToken.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined('_JEXEC') or die('Restricted access'); class VisitorToken { /** * Class instance * * @var object */ private static $instance; /** * Cookie Name * * @var string */ private $cookieName = "nrid"; /** * Represents the maximum age of the visitor's cookie in seconds. * * @var Integer */ private $expire = 90000000; /** * Cookies Object * * @var object */ private $cookies; /** * Class constructor */ private function __construct() { $this->cookies = \JFactory::getApplication()->input->cookie; $token = $this->cookies->get($this->cookieName, null); if ($token === null) { $this->store($this->create()); } } /** * Returns class instance * * @return object */ public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } /** * Get a visitor's unique token id, if a token isn't set yet one will be generated. * * @param boolean $forceNew If true, force a new token to be created * * @return string The session token */ public function get($forceNew = false) { return $this->cookies->get($this->cookieName); } /** * Create a token-string * * @param integer $length Length of string * * @return string Generated token */ private function create($length = 8) { return bin2hex(\JCrypt::genRandomBytes($length)); } /** * Saves the cookie to the visitor's browser * * @param string $value Cookie Value * * @return void */ private function store($value) { $this->cookies->set($this->cookieName, $value, time() + $this->expire, '/', '', true); } }PK! * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined('_JEXEC') or die('Restricted access'); /** * Helper class to work with country names/codes */ class Countries { /** * Countries List * * @deprecated: Use getCountriesData(); * * @const array */ public static $map = [ 'AF' => "Afghanistan", 'AX' => "Aland Islands", 'AL' => "Albania", 'DZ' => "Algeria", 'AS' => "American Samoa", 'AD' => "Andorra", 'AO' => "Angola", 'AI' => "Anguilla", 'AQ' => "Antarctica", 'AG' => "Antigua and Barbuda", 'AR' => "Argentina", 'AM' => "Armenia", 'AW' => "Aruba", 'AU' => "Australia", 'AT' => "Austria", 'AZ' => "Azerbaijan", 'BS' => "Bahamas", 'BH' => "Bahrain", 'BD' => "Bangladesh", 'BB' => "Barbados", 'BY' => "Belarus", 'BE' => "Belgium", 'BZ' => "Belize", 'BJ' => "Benin", 'BM' => "Bermuda", 'BQ-BO' => "Bonaire", 'BQ-SA' => "Saba", 'BQ-SE' => "Sint Eustatius", 'BT' => "Bhutan", 'BO' => "Bolivia", 'BA' => "Bosnia and Herzegovina", 'BW' => "Botswana", 'BV' => "Bouvet Island", 'BR' => "Brazil", 'IO' => "British Indian Ocean Territory", 'BN' => "Brunei Darussalam", 'BG' => "Bulgaria", 'BF' => "Burkina Faso", 'BI' => "Burundi", 'KH' => "Cambodia", 'CM' => "Cameroon", 'CA' => "Canada", 'CV' => "Cape Verde", 'KY' => "Cayman Islands", 'CF' => "Central African Republic", 'TD' => "Chad", 'CL' => "Chile", 'CN' => "China", 'CX' => "Christmas Island", 'CC' => "Cocos (Keeling) Islands", 'CO' => "Colombia", 'KM' => "Comoros", 'CG' => "Congo", 'CD' => "Congo, The Democratic Republic of the", 'CK' => "Cook Islands", 'CR' => "Costa Rica", 'CI' => "Cote d'Ivoire", 'HR' => "Croatia", 'CU' => "Cuba", 'CW' => "Curaçao", 'CY' => "Cyprus", 'CZ' => "Czech Republic", 'DK' => "Denmark", 'DJ' => "Djibouti", 'DM' => "Dominica", 'DO' => "Dominican Republic", 'EC' => "Ecuador", 'EG' => "Egypt", 'SV' => "El Salvador", 'GQ' => "Equatorial Guinea", 'ER' => "Eritrea", 'EE' => "Estonia", 'ET' => "Ethiopia", 'FK' => "Falkland Islands (Malvinas)", 'FO' => "Faroe Islands", 'FJ' => "Fiji", 'FI' => "Finland", 'FR' => "France", 'GF' => "French Guiana", 'PF' => "French Polynesia", 'TF' => "French Southern Territories", 'GA' => "Gabon", 'GM' => "Gambia", 'GE' => "Georgia", 'DE' => "Germany", 'GH' => "Ghana", 'GI' => "Gibraltar", 'GR' => "Greece", 'GL' => "Greenland", 'GD' => "Grenada", 'GP' => "Guadeloupe", 'GU' => "Guam", 'GT' => "Guatemala", 'GG' => "Guernsey", 'GN' => "Guinea", 'GW' => "Guinea-Bissau", 'GY' => "Guyana", 'HT' => "Haiti", 'HM' => "Heard Island and McDonald Islands", 'VA' => "Holy See (Vatican City State)", 'HN' => "Honduras", 'HK' => "Hong Kong", 'HU' => "Hungary", 'IS' => "Iceland", 'IN' => "India", 'ID' => "Indonesia", 'IR' => "Iran, Islamic Republic of", 'IQ' => "Iraq", 'IE' => "Ireland", 'IM' => "Isle of Man", 'IL' => "Israel", 'IT' => "Italy", 'JM' => "Jamaica", 'JP' => "Japan", 'JE' => "Jersey", 'JO' => "Jordan", 'KZ' => "Kazakhstan", 'KE' => "Kenya", 'KI' => "Kiribati", 'KP' => "Korea, Democratic People's Republic of", 'KR' => "Korea, Republic of", 'KW' => "Kuwait", 'KG' => "Kyrgyzstan", 'LA' => "Lao People's Democratic Republic", 'LV' => "Latvia", 'LB' => "Lebanon", 'LS' => "Lesotho", 'LR' => "Liberia", 'LY' => "Libyan Arab Jamahiriya", 'LI' => "Liechtenstein", 'LT' => "Lithuania", 'LU' => "Luxembourg", 'MO' => "Macao", 'MK' => "Macedonia", 'MG' => "Madagascar", 'MW' => "Malawi", 'MY' => "Malaysia", 'MV' => "Maldives", 'ML' => "Mali", 'MT' => "Malta", 'MH' => "Marshall Islands", 'MQ' => "Martinique", 'MR' => "Mauritania", 'MU' => "Mauritius", 'YT' => "Mayotte", 'MX' => "Mexico", 'FM' => "Micronesia, Federated States of", 'MD' => "Moldova, Republic of", 'MC' => "Monaco", 'MN' => "Mongolia", 'ME' => "Montenegro", 'MS' => "Montserrat", 'MA' => "Morocco", 'MZ' => "Mozambique", 'MM' => "Myanmar", 'NA' => "Namibia", 'NR' => "Nauru", 'NP' => "Nepal", 'NL' => "Netherlands", 'AN' => "Netherlands Antilles", 'NC' => "New Caledonia", 'NZ' => "New Zealand", 'NI' => "Nicaragua", 'NE' => "Niger", 'NG' => "Nigeria", 'NU' => "Niue", 'NF' => "Norfolk Island", 'NM' => "North Macedonia", 'MP' => "Northern Mariana Islands", 'NO' => "Norway", 'OM' => "Oman", 'PK' => "Pakistan", 'PW' => "Palau", 'PS' => "Palestinian Territory", 'PA' => "Panama", 'PG' => "Papua New Guinea", 'PY' => "Paraguay", 'PE' => "Peru", 'PH' => "Philippines", 'PN' => "Pitcairn", 'PL' => "Poland", 'PT' => "Portugal", 'PR' => "Puerto Rico", 'QA' => "Qatar", 'RE' => "Reunion", 'RO' => "Romania", 'RU' => "Russian Federation", 'RW' => "Rwanda", 'SH' => "Saint Helena", 'KN' => "Saint Kitts and Nevis", 'LC' => "Saint Lucia", 'PM' => "Saint Pierre and Miquelon", 'VC' => "Saint Vincent and the Grenadines", 'WS' => "Samoa", 'SM' => "San Marino", 'ST' => "Sao Tome and Principe", 'SA' => "Saudi Arabia", 'SN' => "Senegal", 'RS' => "Serbia", 'SC' => "Seychelles", 'SL' => "Sierra Leone", 'SG' => "Singapore", 'SK' => "Slovakia", 'SI' => "Slovenia", 'SB' => "Solomon Islands", 'SO' => "Somalia", 'ZA' => "South Africa", 'GS' => "South Georgia and the South Sandwich Islands", 'ES' => "Spain", 'LK' => "Sri Lanka", 'SD' => "Sudan", 'SS' => "South Sudan", 'SR' => "Suriname", 'SJ' => "Svalbard and Jan Mayen", 'SZ' => "Swaziland", 'SE' => "Sweden", 'CH' => "Switzerland", 'SY' => "Syrian Arab Republic", 'TW' => "Taiwan", 'TJ' => "Tajikistan", 'TZ' => "Tanzania, United Republic of", 'TH' => "Thailand", 'TL' => "Timor-Leste", 'TG' => "Togo", 'TK' => "Tokelau", 'TO' => "Tonga", 'TT' => "Trinidad and Tobago", 'TN' => "Tunisia", 'TR' => "Turkey", 'TM' => "Turkmenistan", 'TC' => "Turks and Caicos Islands", 'TV' => "Tuvalu", 'UG' => "Uganda", 'UA' => "Ukraine", 'AE' => "United Arab Emirates", 'GB' => "United Kingdom", 'US' => "United States", 'UM' => "United States Minor Outlying Islands", 'UY' => "Uruguay", 'UZ' => "Uzbekistan", 'VU' => "Vanuatu", 'VE' => "Venezuela", 'VN' => "Vietnam", 'VG' => "Virgin Islands, British", 'VI' => "Virgin Islands, U.S.", 'WF' => "Wallis and Futuna", 'EH' => "Western Sahara", 'YE' => "Yemen", 'ZM' => "Zambia", 'ZW' => "Zimbabwe", ]; /** * Get information for given country * * @param string $countryCode * * @return array An assosiative array with country information */ public static function getCountry($countryCode) { $countries = self::getCountriesData(); $countryCode = \strtoupper($countryCode); if (!isset($countries[$countryCode])) { return; } return $countries[$countryCode]; } /** * Return a country code from it's name * * @param string $country * @return string|void */ public static function getCode($country) { $country = \ucwords(strtolower($country)); foreach (self::getCountriesList() as $key => $value) { if (strpos($value, $country) !== false) { return $key; } } return null; } /** * Returns translatable countries list * * @return array */ public static function getCountriesList() { $countries = []; foreach (self::getCountriesData() as $key => $country) { $countries[$key] = $country['name']; } return $countries; } /** * Holds the following data for each country: * - Name * - Code * - Calling Code * - Currency Code * - Curency Name * - Currency Symbol * * @return array */ public static function getCountriesData() { return [ 'AF' => [ 'name' => \JText::_('NR_COUNTRY_AF'), 'calling_code' => '93', 'currency_code' => 'AFN', 'currency_name' => 'Afghan Afghani', 'currency_symbol' => '؋' ], 'AX' => [ 'name' => \JText::_('NR_COUNTRY_AX'), 'calling_code' => '35818', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'AL' => [ 'name' => \JText::_('NR_COUNTRY_AL'), 'calling_code' => '355', 'currency_code' => 'ALL', 'currency_name' => 'Lek', 'currency_symbol' => 'Lek' ], 'DZ' => [ 'name' => \JText::_('NR_COUNTRY_DZ'), 'calling_code' => '213', 'currency_code' => 'DZD', 'currency_name' => 'Dinar', 'currency_symbol' => 'دج' ], 'AS' => [ 'name' => \JText::_('NR_COUNTRY_AS'), 'calling_code' => '1684', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'AD' => [ 'name' => \JText::_('NR_COUNTRY_AD'), 'calling_code' => '376', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'AO' => [ 'name' => \JText::_('NR_COUNTRY_AO'), 'calling_code' => '244', 'currency_code' => 'AOA', 'currency_name' => 'Kwanza', 'currency_symbol' => 'Kz' ], 'AI' => [ 'name' => \JText::_('NR_COUNTRY_AI'), 'calling_code' => '1264', 'currency_code' => 'XCD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'AQ' => [ 'name' => \JText::_('NR_COUNTRY_AQ'), 'calling_code' => '672', 'currency_code' => '', 'currency_name' => '', 'currency_symbol' => '' ], 'AG' => [ 'name' => \JText::_('NR_COUNTRY_AG'), 'calling_code' => '1268', 'currency_code' => 'XCD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'AR' => [ 'name' => \JText::_('NR_COUNTRY_AR'), 'calling_code' => '54', 'currency_code' => 'ARS', 'currency_name' => 'Peso', 'currency_symbol' => '$' ], 'AM' => [ 'name' => \JText::_('NR_COUNTRY_AM'), 'calling_code' => '374', 'currency_code' => 'AMD', 'currency_name' => 'Dram', 'currency_symbol' => '֏' ], 'AW' => [ 'name' => \JText::_('NR_COUNTRY_AW'), 'calling_code' => '297', 'currency_code' => 'AWG', 'currency_name' => 'Guilder', 'currency_symbol' => 'ƒ' ], 'AU' => [ 'name' => \JText::_('NR_COUNTRY_AU'), 'calling_code' => '61', 'currency_code' => 'AUD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'AT' => [ 'name' => \JText::_('NR_COUNTRY_AT'), 'calling_code' => '43', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'AZ' => [ 'name' => \JText::_('NR_COUNTRY_AZ'), 'calling_code' => '994', 'currency_code' => 'AZN', 'currency_name' => 'Manat', 'currency_symbol' => 'ман' ], 'BS' => [ 'name' => \JText::_('NR_COUNTRY_BS'), 'calling_code' => '1242', 'currency_code' => 'BSD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'BH' => [ 'name' => \JText::_('NR_COUNTRY_BH'), 'calling_code' => '973', 'currency_code' => 'BHD', 'currency_name' => 'Dinar', 'currency_symbol' => 'د.ب' ], 'BD' => [ 'name' => \JText::_('NR_COUNTRY_BD'), 'calling_code' => '880', 'currency_code' => 'BDT', 'currency_name' => 'Taka', 'currency_symbol' => '৳' ], 'BB' => [ 'name' => \JText::_('NR_COUNTRY_BB'), 'calling_code' => '1246', 'currency_code' => 'BBD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'BY' => [ 'name' => \JText::_('NR_COUNTRY_BY'), 'calling_code' => '375', 'currency_code' => 'BYR', 'currency_name' => 'Ruble', 'currency_symbol' => 'p.' ], 'BE' => [ 'name' => \JText::_('NR_COUNTRY_BE'), 'calling_code' => '32', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'BZ' => [ 'name' => \JText::_('NR_COUNTRY_BZ'), 'calling_code' => '501', 'currency_code' => 'BZD', 'currency_name' => 'Dollar', 'currency_symbol' => 'BZ$' ], 'BJ' => [ 'name' => \JText::_('NR_COUNTRY_BJ'), 'calling_code' => '229', 'currency_code' => 'XOF', 'currency_name' => 'Franc', 'currency_symbol' => 'CFA' ], 'BM' => [ 'name' => \JText::_('NR_COUNTRY_BM'), 'calling_code' => '1441', 'currency_code' => 'BMD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'BQ-BO' => [ 'name' => \JText::_('NR_COUNTRY_BQ_BO'), 'calling_code' => '599-7', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'BQ-SA' => [ 'name' => \JText::_('NR_COUNTRY_BQ_SA'), 'calling_code' => '599-4', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'BQ-SE' => [ 'name' => \JText::_('NR_COUNTRY_BQ_SE'), 'calling_code' => '599-3', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'BT' => [ 'name' => \JText::_('NR_COUNTRY_BT'), 'calling_code' => '975', 'currency_code' => 'BTN', 'currency_name' => 'Ngultrum', 'currency_symbol' => 'Nu.' ], 'BO' => [ 'name' => \JText::_('NR_COUNTRY_BO'), 'calling_code' => '591', 'currency_code' => 'BOB', 'currency_name' => 'Boliviano', 'currency_symbol' => '$b' ], 'BA' => [ 'name' => \JText::_('NR_COUNTRY_BA'), 'calling_code' => '387', 'currency_code' => 'BAM', 'currency_name' => 'Marka', 'currency_symbol' => 'KM' ], 'BW' => [ 'name' => \JText::_('NR_COUNTRY_BW'), 'calling_code' => '267', 'currency_code' => 'BWP', 'currency_name' => 'Pula', 'currency_symbol' => 'P' ], 'BV' => [ 'name' => \JText::_('NR_COUNTRY_BV'), 'calling_code' => '', 'currency_code' => 'NOK', 'currency_name' => 'Krone', 'currency_symbol' => 'kr' ], 'BR' => [ 'name' => \JText::_('NR_COUNTRY_BR'), 'calling_code' => '55', 'currency_code' => 'BRL', 'currency_name' => 'Real', 'currency_symbol' => 'R$' ], 'IO' => [ 'name' => \JText::_('NR_COUNTRY_IO'), 'calling_code' => '', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'VG' => [ 'name' => \JText::_('NR_COUNTRY_VG'), 'calling_code' => '1284', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'BN' => [ 'name' => \JText::_('NR_COUNTRY_BN'), 'calling_code' => '673', 'currency_code' => 'BND', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'BG' => [ 'name' => \JText::_('NR_COUNTRY_BG'), 'calling_code' => '359', 'currency_code' => 'BGN', 'currency_name' => 'Lev', 'currency_symbol' => 'лв' ], 'BF' => [ 'name' => \JText::_('NR_COUNTRY_BF'), 'calling_code' => '226', 'currency_code' => 'XOF', 'currency_name' => 'Franc', 'currency_symbol' => 'CFA' ], 'BI' => [ 'name' => \JText::_('NR_COUNTRY_BI'), 'calling_code' => '257', 'currency_code' => 'BIF', 'currency_name' => 'Franc', 'currency_symbol' => 'FBu' ], 'KH' => [ 'name' => \JText::_('NR_COUNTRY_KH'), 'calling_code' => '855', 'currency_code' => 'KHR', 'currency_name' => 'Riels', 'currency_symbol' => '៛' ], 'CM' => [ 'name' => \JText::_('NR_COUNTRY_CM'), 'calling_code' => '237', 'currency_code' => 'XAF', 'currency_name' => 'Franc', 'currency_symbol' => 'FCF' ], 'CA' => [ 'name' => \JText::_('NR_COUNTRY_CA'), 'calling_code' => '1', 'currency_code' => 'CAD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'CV' => [ 'name' => \JText::_('NR_COUNTRY_CV'), 'calling_code' => '238', 'currency_code' => 'CVE', 'currency_name' => 'Escudo', 'currency_symbol' => '$' ], 'KY' => [ 'name' => \JText::_('NR_COUNTRY_KY'), 'calling_code' => '1345', 'currency_code' => 'KYD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'CF' => [ 'name' => \JText::_('NR_COUNTRY_CF'), 'calling_code' => '236', 'currency_code' => 'XAF', 'currency_name' => 'Franc', 'currency_symbol' => 'FCF' ], 'TD' => [ 'name' => \JText::_('NR_COUNTRY_TD'), 'calling_code' => '235', 'currency_code' => 'XAF', 'currency_name' => 'Franc', 'currency_symbol' => 'FCFA' ], 'CL' => [ 'name' => \JText::_('NR_COUNTRY_CL'), 'calling_code' => '56', 'currency_code' => 'CLP', 'currency_name' => 'Peso', 'currency_symbol' => '$' ], 'CN' => [ 'name' => \JText::_('NR_COUNTRY_CN'), 'calling_code' => '86', 'currency_code' => 'CNY', 'currency_name' => 'YuanRenminbi', 'currency_symbol' => '¥' ], 'CX' => [ 'name' => \JText::_('NR_COUNTRY_CX'), 'calling_code' => '61', 'currency_code' => 'AUD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'CC' => [ 'name' => \JText::_('NR_COUNTRY_CC'), 'calling_code' => '61', 'currency_code' => 'AUD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'CO' => [ 'name' => \JText::_('NR_COUNTRY_CO'), 'calling_code' => '57', 'currency_code' => 'COP', 'currency_name' => 'Peso', 'currency_symbol' => '$' ], 'KM' => [ 'name' => \JText::_('NR_COUNTRY_KM'), 'calling_code' => '269', 'currency_code' => 'KMF', 'currency_name' => 'Franc', 'currency_symbol' => 'CF' ], 'CK' => [ 'name' => \JText::_('NR_COUNTRY_CK'), 'calling_code' => '682', 'currency_code' => 'NZD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'CR' => [ 'name' => \JText::_('NR_COUNTRY_CR'), 'calling_code' => '506', 'currency_code' => 'CRC', 'currency_name' => 'Colon', 'currency_symbol' => '₡' ], 'HR' => [ 'name' => \JText::_('NR_COUNTRY_HR'), 'calling_code' => '385', 'currency_code' => 'HRK', 'currency_name' => 'Kuna', 'currency_symbol' => 'kn' ], 'CU' => [ 'name' => \JText::_('NR_COUNTRY_CU'), 'calling_code' => '53', 'currency_code' => 'CUP', 'currency_name' => 'Peso', 'currency_symbol' => '₱' ], 'CW' => [ 'name' => \JText::_('NR_COUNTRY_CW'), 'calling_code' => '5999', 'currency_code' => 'ANG', 'currency_name' => 'Guilder', 'currency_symbol' => 'ƒ' ], 'CY' => [ 'name' => \JText::_('NR_COUNTRY_CY'), 'calling_code' => '357', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'CZ' => [ 'name' => \JText::_('NR_COUNTRY_CZ'), 'calling_code' => '420', 'currency_code' => 'CZK', 'currency_name' => 'Koruna', 'currency_symbol' => 'Kč' ], 'CD' => [ 'name' => \JText::_('NR_COUNTRY_CD'), 'calling_code' => '243', 'currency_code' => 'CDF', 'currency_name' => 'Franc', 'currency_symbol' => 'FC' ], 'DK' => [ 'name' => \JText::_('NR_COUNTRY_DK'), 'calling_code' => '45', 'currency_code' => 'DKK', 'currency_name' => 'Krone', 'currency_symbol' => 'kr' ], 'DJ' => [ 'name' => \JText::_('NR_COUNTRY_DJ'), 'calling_code' => '253', 'currency_code' => 'DJF', 'currency_name' => 'Franc', 'currency_symbol' => 'Fdj' ], 'DM' => [ 'name' => \JText::_('NR_COUNTRY_DM'), 'calling_code' => '1767', 'currency_code' => 'XCD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'DO' => [ 'name' => \JText::_('NR_COUNTRY_DO'), 'calling_code' => '1809', 'currency_code' => 'DOP', 'currency_name' => 'Peso', 'currency_symbol' => 'RD$' ], 'TL' => [ 'name' => \JText::_('NR_COUNTRY_TL'), 'calling_code' => '670', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'EC' => [ 'name' => \JText::_('NR_COUNTRY_EC'), 'calling_code' => '593', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'EG' => [ 'name' => \JText::_('NR_COUNTRY_EG'), 'calling_code' => '20', 'currency_code' => 'EGP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'SV' => [ 'name' => \JText::_('NR_COUNTRY_SV'), 'calling_code' => '503', 'currency_code' => 'SVC', 'currency_name' => 'Colone', 'currency_symbol' => '$' ], 'GQ' => [ 'name' => \JText::_('NR_COUNTRY_GQ'), 'calling_code' => '240', 'currency_code' => 'XAF', 'currency_name' => 'Franc', 'currency_symbol' => 'FCF' ], 'ER' => [ 'name' => \JText::_('NR_COUNTRY_ER'), 'calling_code' => '291', 'currency_code' => 'ERN', 'currency_name' => 'Nakfa', 'currency_symbol' => 'Nfk' ], 'EE' => [ 'name' => \JText::_('NR_COUNTRY_EE'), 'calling_code' => '372', 'currency_code' => 'EEK', 'currency_name' => 'Kroon', 'currency_symbol' => 'kr' ], 'ET' => [ 'name' => \JText::_('NR_COUNTRY_ET'), 'calling_code' => '251', 'currency_code' => 'ETB', 'currency_name' => 'Birr', 'currency_symbol' => 'Br' ], 'FK' => [ 'name' => \JText::_('NR_COUNTRY_FK'), 'calling_code' => '500', 'currency_code' => 'FKP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'FO' => [ 'name' => \JText::_('NR_COUNTRY_FO'), 'calling_code' => '298', 'currency_code' => 'DKK', 'currency_name' => 'Krone', 'currency_symbol' => 'kr' ], 'FJ' => [ 'name' => \JText::_('NR_COUNTRY_FJ'), 'calling_code' => '679', 'currency_code' => 'FJD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'FI' => [ 'name' => \JText::_('NR_COUNTRY_FI'), 'calling_code' => '358', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'FR' => [ 'name' => \JText::_('NR_COUNTRY_FR'), 'calling_code' => '33', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'GF' => [ 'name' => \JText::_('NR_COUNTRY_GF'), 'calling_code' => '594', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'PF' => [ 'name' => \JText::_('NR_COUNTRY_PF'), 'calling_code' => '689', 'currency_code' => 'XPF', 'currency_name' => 'Franc', 'currency_symbol' => 'F' ], 'TF' => [ 'name' => \JText::_('NR_COUNTRY_TF'), 'calling_code' => '262', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'GA' => [ 'name' => \JText::_('NR_COUNTRY_GA'), 'calling_code' => '241', 'currency_code' => 'XAF', 'currency_name' => 'Franc', 'currency_symbol' => 'FCF' ], 'GM' => [ 'name' => \JText::_('NR_COUNTRY_GM'), 'calling_code' => '220', 'currency_code' => 'GMD', 'currency_name' => 'Dalasi', 'currency_symbol' => 'D' ], 'GE' => [ 'name' => \JText::_('NR_COUNTRY_GE'), 'calling_code' => '995', 'currency_code' => 'GEL', 'currency_name' => 'Lari', 'currency_symbol' => '₾' ], 'DE' => [ 'name' => \JText::_('NR_COUNTRY_DE'), 'calling_code' => '49', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'GH' => [ 'name' => \JText::_('NR_COUNTRY_GH'), 'calling_code' => '233', 'currency_code' => 'GHC', 'currency_name' => 'Cedi', 'currency_symbol' => '¢' ], 'GI' => [ 'name' => \JText::_('NR_COUNTRY_GI'), 'calling_code' => '350', 'currency_code' => 'GIP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'GR' => [ 'name' => \JText::_('NR_COUNTRY_GR'), 'calling_code' => '30', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'GL' => [ 'name' => \JText::_('NR_COUNTRY_GL'), 'calling_code' => '299', 'currency_code' => 'DKK', 'currency_name' => 'Krone', 'currency_symbol' => 'kr' ], 'GD' => [ 'name' => \JText::_('NR_COUNTRY_GD'), 'calling_code' => '1473', 'currency_code' => 'XCD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'GP' => [ 'name' => \JText::_('NR_COUNTRY_GP'), 'calling_code' => '590', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'GU' => [ 'name' => \JText::_('NR_COUNTRY_GU'), 'calling_code' => '1671', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'GT' => [ 'name' => \JText::_('NR_COUNTRY_GT'), 'calling_code' => '502', 'currency_code' => 'GTQ', 'currency_name' => 'Quetzal', 'currency_symbol' => 'Q' ], 'GN' => [ 'name' => \JText::_('NR_COUNTRY_GN'), 'calling_code' => '224', 'currency_code' => 'GNF', 'currency_name' => 'Franc', 'currency_symbol' => 'FG' ], 'GW' => [ 'name' => \JText::_('NR_COUNTRY_GW'), 'calling_code' => '245', 'currency_code' => 'XOF', 'currency_name' => 'Franc', 'currency_symbol' => 'CFA' ], 'GY' => [ 'name' => \JText::_('NR_COUNTRY_GY'), 'calling_code' => '592', 'currency_code' => 'GYD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'HT' => [ 'name' => \JText::_('NR_COUNTRY_HT'), 'calling_code' => '509', 'currency_code' => 'HTG', 'currency_name' => 'Gourde', 'currency_symbol' => 'G' ], 'HM' => [ 'name' => \JText::_('NR_COUNTRY_HM'), 'calling_code' => '', 'currency_code' => 'AUD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'HN' => [ 'name' => \JText::_('NR_COUNTRY_HN'), 'calling_code' => '504', 'currency_code' => 'HNL', 'currency_name' => 'Lempira', 'currency_symbol' => 'L' ], 'HK' => [ 'name' => \JText::_('NR_COUNTRY_HK'), 'calling_code' => '852', 'currency_code' => 'HKD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'HU' => [ 'name' => \JText::_('NR_COUNTRY_HU'), 'calling_code' => '36', 'currency_code' => 'HUF', 'currency_name' => 'Forint', 'currency_symbol' => 'Ft' ], 'IS' => [ 'name' => \JText::_('NR_COUNTRY_IS'), 'calling_code' => '354', 'currency_code' => 'ISK', 'currency_name' => 'Krona', 'currency_symbol' => 'kr' ], 'IN' => [ 'name' => \JText::_('NR_COUNTRY_IN'), 'calling_code' => '91', 'currency_code' => 'INR', 'currency_name' => 'Rupee', 'currency_symbol' => '₹' ], 'ID' => [ 'name' => \JText::_('NR_COUNTRY_ID'), 'calling_code' => '62', 'currency_code' => 'IDR', 'currency_name' => 'Rupiah', 'currency_symbol' => 'Rp' ], 'IR' => [ 'name' => \JText::_('NR_COUNTRY_IR'), 'calling_code' => '98', 'currency_code' => 'IRR', 'currency_name' => 'Rial', 'currency_symbol' => '﷼' ], 'IQ' => [ 'name' => \JText::_('NR_COUNTRY_IQ'), 'calling_code' => '964', 'currency_code' => 'IQD', 'currency_name' => 'Dinar', 'currency_symbol' => 'د.ع' ], 'IE' => [ 'name' => \JText::_('NR_COUNTRY_IE'), 'calling_code' => '353', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'IM' => [ 'name' => \JText::_('NR_COUNTRY_IM'), 'calling_code' => '44', 'currency_code' => 'GBP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'IL' => [ 'name' => \JText::_('NR_COUNTRY_IL'), 'calling_code' => '972', 'currency_code' => 'ILS', 'currency_name' => 'Shekel', 'currency_symbol' => '₪' ], 'IT' => [ 'name' => \JText::_('NR_COUNTRY_IT'), 'calling_code' => '39', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'CI' => [ 'name' => \JText::_('NR_COUNTRY_CI'), 'calling_code' => '225', 'currency_code' => 'XOF', 'currency_name' => 'Franc', 'currency_symbol' => 'CFA' ], 'JM' => [ 'name' => \JText::_('NR_COUNTRY_JM'), 'calling_code' => '1876', 'currency_code' => 'JMD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'JP' => [ 'name' => \JText::_('NR_COUNTRY_JP'), 'calling_code' => '81', 'currency_code' => 'JPY', 'currency_name' => 'Yen', 'currency_symbol' => '¥' ], 'JO' => [ 'name' => \JText::_('NR_COUNTRY_JO'), 'calling_code' => '962', 'currency_code' => 'JOD', 'currency_name' => 'Dinar', 'currency_symbol' => 'د.أ' ], 'KZ' => [ 'name' => \JText::_('NR_COUNTRY_KZ'), 'calling_code' => '7', 'currency_code' => 'KZT', 'currency_name' => 'Tenge', 'currency_symbol' => 'лв' ], 'KE' => [ 'name' => \JText::_('NR_COUNTRY_KE'), 'calling_code' => '254', 'currency_code' => 'KES', 'currency_name' => 'Shilling', 'currency_symbol' => 'KSh' ], 'KI' => [ 'name' => \JText::_('NR_COUNTRY_KI'), 'calling_code' => '686', 'currency_code' => 'AUD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'KW' => [ 'name' => \JText::_('NR_COUNTRY_KW'), 'calling_code' => '965', 'currency_code' => 'KWD', 'currency_name' => 'Dinar', 'currency_symbol' => 'د.ك' ], 'KG' => [ 'name' => \JText::_('NR_COUNTRY_KG'), 'calling_code' => '996', 'currency_code' => 'KGS', 'currency_name' => 'Som', 'currency_symbol' => 'лв' ], 'LA' => [ 'name' => \JText::_('NR_COUNTRY_LA'), 'calling_code' => '856', 'currency_code' => 'LAK', 'currency_name' => 'Kip', 'currency_symbol' => '₭' ], 'LV' => [ 'name' => \JText::_('NR_COUNTRY_LV'), 'calling_code' => '371', 'currency_code' => 'LVL', 'currency_name' => 'Lat', 'currency_symbol' => 'Ls' ], 'LB' => [ 'name' => \JText::_('NR_COUNTRY_LB'), 'calling_code' => '961', 'currency_code' => 'LBP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'LS' => [ 'name' => \JText::_('NR_COUNTRY_LS'), 'calling_code' => '266', 'currency_code' => 'LSL', 'currency_name' => 'Loti', 'currency_symbol' => 'L' ], 'LR' => [ 'name' => \JText::_('NR_COUNTRY_LR'), 'calling_code' => '231', 'currency_code' => 'LRD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'LY' => [ 'name' => \JText::_('NR_COUNTRY_LY'), 'calling_code' => '218', 'currency_code' => 'LYD', 'currency_name' => 'Dinar', 'currency_symbol' => 'ل.د' ], 'LI' => [ 'name' => \JText::_('NR_COUNTRY_LI'), 'calling_code' => '423', 'currency_code' => 'CHF', 'currency_name' => 'Franc', 'currency_symbol' => 'CHF' ], 'LT' => [ 'name' => \JText::_('NR_COUNTRY_LT'), 'calling_code' => '370', 'currency_code' => 'LTL', 'currency_name' => 'Litas', 'currency_symbol' => 'Lt' ], 'LU' => [ 'name' => \JText::_('NR_COUNTRY_LU'), 'calling_code' => '352', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'MO' => [ 'name' => \JText::_('NR_COUNTRY_MO'), 'calling_code' => '853', 'currency_code' => 'MOP', 'currency_name' => 'Pataca', 'currency_symbol' => 'MOP' ], 'MK' => [ 'name' => \JText::_('NR_COUNTRY_MK'), 'calling_code' => '389', 'currency_code' => 'MKD', 'currency_name' => 'Denar', 'currency_symbol' => 'ден' ], 'MG' => [ 'name' => \JText::_('NR_COUNTRY_MG'), 'calling_code' => '261', 'currency_code' => 'MGA', 'currency_name' => 'Ariary', 'currency_symbol' => 'Ar' ], 'MW' => [ 'name' => \JText::_('NR_COUNTRY_MW'), 'calling_code' => '265', 'currency_code' => 'MWK', 'currency_name' => 'Kwacha', 'currency_symbol' => 'MK' ], 'MY' => [ 'name' => \JText::_('NR_COUNTRY_MY'), 'calling_code' => '60', 'currency_code' => 'MYR', 'currency_name' => 'Ringgit', 'currency_symbol' => 'RM' ], 'MV' => [ 'name' => \JText::_('NR_COUNTRY_MV'), 'calling_code' => '960', 'currency_code' => 'MVR', 'currency_name' => 'Rufiyaa', 'currency_symbol' => 'Rf' ], 'ML' => [ 'name' => \JText::_('NR_COUNTRY_ML'), 'calling_code' => '223', 'currency_code' => 'XOF', 'currency_name' => 'Franc', 'currency_symbol' => 'CFA' ], 'MT' => [ 'name' => \JText::_('NR_COUNTRY_MT'), 'calling_code' => '356', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'MH' => [ 'name' => \JText::_('NR_COUNTRY_MH'), 'calling_code' => '692', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'MQ' => [ 'name' => \JText::_('NR_COUNTRY_MQ'), 'calling_code' => '596', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'MR' => [ 'name' => \JText::_('NR_COUNTRY_MR'), 'calling_code' => '222', 'currency_code' => 'MRO', 'currency_name' => 'Ouguiya', 'currency_symbol' => 'UM' ], 'MU' => [ 'name' => \JText::_('NR_COUNTRY_MU'), 'calling_code' => '230', 'currency_code' => 'MUR', 'currency_name' => 'Rupee', 'currency_symbol' => '₨' ], 'YT' => [ 'name' => \JText::_('NR_COUNTRY_YT'), 'calling_code' => '262', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'MX' => [ 'name' => \JText::_('NR_COUNTRY_MX'), 'calling_code' => '52', 'currency_code' => 'MXN', 'currency_name' => 'Peso', 'currency_symbol' => '$' ], 'FM' => [ 'name' => \JText::_('NR_COUNTRY_FM'), 'calling_code' => '691', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'MD' => [ 'name' => \JText::_('NR_COUNTRY_MD'), 'calling_code' => '373', 'currency_code' => 'MDL', 'currency_name' => 'Leu', 'currency_symbol' => 'L' ], 'MC' => [ 'name' => \JText::_('NR_COUNTRY_MC'), 'calling_code' => '377', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'MN' => [ 'name' => \JText::_('NR_COUNTRY_MN'), 'calling_code' => '976', 'currency_code' => 'MNT', 'currency_name' => 'Tugrik', 'currency_symbol' => '₮' ], 'ME' => [ 'name' => \JText::_('NR_COUNTRY_ME'), 'calling_code' => '382', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'MS' => [ 'name' => \JText::_('NR_COUNTRY_MS'), 'calling_code' => '1664', 'currency_code' => 'XCD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'MA' => [ 'name' => \JText::_('NR_COUNTRY_MA'), 'calling_code' => '212', 'currency_code' => 'MAD', 'currency_name' => 'Dirham', 'currency_symbol' => 'DH' ], 'MZ' => [ 'name' => \JText::_('NR_COUNTRY_MZ'), 'calling_code' => '258', 'currency_code' => 'MZN', 'currency_name' => 'Meticail', 'currency_symbol' => 'MT' ], 'MM' => [ 'name' => \JText::_('NR_COUNTRY_MM'), 'calling_code' => '95', 'currency_code' => 'MMK', 'currency_name' => 'Kyat', 'currency_symbol' => 'K' ], 'NA' => [ 'name' => \JText::_('NR_COUNTRY_NA'), 'calling_code' => '264', 'currency_code' => 'NAD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'NR' => [ 'name' => \JText::_('NR_COUNTRY_NR'), 'calling_code' => '674', 'currency_code' => 'AUD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'NP' => [ 'name' => \JText::_('NR_COUNTRY_NP'), 'calling_code' => '977', 'currency_code' => 'NPR', 'currency_name' => 'Rupee', 'currency_symbol' => '₨' ], 'NL' => [ 'name' => \JText::_('NR_COUNTRY_NL'), 'calling_code' => '31', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'NC' => [ 'name' => \JText::_('NR_COUNTRY_NC'), 'calling_code' => '687', 'currency_code' => 'XPF', 'currency_name' => 'Franc', 'currency_symbol' => 'F' ], 'NZ' => [ 'name' => \JText::_('NR_COUNTRY_NZ'), 'calling_code' => '64', 'currency_code' => 'NZD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'NI' => [ 'name' => \JText::_('NR_COUNTRY_NI'), 'calling_code' => '505', 'currency_code' => 'NIO', 'currency_name' => 'Cordoba', 'currency_symbol' => 'C$' ], 'NE' => [ 'name' => \JText::_('NR_COUNTRY_NE'), 'calling_code' => '227', 'currency_code' => 'XOF', 'currency_name' => 'Franc', 'currency_symbol' => 'CFA' ], 'NG' => [ 'name' => \JText::_('NR_COUNTRY_NG'), 'calling_code' => '234', 'currency_code' => 'NGN', 'currency_name' => 'Naira', 'currency_symbol' => '₦' ], 'NU' => [ 'name' => \JText::_('NR_COUNTRY_NU'), 'calling_code' => '683', 'currency_code' => 'NZD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'NF' => [ 'name' => \JText::_('NR_COUNTRY_NF'), 'calling_code' => '672', 'currency_code' => 'AUD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'KP' => [ 'name' => \JText::_('NR_COUNTRY_KP'), 'calling_code' => '850', 'currency_code' => 'KPW', 'currency_name' => 'Won', 'currency_symbol' => '₩' ], 'MP' => [ 'name' => \JText::_('NR_COUNTRY_MP'), 'calling_code' => '1670', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'NO' => [ 'name' => \JText::_('NR_COUNTRY_NO'), 'calling_code' => '47', 'currency_code' => 'NOK', 'currency_name' => 'Krone', 'currency_symbol' => 'kr' ], 'OM' => [ 'name' => \JText::_('NR_COUNTRY_OM'), 'calling_code' => '968', 'currency_code' => 'OMR', 'currency_name' => 'Rial', 'currency_symbol' => '﷼' ], 'PK' => [ 'name' => \JText::_('NR_COUNTRY_PK'), 'calling_code' => '92', 'currency_code' => 'PKR', 'currency_name' => 'Rupee', 'currency_symbol' => '₨' ], 'PW' => [ 'name' => \JText::_('NR_COUNTRY_PW'), 'calling_code' => '680', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'PS' => [ 'name' => \JText::_('NR_COUNTRY_PS'), 'calling_code' => '970', 'currency_code' => 'ILS', 'currency_name' => 'Shekel', 'currency_symbol' => '₪' ], 'PA' => [ 'name' => \JText::_('NR_COUNTRY_PA'), 'calling_code' => '507', 'currency_code' => 'PAB', 'currency_name' => 'Balboa', 'currency_symbol' => 'B/.' ], 'PG' => [ 'name' => \JText::_('NR_COUNTRY_PG'), 'calling_code' => '675', 'currency_code' => 'PGK', 'currency_name' => 'Kina', 'currency_symbol' => 'K' ], 'PY' => [ 'name' => \JText::_('NR_COUNTRY_PY'), 'calling_code' => '595', 'currency_code' => 'PYG', 'currency_name' => 'Guarani', 'currency_symbol' => 'Gs' ], 'PE' => [ 'name' => \JText::_('NR_COUNTRY_PE'), 'calling_code' => '51', 'currency_code' => 'PEN', 'currency_name' => 'Sol', 'currency_symbol' => 'S/.' ], 'PH' => [ 'name' => \JText::_('NR_COUNTRY_PH'), 'calling_code' => '63', 'currency_code' => 'PHP', 'currency_name' => 'Peso', 'currency_symbol' => 'Php' ], 'PN' => [ 'name' => \JText::_('NR_COUNTRY_PN'), 'calling_code' => '870', 'currency_code' => 'NZD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'PL' => [ 'name' => \JText::_('NR_COUNTRY_PL'), 'calling_code' => '48', 'currency_code' => 'PLN', 'currency_name' => 'Zloty', 'currency_symbol' => 'zł' ], 'PT' => [ 'name' => \JText::_('NR_COUNTRY_PT'), 'calling_code' => '351', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'PR' => [ 'name' => \JText::_('NR_COUNTRY_PR'), 'calling_code' => '1', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'QA' => [ 'name' => \JText::_('NR_COUNTRY_QA'), 'calling_code' => '974', 'currency_code' => 'QAR', 'currency_name' => 'Rial', 'currency_symbol' => '﷼' ], 'CG' => [ 'name' => \JText::_('NR_COUNTRY_CG'), 'calling_code' => '242', 'currency_code' => 'XAF', 'currency_name' => 'Franc', 'currency_symbol' => 'FCF' ], 'RE' => [ 'name' => \JText::_('NR_COUNTRY_RE'), 'calling_code' => '262', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'RO' => [ 'name' => \JText::_('NR_COUNTRY_RO'), 'calling_code' => '40', 'currency_code' => 'RON', 'currency_name' => 'Leu', 'currency_symbol' => 'lei' ], 'RU' => [ 'name' => \JText::_('NR_COUNTRY_RU'), 'calling_code' => '7', 'currency_code' => 'RUB', 'currency_name' => 'Ruble', 'currency_symbol' => 'руб' ], 'RW' => [ 'name' => \JText::_('NR_COUNTRY_RW'), 'calling_code' => '250', 'currency_code' => 'RWF', 'currency_name' => 'Franc', 'currency_symbol' => 'FRw' ], 'SH' => [ 'name' => \JText::_('NR_COUNTRY_SH'), 'calling_code' => '290', 'currency_code' => 'SHP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'KN' => [ 'name' => \JText::_('NR_COUNTRY_KN'), 'calling_code' => '1869', 'currency_code' => 'XCD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'LC' => [ 'name' => \JText::_('NR_COUNTRY_LC'), 'calling_code' => '1758', 'currency_code' => 'XCD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'PM' => [ 'name' => \JText::_('NR_COUNTRY_PM'), 'calling_code' => '508', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'VC' => [ 'name' => \JText::_('NR_COUNTRY_VC'), 'calling_code' => '1784', 'currency_code' => 'XCD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'WS' => [ 'name' => \JText::_('NR_COUNTRY_WS'), 'calling_code' => '685', 'currency_code' => 'WST', 'currency_name' => 'Tala', 'currency_symbol' => 'WS$' ], 'SM' => [ 'name' => \JText::_('NR_COUNTRY_SM'), 'calling_code' => '378', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'ST' => [ 'name' => \JText::_('NR_COUNTRY_ST'), 'calling_code' => '239', 'currency_code' => 'STD', 'currency_name' => 'Dobra', 'currency_symbol' => 'Db' ], 'SA' => [ 'name' => \JText::_('NR_COUNTRY_SA'), 'calling_code' => '966', 'currency_code' => 'SAR', 'currency_name' => 'Rial', 'currency_symbol' => '﷼' ], 'SN' => [ 'name' => \JText::_('NR_COUNTRY_SN'), 'calling_code' => '221', 'currency_code' => 'XOF', 'currency_name' => 'Franc', 'currency_symbol' => 'CFA' ], 'RS' => [ 'name' => \JText::_('NR_COUNTRY_RS'), 'calling_code' => '381', 'currency_code' => 'RSD', 'currency_name' => 'Dinar', 'currency_symbol' => 'Дин' ], 'SC' => [ 'name' => \JText::_('NR_COUNTRY_SC'), 'calling_code' => '248', 'currency_code' => 'SCR', 'currency_name' => 'Rupee', 'currency_symbol' => '₨' ], 'SL' => [ 'name' => \JText::_('NR_COUNTRY_SL'), 'calling_code' => '232', 'currency_code' => 'SLL', 'currency_name' => 'Leone', 'currency_symbol' => 'Le' ], 'SG' => [ 'name' => \JText::_('NR_COUNTRY_SG'), 'calling_code' => '65', 'currency_code' => 'SGD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'SK' => [ 'name' => \JText::_('NR_COUNTRY_SK'), 'calling_code' => '421', 'currency_code' => 'SKK', 'currency_name' => 'Koruna', 'currency_symbol' => 'Sk' ], 'SI' => [ 'name' => \JText::_('NR_COUNTRY_SI'), 'calling_code' => '386', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'SB' => [ 'name' => \JText::_('NR_COUNTRY_SB'), 'calling_code' => '677', 'currency_code' => 'SBD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'SO' => [ 'name' => \JText::_('NR_COUNTRY_SO'), 'calling_code' => '252', 'currency_code' => 'SOS', 'currency_name' => 'Shilling', 'currency_symbol' => 'S' ], 'ZA' => [ 'name' => \JText::_('NR_COUNTRY_ZA'), 'calling_code' => '27', 'currency_code' => 'ZAR', 'currency_name' => 'Rand', 'currency_symbol' => 'R' ], 'GS' => [ 'name' => \JText::_('NR_COUNTRY_GS'), 'calling_code' => '500', 'currency_code' => 'GBP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'KR' => [ 'name' => \JText::_('NR_COUNTRY_KR'), 'calling_code' => '82', 'currency_code' => 'KRW', 'currency_name' => 'Won', 'currency_symbol' => '₩' ], 'ES' => [ 'name' => \JText::_('NR_COUNTRY_ES'), 'calling_code' => '34', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'LK' => [ 'name' => \JText::_('NR_COUNTRY_LK'), 'calling_code' => '94', 'currency_code' => 'LKR', 'currency_name' => 'Rupee', 'currency_symbol' => '₨' ], 'SD' => [ 'name' => \JText::_('NR_COUNTRY_SD'), 'calling_code' => '249', 'currency_code' => 'SDD', 'currency_name' => 'Dinar', 'currency_symbol' => 'ج.س' ], 'SS' => [ 'name' => \JText::_('NR_COUNTRY_SS'), 'calling_code' => '211', 'currency_code' => 'SSP', 'currency_name' => 'Pound', 'currency_symbol' => 'SS£' ], 'SR' => [ 'name' => \JText::_('NR_COUNTRY_SR'), 'calling_code' => '597', 'currency_code' => 'SRD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'SJ' => [ 'name' => \JText::_('NR_COUNTRY_SJ'), 'calling_code' => '47', 'currency_code' => 'NOK', 'currency_name' => 'Krone', 'currency_symbol' => 'kr' ], 'SZ' => [ 'name' => \JText::_('NR_COUNTRY_SZ'), 'calling_code' => '268', 'currency_code' => 'SZL', 'currency_name' => 'Lilangeni', 'currency_symbol' => 'L' ], 'SE' => [ 'name' => \JText::_('NR_COUNTRY_SE'), 'calling_code' => '46', 'currency_code' => 'SEK', 'currency_name' => 'Krona', 'currency_symbol' => 'kr' ], 'CH' => [ 'name' => \JText::_('NR_COUNTRY_CH'), 'calling_code' => '41', 'currency_code' => 'CHF', 'currency_name' => 'Franc', 'currency_symbol' => 'CHF' ], 'SY' => [ 'name' => \JText::_('NR_COUNTRY_SY'), 'calling_code' => '963', 'currency_code' => 'SYP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'TW' => [ 'name' => \JText::_('NR_COUNTRY_TW'), 'calling_code' => '886', 'currency_code' => 'TWD', 'currency_name' => 'Dollar', 'currency_symbol' => 'NT$' ], 'TJ' => [ 'name' => \JText::_('NR_COUNTRY_TJ'), 'calling_code' => '992', 'currency_code' => 'TJS', 'currency_name' => 'Somoni', 'currency_symbol' => 'SM' ], 'TZ' => [ 'name' => \JText::_('NR_COUNTRY_TZ'), 'calling_code' => '255', 'currency_code' => 'TZS', 'currency_name' => 'Shilling', 'currency_symbol' => 'TSh' ], 'TH' => [ 'name' => \JText::_('NR_COUNTRY_TH'), 'calling_code' => '66', 'currency_code' => 'THB', 'currency_name' => 'Baht', 'currency_symbol' => '฿' ], 'TG' => [ 'name' => \JText::_('NR_COUNTRY_TG'), 'calling_code' => '228', 'currency_code' => 'XOF', 'currency_name' => 'Franc', 'currency_symbol' => 'CFA' ], 'TK' => [ 'name' => \JText::_('NR_COUNTRY_TK'), 'calling_code' => '690', 'currency_code' => 'NZD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'TO' => [ 'name' => \JText::_('NR_COUNTRY_TO'), 'calling_code' => '676', 'currency_code' => 'TOP', 'currency_name' => 'Paanga', 'currency_symbol' => 'T$' ], 'TT' => [ 'name' => \JText::_('NR_COUNTRY_TT'), 'calling_code' => '1868', 'currency_code' => 'TTD', 'currency_name' => 'Dollar', 'currency_symbol' => 'TT$' ], 'TN' => [ 'name' => \JText::_('NR_COUNTRY_TN'), 'calling_code' => '216', 'currency_code' => 'TND', 'currency_name' => 'Dinar', 'currency_symbol' => 'د.ت' ], 'TR' => [ 'name' => \JText::_('NR_COUNTRY_TR'), 'calling_code' => '90', 'currency_code' => 'TRY', 'currency_name' => 'Lira', 'currency_symbol' => 'YTL' ], 'TM' => [ 'name' => \JText::_('NR_COUNTRY_TM'), 'calling_code' => '993', 'currency_code' => 'TMM', 'currency_name' => 'Manat', 'currency_symbol' => 'm' ], 'TC' => [ 'name' => \JText::_('NR_COUNTRY_TC'), 'calling_code' => '1649', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'TV' => [ 'name' => \JText::_('NR_COUNTRY_TV'), 'calling_code' => '688', 'currency_code' => 'AUD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'VI' => [ 'name' => \JText::_('NR_COUNTRY_VI'), 'calling_code' => '1340', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'UG' => [ 'name' => \JText::_('NR_COUNTRY_UG'), 'calling_code' => '256', 'currency_code' => 'UGX', 'currency_name' => 'Shilling', 'currency_symbol' => 'USh' ], 'UA' => [ 'name' => \JText::_('NR_COUNTRY_UA'), 'calling_code' => '380', 'currency_code' => 'UAH', 'currency_name' => 'Hryvnia', 'currency_symbol' => '₴' ], 'AE' => [ 'name' => \JText::_('NR_COUNTRY_AE'), 'calling_code' => '971', 'currency_code' => 'AED', 'currency_name' => 'Dirham', 'currency_symbol' => 'د.إ' ], 'GB' => [ 'name' => \JText::_('NR_COUNTRY_GB'), 'calling_code' => '44', 'currency_code' => 'GBP', 'currency_name' => 'Pound', 'currency_symbol' => '£' ], 'US' => [ 'name' => \JText::_('NR_COUNTRY_US'), 'calling_code' => '1', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'UM' => [ 'name' => \JText::_('NR_COUNTRY_UM'), 'calling_code' => '246', 'currency_code' => 'USD', 'currency_name' => 'Dollar', 'currency_symbol' => '$' ], 'UY' => [ 'name' => \JText::_('NR_COUNTRY_UY'), 'calling_code' => '598', 'currency_code' => 'UYU', 'currency_name' => 'Peso', 'currency_symbol' => '$U' ], 'UZ' => [ 'name' => \JText::_('NR_COUNTRY_UZ'), 'calling_code' => '998', 'currency_code' => 'UZS', 'currency_name' => 'Som', 'currency_symbol' => 'лв' ], 'VU' => [ 'name' => \JText::_('NR_COUNTRY_VU'), 'calling_code' => '678', 'currency_code' => 'VUV', 'currency_name' => 'Vatu', 'currency_symbol' => 'Vt' ], 'VA' => [ 'name' => \JText::_('NR_COUNTRY_VA'), 'calling_code' => '39', 'currency_code' => 'EUR', 'currency_name' => 'Euro', 'currency_symbol' => '€' ], 'VE' => [ 'name' => \JText::_('NR_COUNTRY_VE'), 'calling_code' => '58', 'currency_code' => 'VEF', 'currency_name' => 'Bolivar', 'currency_symbol' => 'Bs' ], 'VN' => [ 'name' => \JText::_('NR_COUNTRY_VN'), 'calling_code' => '84', 'currency_code' => 'VND', 'currency_name' => 'Dong', 'currency_symbol' => '₫' ], 'WF' => [ 'name' => \JText::_('NR_COUNTRY_WF'), 'calling_code' => '681', 'currency_code' => 'XPF', 'currency_name' => 'Franc', 'currency_symbol' => 'F' ], 'EH' => [ 'name' => \JText::_('NR_COUNTRY_EH'), 'calling_code' => '212', 'currency_code' => 'MAD', 'currency_name' => 'Dirham', 'currency_symbol' => 'DH' ], 'YE' => [ 'name' => \JText::_('NR_COUNTRY_YE'), 'calling_code' => '967', 'currency_code' => 'YER', 'currency_name' => 'Rial', 'currency_symbol' => '﷼' ], 'ZM' => [ 'name' => \JText::_('NR_COUNTRY_ZM'), 'calling_code' => '260', 'currency_code' => 'ZMK', 'currency_name' => 'Kwacha', 'currency_symbol' => 'ZK' ], 'ZW' => [ 'name' => \JText::_('NR_COUNTRY_ZW'), 'calling_code' => '263', 'currency_code' => 'ZWD', 'currency_name' => 'Dollar', 'currency_symbol' => 'Z$' ] ]; } }PK!._1system/nrframework/NRFramework/Widgets/Rating.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; /** * The Rating Widget */ class Rating extends Widget { /** * Widget default options * * @var array */ protected $widget_options = [ // The SVG icon representing the rating icon. Available values: check, circle, flag, heart, smiley, square, star, thumbs_up 'icon' => 'star', // The default value of the widget. 'value' => 0, // How many stars to show? 'max_rating' => 5, // Whether to show half ratings 'half_ratings' => false, // The size of the rating icon in pixels. 'size' => 24, // The color of the icon in the default state 'selected_color' => '#f6cc01', // The color of the icon in the selected and hover state 'unselected_color' => '#bdbdbd' ]; /** * Class constructor * * @param array $options */ public function __construct($options = []) { parent::__construct($options); $this->options['value'] = $this->options['value'] > $this->options['max_rating'] ? $this->options['max_rating'] : $this->options['value']; $this->options['icon_url'] = \JURI::root() . 'media/plg_system_nrframework/svg/rating/' . $this->options['icon'] . '.svg'; $this->options['max_rating'] = $this->options['half_ratings'] ? 2 * $this->options['max_rating'] : $this->options['max_rating']; } }PK!+'c""9system/nrframework/NRFramework/Widgets/GalleryManager.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; use Joomla\Registry\Registry; use NRFramework\Helpers\Widgets\GalleryManager as GalleryManagerHelper; /** * Gallery Manager */ class GalleryManager extends Widget { /** * Widget default options * * @var array */ protected $widget_options = [ // The input name 'name' => '', // The field ID associated to this Gallery Manager, used to retrieve the field settings on AJAX actions 'field_id' => null, /** * Max file size in MB. * * Defults to 0 (no limit). */ 'max_file_size' => 0, /** * How many files we can upload. * * Defaults to 0 (no limit). */ 'limit_files' => 0, // Allowed upload file types 'allowed_file_types' => '.jpg, .jpeg, .png, .gif', /** * Original Image */ // Should the original uploaded image be resized? 'original_image_resize' => false, // Original Image Resize Quality 'original_image_resize_quality' => 80, // Main image width 'original_image_resize_width' => 1920, /** * Thumbnails */ // Thumbnails width 'thumb_width' => 300, // Thumbnails height 'thumb_height' => null, // Thumbnails resize method (crop, stretch, fit) 'thumb_resize_method' => 'crop', // Thumbnails resize quality 'thumb_resize_quality' => 80 ]; public function __construct($options = []) { parent::__construct($options); // Set gallery items $this->options['gallery_items'] = is_array($this->options['value']) ? $this->options['value'] : []; // Set css class for readonly state if ($this->options['readonly']) { $this->options['css_class'] .= ' readonly'; } // Adds a css class when the gallery contains at least one item if (count($this->options['gallery_items'])) { $this->options['css_class'] .= ' dz-has-items'; } // Load translation strings \JText::script('NR_GALLERY_MANAGER_CONFIRM_REGENERATE_THUMBNAILS'); \JText::script('NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL_SELECTED'); \JText::script('NR_GALLERY_MANAGER_CONFIRM_DELETE_ALL'); \JText::script('NR_GALLERY_MANAGER_CONFIRM_DELETE'); \JText::script('NR_GALLERY_MANAGER_FILE_MISSING'); \JText::script('NR_GALLERY_MANAGER_REACHED_FILES_LIMIT'); } /** * The upload task called by the AJAX hanler * * @return void */ protected function ajax_upload() { $input = \JFactory::getApplication()->input; // Make sure we have a valid field id if (!$field_id = $input->getInt('field_id')) { $this->exitWithMessage('NR_GALLERY_MANAGER_FIELD_ID_ERROR'); } // Make sure we have a valid file passed if (!$file = $input->files->get('file', null, null)) { $this->exitWithMessage('NR_GALLERY_MANAGER_ERROR_INVALID_FILE'); } if (!$field_data = \NRFramework\Helpers\CustomField::getData($field_id)) { $this->exitWithMessage('NR_GALLERY_MANAGER_INVALID_FIELD_DATA'); } // get the media uploader file data, values are passed when we upload a file using the Media Uploader $media_uploader_file_data = [ 'is_media_uploader_file' => $input->get('media_uploader', false) == '1', 'media_uploader_filename' => $input->getString('media_uploader_filename', ''), // Whether the image was copied to the `tmp` folder when added via the media uploader 'copied_from_media_uploader' => $input->get('media_uploader', false) == '1' ]; // In case we allow multiple uploads the file parameter is a 2 levels array. $first_property = array_pop($file); if (is_array($first_property)) { $file = $first_property; } $uploadSettings = [ 'allow_unsafe' => false, 'allowed_types' => $field_data->get('allowed_file_types', $this->widget_options['allowed_file_types']) ]; // resize image settings $resizeSettings = [ 'thumb_width' => $field_data->get('thumb_width', 300), // Send the height only if grid is selected. We do not need it for masonry style 'thumb_height' => $field_data->get('style', 'masonry') === 'grid' ? $field_data->get('thumb_height', null) : null, 'thumb_resize_method' => $field_data->get('thumb_resize_method', 'crop'), 'thumb_resize_quality' => $field_data->get('thumb_resize_quality', 80), 'original_image_resize' => ($field_data->get('original_image_resize', false)), 'original_image_resize_width' => $field_data->get('original_image_resize_width', 1920), 'original_image_resize_quality' => $field_data->get('original_image_resize_quality', 80) ]; // Upload the file and resize the image if needed if (!$uploaded_filenames = GalleryManagerHelper::upload($file, $uploadSettings, $media_uploader_file_data, $resizeSettings)) { $this->exitWithMessage('NR_GALLERY_MANAGER_ERROR_CANNOT_UPLOAD_FILE'); } echo json_encode([ 'filename' => $uploaded_filenames['filename'], 'thumbnail' => $uploaded_filenames['thumbnail'], 'is_media_uploader_file' => $media_uploader_file_data['is_media_uploader_file'], 'copied_from_media_uploader' => $media_uploader_file_data['copied_from_media_uploader'] ]); } /** * The delete task called by the AJAX hanlder * * @return void */ protected function ajax_delete() { $input = \JFactory::getApplication()->input; // Make sure we have a valid file passed if (!$filename = $input->getString('filename')) { $this->exitWithMessage('NR_GALLERY_MANAGER_ERROR_INVALID_FILE'); } // Make sure we have a valid field id if (!$field_id = $input->getInt('field_id')) { $this->exitWithMessage('NR_GALLERY_MANAGER_FIELD_ID_ERROR'); } if (!$field_data = \NRFramework\Helpers\CustomField::getData($field_id)) { $this->exitWithMessage('NR_GALLERY_MANAGER_INVALID_FIELD_DATA'); } // Delete the uploaded file $deleted = GalleryManagerHelper::deleteFile( $filename, $input->getString('thumbnail'), [ 'copied_from_media_uploader' => $input->get('copied_from_media_uploader') === 'true', 'is_media_uploader_file' => $input->get('is_media_uploader_file') === 'true', 'upload_folder_type' => $field_data->get('upload_folder_type', 'auto') ] ); echo json_encode(['success' => $deleted]); } /** * This task allows us to regenerate the thumbnails. * * @return void */ protected function ajax_regenerate_thumbs() { $input = \JFactory::getApplication()->input; // Make sure we have a valid field id if (!$field_id = $input->getInt('field_id')) { echo json_encode(['success' => false, 'message' => \JText::_('NR_GALLERY_MANAGER_FIELD_ID_ERROR')]); die(); } if (!$field_data = \NRFramework\Helpers\CustomField::getData($field_id)) { echo json_encode(['success' => false, 'message' => \JText::_('NR_GALLERY_MANAGER_INVALID_FIELD_DATA')]); die(); } $resizeSettings = [ 'thumb_width' => $field_data->get('thumb_width', 300), // Send the height only if grid is selected. We do not need it for masonry style 'thumb_height' => $field_data->get('style', 'masonry') === 'grid' ? $field_data->get('thumb_height', null) : null, 'thumb_resize_method' => $field_data->get('thumb_resize_method', 'crop'), 'thumb_resize_quality' => $field_data->get('thumb_resize_quality', 80), ]; $existing = $input->get('existing', null, 'ARRAY'); $existing = json_decode($existing[0], true); $new = $input->get('new', null, 'ARRAY'); $new = json_decode($new[0], true); $ds = DIRECTORY_SEPARATOR; // Check each existing file and re-create thumbs if (is_array($existing) && count($existing)) { foreach ($existing as $path) { $_path = implode($ds, [JPATH_ROOT, $path]); if (!file_exists($_path)) { continue; } \NRFramework\Helpers\Widgets\GalleryManager::generateThumbnail($_path, $resizeSettings, null, false); } } // Check each newly added file in temp folder and re-create thumbs if (is_array($new) && count($new)) { foreach ($new as $path) { $_path = implode($ds, [\NRFramework\File::getTempFolder(), $path]); if (!file_exists($_path)) { continue; } \NRFramework\Helpers\Widgets\GalleryManager::generateThumbnail($_path, $resizeSettings, null, false); } } echo json_encode(['success' => true, 'message' => \JText::_('NR_GALLERY_MANAGER_THUMBS_REGENERATED')]); } /** * Exits the page with given message. * * @param string $translation_string * * @return void */ private function exitWithMessage($translation_string) { http_response_code('500'); die(\JText::_($translation_string)); } }PK!5TT1system/nrframework/NRFramework/Widgets/Widget.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; class Widget { /** * Widget's default options * * @var array */ protected $options = [ // Set whether to load the CSS variables 'load_css_vars' => true, // Set whether to load the default stylesheet 'load_stylesheet' => true, // If true, the widget will be rended in read-only mode. 'readonly' => false, // If true, the widget will be rended in disabled mode. 'disabled' => false, // Indicates the widget's input field must be filled out before submitting the form. 'required' => false, // The CSS class to be used on the widget's wrapper 'css_class' => '', // The CSS class to be used on the input 'input_class' => '', // The default widget value 'value' => '', // Extra attributes 'atts' => '', // A short hint that describes the expected value 'placeholder' => '', // The name of the layout to be used to render the widget 'layout' => 'default', // Whether we are rendering the Pro version of the widget 'pro' => false ]; /** * If no name is provided, this counter is appended to the widget's name to prevent name conflicts * * @var int */ protected static $counter = 0; /** * Class constructor * * @param array $options */ public function __construct($options = []) { // Merge Widget class default options with given Widget default options $this->options = array_merge($this->options, $this->widget_options, $options); // Set ID if none given if (!isset($this->options['id'])) { $this->options['id'] = $this->getName() . self::$counter; } // Help developers target the whole widget by applying the widget's ID to the CSS class list. // Do not use the id="xx" attribute in the HTML to prevent conflicts with the input's ID. $this->options['css_class'] .= ' ' . $this->options['id']; // Set name if none given if (!isset($this->options['name'])) { $this->options['name'] = $this->options['id']; } // Set disabled class if widget is disabled if ($this->options['disabled']) { $this->options['css_class'] .= ' disabled'; } self::$counter++; } /** * Renders the widget with the given layout * * Layouts can be overriden in the following folder: /templates/TEMPLATE_NAME/html/tassos/WIDGET_NAME/LAYOUT_NAME.php * * @return string */ public function render() { $defaultPath = implode(DIRECTORY_SEPARATOR, [JPATH_PLUGINS, 'system', 'nrframework', 'layouts']); $overridePath = implode(DIRECTORY_SEPARATOR, [JPATH_THEMES, \JFactory::getApplication()->getTemplate(), 'html', 'tassos']); $layout = new \JLayoutFile('widgets.' . $this->getName() . '.' . $this->options['layout'], null, ['debug' => false]); $layout->addIncludePaths($defaultPath); $layout->addIncludePaths($overridePath); return $layout->render($this->options); } /** * Get the name of the widget * * @return void */ public function getName() { return strtolower((new \ReflectionClass($this))->getShortName()); } /** * Manages ajax requests for the widget. * * @param string $task * * @return void */ public function onAjax($task) { \JSession::checkToken('request') or die('Invalid Token'); if (!$task || !is_string($task)) { return; } $method = 'ajax_' . $task; if (!method_exists($this, $method)) { return; } $this->$method(); } }PK!Ozz1system/nrframework/NRFramework/Widgets/Helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; use Joomla\CMS\Filesystem\Folder; defined('_JEXEC') or die; class Helper { /** * This is a map with all widgets used for caching the widget's class name * * @var array */ public static $widgets_map = []; /** * Renders a Widget and returns * * @param array $options A list of attributes passed to the layout * * @return string The widget's final HTML layout */ public static function render($widget_name, $options = []) { if (!$widgetClass = self::find($widget_name)) { return; } $class = __NAMESPACE__ . '\\' . $widgetClass; // ensure class exists if (!class_exists($class)) { return; } return (new $class($options))->render(); } /** * Return the real class name of a widget by a case-insensitive name. * * @param string $name The widget's name * * @return mixed Null when the class name is not found, string when the class name is found. */ public static function find($name) { if (!$name) { return; } $name = strtolower($name); if (empty(self::$widgets_map) || !isset(self::$widgets_map[$name])) { $widgetClasses = Folder::files(__DIR__); foreach ($widgetClasses as $widgetClass) { $widgetClass = str_replace('.php', '', $widgetClass); self::$widgets_map[strtolower($widgetClass)] = $widgetClass; } } return isset(self::$widgets_map[$name]) ? self::$widgets_map[$name] : null; } }PK! 4system/nrframework/NRFramework/Widgets/Signature.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; /** * Signature */ class Signature extends Widget { /** * Widget default options * * @var array */ protected $widget_options = [ // The base64 image data of the signature. 'value' => '', // The width of the signature in pixels or empty for auto width. The width will be taken from the signature container. 'width' => '', // The height of the signature in pixels. 'height' => '300px', // The background color of the signature. 'background_color' => '#ffffff', // The border color of the canvas. 'border_color' => '#dedede', /** * The border radius of the canvas. * * Example values: 0, 0px, 50px, 50% */ 'border_radius' => 0, /** * The border width of the canvas. * * Example values: 0, 1px, 5px */ 'border_width' => '1px', // Whether to show the horizontal line within the canvas 'show_line' => true, /** * The line color. * * If `null`, retrieves the value from `border_color` */ 'line_color' => null, // The pen color 'pen_color' => '#000' ]; /** * Class constructor * * @param array $options */ public function __construct($options = []) { parent::__construct($options); if ($this->options['readonly']) { $this->options['css_class'] .= ' readonly'; } if (!empty($this->options['value'])) { $this->options['css_class'] .= ' painted has-value'; } if ($this->options['show_line']) { $this->options['css_class'] .= ' show-line'; } } }PK!M>F 8system/nrframework/NRFramework/Widgets/OpenStreetMap.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; /** * OpenStreetMap */ class OpenStreetMap extends Widget { /** * Widget default options * * @var array */ protected $widget_options = [ /** * The value of the widget. * Format: latitude,longitude * * i.e. 36.891319,27.283480 */ 'value' => '', // Default map width 'width' => '500px', // Default map height 'height' => '400px', // Default map zoon 'zoom' => 4, // Map scale. Values: metric, imperial, false 'scale' => false, // View mode of the map. Values: road, aerial. 'view' => 'road', /** * Address input above map */ // Whether to show the address input above the map 'showAddressInput' => false, /** * Map Marker */ // Whether to show the marker 'showMarker' => true, // Marker image relative to Joomla installation 'markerImage' => 'media/plg_system_nrframework/img/marker.png', // Allows marker to be dragged 'allowMarkerDrag' => false, // Allows map to be clicked and thus allows us to select a new location 'allowMapClick' => false, // Whether to show the marker tooltip 'showMarkerTooltip' => false, // Set whether to display the marker tooltip textarea. 'showMarkerTooltipInput' => false, // Marker Tooltip Textarea Name. If a value is given, then the tooltip textarea field appears below the map 'markerTooltipName' => '', // Marker tooltip value 'markerTooltipValue' => '', /** * Coordinates input below map */ // Whether to show the coordinates input 'showCoordsInput' => false, // Coordinates input name. If a value is given, then the coordinates input field appears below the map 'coordsInputName' => '' ]; public function __construct($options = []) { parent::__construct($options); $this->options['markerImage'] = \JURI::root() . ltrim($this->options['markerImage'], DIRECTORY_SEPARATOR); } /** * Renders the widget * * @return string */ public function render() { self::loadMedia(); return parent::render(); } /** * Loads media files * * @return void */ private function loadMedia() { \JHtml::stylesheet('https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/css/ol.css'); \JHtml::script('https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/build/ol.js'); $this->load_geocoder(); if ($this->options['load_stylesheet']) { \JHtml::stylesheet('plg_system_nrframework/widgets/openstreetmap.css', ['relative' => true, 'version' => 'auto']); } \JHtml::script('plg_system_nrframework/widgets/openstreetmap.js', ['relative' => true, 'version' => 'auto']); } /** * Checks whether geocoder is enabled and loads it. * * @return void */ private function load_geocoder() { if (!$this->options['showAddressInput']) { return; } $lang = \JFactory::getLanguage(); $lang_tag = $lang->getTag(); $doc = \JFactory::getDocument(); $doc->addScriptOptions('nrf_osm_settings', [ 'lang_tag' => $lang_tag ]); \JText::script('NR_OSM_ADDRESS_DESC'); \JHtml::stylesheet('https://unpkg.com/ol-geocoder/dist/ol-geocoder.min.css'); \JHtml::script('https://unpkg.com/ol-geocoder'); $this->options['css_class'] .= ' geocoder'; } }PK!3z46system/nrframework/NRFramework/Widgets/ColorPicker.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; /** * Color picker */ class ColorPicker extends Widget { /** * Widget default options * * @var array */ protected $widget_options = [ // The default value of the widget. 'value' => '#dedede', // The input border color 'input_border_color' => '#dedede', // The input border color on focus 'input_border_color_focus' => '#dedede', // The input background color 'input_bg_color' => '#fff', // Input text color 'input_text_color' => '#333' ]; }PK!}#xx4system/nrframework/NRFramework/Widgets/Countdown.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; /** * Countdown */ class Countdown extends Widget { /** * Widget default options * * @var array */ protected $widget_options = [ /** * The Countdown type: * * - static: Counts down to a specific date and time. Universal deadline for all visitors. * - dynamic: Set-and-forget solution. The countdown starts when your visitor sees the offer. */ 'countdown_type' => 'static', // The Static Countdown Date 'value' => '', /** * The timezone that will be used. * * - server - Use server's timezone * - client - Use client's timezone */ 'timezone' => 'server', // Dynamic Days 'dynamic_days' => 0, // Dynamic Hours 'dynamic_hours' => 0, // Dynamic Minutes 'dynamic_minutes' => 0, // Dynamic Seconds 'dynamic_seconds' => 0, /** * The countdown format. * * Available tags: * {years} * {months} * {days} * {hours} * {minutes} * {seconds} */ 'format' => '{days} days, {hours} hours, {minutes} minutes and {seconds} seconds', /** * The countdown theme. * * Available themes: * theme1 * theme2 * theme3 */ 'theme' => 'theme1', /** * Set the action once countdown finishes. * * Available values: * keep - Keep the countdown visible * hide - Hide the countdown * message - Show a message * redirect - Redirect to a URL */ 'countdown_action' => 'keep', /** * The message appearing after the countdown has finished. * * Requires `countdown_action` to be set to `message` * * Example: Countdown finished. */ 'finish_text' => '', /** * The redirect URL once the countdown expires. * * Requires `countdown_action` to be set to `redirect` */ 'redirect_url' => '', // Whether to display Days 'days' => true, // Days Label 'days_label' => 'Days', // Whether to display Hours 'hours' => true, // Hours Label 'hours_label' => 'Hours', // Whether to display Minutes 'minutes' => true, // Minutes Label 'minutes_label' => 'Minutes', // Whether to display Seconds 'seconds' => true, // Seconds Label 'seconds_label' => 'Seconds', // Unit Border Color 'item_border_color' => '', // Unit Label Color 'unit_label_color' => '', // Digit Item Background Color. This applies for each of the 2 digits on a unit. 'digit_background_color' => '', // Digit Item Text Color 'digit_text_color' => '', // Unit Label Margin Top. The spacing between the unit and its label. 'unit_label_margin_top' => '', // Digit Minimum Width. This is the minimum width for each number within a digit. 'digit_min_width' => '', // Whether the units will appear in bold. 'digits_bold' => false, // Whether each unit label will appear in bold. 'unit_label_bold' => false, // Alignment 'align' => '', // Extra attributes added to the widget 'atts' => '', // CSS variables to style the countdown 'css_vars' => '' ]; /** * Class constructor * * @param array $options */ public function __construct($options = []) { parent::__construct($options); $this->prepare(); } /** * Prepares the countdown. * * @return void */ private function prepare() { $this->setCSSVars(); $this->options['css_class'] .= ' ' . $this->options['theme'] . ' ' . $this->options['align']; if (!empty($this->options['value']) && $this->options['value'] !== '0000-00-00 00:00:00') { if ($this->options['countdown_type'] === 'static' && $this->options['timezone'] === 'server') { // Get timezone $tz = new \DateTimeZone(\JFactory::getApplication()->getCfg('offset', 'UTC')); // Convert given date time to UTC $this->options['value'] = date_create($this->options['value'], $tz)->setTimezone(new \DateTimeZone('UTC'))->format('c'); // Apply server timezone $this->options['value'] = (new \DateTime($this->options['value']))->setTimezone($tz)->format('c'); } } // Set countdown payload $payload = [ 'data-countdown-type="' . $this->options['countdown_type'] . '"', 'data-value="' . $this->options['value'] . '"', 'data-timezone="' . $this->options['timezone'] . '"', 'data-dynamic-days="' . $this->options['dynamic_days'] . '"', 'data-dynamic-hours="' . $this->options['dynamic_hours'] . '"', 'data-dynamic-minutes="' . $this->options['dynamic_minutes'] . '"', 'data-dynamic-seconds="' . $this->options['dynamic_seconds'] . '"', 'data-finish-text="' . htmlspecialchars($this->options['finish_text']) . '"', 'data-redirect-url="' . $this->options['redirect_url'] . '"', 'data-theme="' . $this->options['theme'] . '"', 'data-format="' . htmlspecialchars($this->options['format']) . '"', 'data-countdown-action="' . $this->options['countdown_action'] . '"', 'data-days="' . var_export($this->options['days'], true) . '"', 'data-days-label="' . $this->options['days_label'] . '"', 'data-hours="' . var_export($this->options['hours'], true) . '"', 'data-hours-label="' . $this->options['hours_label'] . '"', 'data-minutes="' . var_export($this->options['minutes'], true) . '"', 'data-minutes-label="' . $this->options['minutes_label'] . '"', 'data-seconds="' . var_export($this->options['seconds'], true) . '"', 'data-seconds-label="' . $this->options['seconds_label'] . '"' ]; $this->options['atts'] = implode(' ', $payload); } /** * Set widget CSS vars * * @return mixed */ private function setCSSVars() { $atts = []; if (!empty($this->options['item_border_color'])) { $atts['item-border-color'] = $this->options['item_border_color']; } if (!empty($this->options['unit_label_color'])) { $atts['unit-label-color'] = $this->options['unit_label_color']; } if (!empty($this->options['digit_background_color'])) { $atts['digit-background-color'] = $this->options['digit_background_color']; } if (!empty($this->options['digit_text_color'])) { $atts['digit-text-color'] = $this->options['digit_text_color']; } if (!empty($this->options['unit_label_margin_top'])) { $atts['unit-label-margin-top'] = $this->options['unit_label_margin_top'] . 'px'; } if (!empty($this->options['digit_min_width'])) { $atts['digit-min-width'] = $this->options['digit_min_width'] . 'px'; } if (!empty($this->options['digits_bold'])) { $atts['digits-font-weight'] = 'bold'; } if (!empty($this->options['unit_label_bold'])) { $atts['unit-label-font-weight'] = 'bold'; } if (empty($atts)) { return; } if (!$css = \NRFramework\Helpers\CSS::cssVarsToString($atts, '.nrf-countdown.' . $this->options['id'])) { return; } $this->options['css_vars'] = $css; } }PK!L4^4^2system/nrframework/NRFramework/Widgets/Gallery.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; use \NRFramework\Helpers\Widgets\Gallery as GalleryHelper; use NRFramework\Mimes; use NRFramework\File; use NRFramework\Image; /** * Gallery */ class Gallery extends Widget { /** * Widget default options * * @var array */ protected $widget_options = [ /** * The gallery items source. * * This can be one or combination of the following: * * - Path to a relative folder (String) * /path/to/folder * - Path to a relative image (String) * /path/to/folder/image.png * - URL of an image (String) * https://example.com/path/to/image.png * - Array of images (Array) * [ * 'url' => 'https://example.com/path/to/image.png', * 'thumbnail_url' => 'https://example.com/path/to/image_thumb.png', * 'caption' => 'This is a caption', * 'thumbnail_size' => [ * 'width' => '200', * 'height' => '200' * ], * 'module' => 'position-2' * ] * * - The `url` property is required. * - All other properties are optional. */ 'items' => [], /** * Set the ordering. * * Available values: * - default * - alphabetical * - reverse_alphabetical * - random */ 'ordering' => 'default', // Set the module key to display whenever we are viewing a single item's lightbox, appearing after the image 'module' => '', // Set the style of the gallery (masonry, grid) 'style' => 'masonry', /** * Define the columns per supported device. * * Example value: * - An integer representing the columns for all devices: 3 * - A value for each device: * [ * 'desktop' => 3, * 'tablet' => 2, * 'mobile' => 1 * ] */ 'columns' => 4, /** * Define the gap per gallery item per supported device. * * Example value: * - An integer representing the gap for all devices: 30 * - A value for each device: * [ * 'desktop' => 30, * 'tablet' => 20, * 'mobile' => 10 * ] */ 'gap' => 15, /** * Set the allowed file types. * * This is used to validate the files loaded via a directory or a fixed path to an image. * * Given URLs are not validated by this setting. */ 'allowed_file_types' => '.jpg, .jpeg, .png', // Gallery Items wrapper CSS classes 'gallery_items_css' => '', // Set whether to display a lightbox 'lightbox' => true, /** * Source Image */ /** * Should the source image be resized? * * If `original_image_resize` is false, then the source image will appear * in the lightbox (also if `thumbnails` is false, the source image will also appear as the thumbnail) * * Issue: if this image is a raw photo, there are chances it will increase the page load in order for the browser to display the image. * * By enabling this, we resize the source image to our desired dimensions and reduce the page load in the above scenario. * * Note: Always ensure the source image is backed up to a safe place. * Note 2: We require thumbnails or original image resize to be enabled for this to work. * Reason: The above options if enabled generate the gallery_info.txt file in the /cache folder which helps us * generate the source images only if necessary(image has been edited), otherwise, the source image would * be generated on each page refresh. */ 'source_image_resize' => false, // Source image resize width 'source_image_resize_width' => 1920, // Source image resize height 'source_image_resize_height' => null, // Source image resize method (crop, stretch, fit) 'source_image_resize_method' => 'crop', // Source image resize quality 'source_image_resize_image_quality' => 80, /** * Original Image */ // Should the original uploaded image be resized? 'original_image_resize' => false, // Resize method (crop, stretch, fit) 'original_image_resize_method' => 'crop', /** * Original Image Resize Width. * * If `original_image_resize_height` is null, resizes via the width to keep the aspect ratio. */ 'original_image_resize_width' => 1920, // Original Image Resize Height 'original_image_resize_height' => null, // Original Image Resize Quality 'original_image_resize_image_quality' => 80, /** * Thumbnails */ // Set whether to generate thumbnails on-the-fly 'thumbnails' => false, // Resize method (crop, stretch, fit) 'thumb_resize_method' => 'crop', // Resize quality 'thumb_resize_quality' => 80, // Thumbnails width 'thumb_width' => 300, // Thumbnails height 'thumb_height' => null, // The CSS class of the thumbnail 'thumb_class' => '', /** * Set whether to resize the images whenever their source file changes. * * i.e. If we edit the source image and also need to recreate the resized original image or thumbnail. * This is rather useful otherwise we would have to delete the resized image or thumbnail in order for it to be recreated. */ 'force_resizing' => false, // Destination folder 'destination_folder' => 'cache/tassos/gallery', // The unique hash of this gallery based on its options 'hash' => null, // Set whether to show warnings when an image that has been set to appear does not exist. 'show_warnings' => true ]; public function __construct($options = []) { parent::__construct($options); $this->prepare(); } /** * Prepares the Gallery. * * @return void */ private function prepare() { $this->options['hash'] = $this->getHash(); $this->options['destination_folder'] = JPATH_ROOT . DIRECTORY_SEPARATOR . $this->options['destination_folder'] . DIRECTORY_SEPARATOR . $this->options['hash'] . DIRECTORY_SEPARATOR; $this->parseGalleryItems(); $this->cleanDestinationFolder(); $this->resizeSourceImages(); $this->resizeOriginalImages(); $this->createThumbnails(); // Set style on the gallery items container. $this->options['gallery_items_css'] .= ' ' . $this->getStyle(); // Set class to trigger lightbox. if ($this->options['lightbox']) { $this->options['css_class'] .= ' lightbox'; } $this->prepareItems(); $this->setCSSVariables(); $this->setOrdering(); } /** * Sets the ordering of the gallery. * * @return void */ private function setOrdering() { switch ($this->options['ordering']) { case 'random': shuffle($this->options['items']); break; case 'alphabetical': usort($this->options['items'], [$this, 'compareByThumbnailASC']); break; case 'reverse_alphabetical': usort($this->options['items'], [$this, 'compareByThumbnailDESC']); break; } } /** * Compares thumbnail file names in ASC order * * @param array $a * @param array $b * * @return bool */ private function compareByThumbnailASC($a, $b) { return strcmp(basename($a['thumbnail']), basename($b['thumbnail'])); } /** * Compares thumbnail file names in DESC order * * @param array $a * @param array $b * * @return bool */ private function compareByThumbnailDESC($a, $b) { return strcmp(basename($b['thumbnail']), basename($a['thumbnail'])); } /** * Get the hash of this gallery. * * Generate the hash with only the essential options of the Gallery widget. * i.e. with the data that are related to the images. * * @return string */ private function getHash() { $opts = [ 'items', 'style', 'allowed_file_types', 'source_image_resize', 'source_image_resize_width', 'source_image_resize_height', 'source_image_resize_method', 'source_image_resize_image_quality', 'original_image_resize', 'original_image_resize_method', 'original_image_resize_width', 'original_image_resize_height', 'original_image_resize_image_quality', 'thumbnails', 'thumb_resize_method', 'thumb_resize_quality', 'thumb_width', 'thumb_height', 'force_resizing', 'destination_folder' ]; $payload = []; foreach ($opts as $opt) { $payload[$opt] = $this->options[$opt]; } return md5(serialize($payload)); } /** * Cleans the source folder. * * If an image from the source folder is removed, we also remove the * original image/thumbnail from the destination folder as well as * from the gallery info file. * * @return void */ private function cleanDestinationFolder() { if (!$this->options['original_image_resize'] && !$this->options['thumbnails']) { return; } // Find all folders that we need to search $dirs_to_search = []; // Store all source files $source_files = []; foreach ($this->options['items'] as $key => $item) { if (!isset($item['path'])) { continue; } $source_files[] = pathinfo($item['path'], PATHINFO_BASENAME); $directory = is_dir($item['path']) ? $item['path'] : dirname($item['path']); if (in_array($directory, $dirs_to_search)) { continue; } $dirs_to_search[] = $directory; } if (empty($dirs_to_search)) { return; } // Loop each directory found and check which files we need to delete foreach ($dirs_to_search as $dir) { $source_folder_info_file = GalleryHelper::getGalleryInfoFileData($dir); // Find all soon to be deleted files $to_be_deleted = array_diff(array_keys($source_folder_info_file), $source_files); if (!count($to_be_deleted)) { continue; } foreach ($to_be_deleted as $source) { // Original image delete if (isset($source_folder_info_file[$source])) { $file = $this->options['destination_folder'] . $source_folder_info_file[$source]['filename']; if (file_exists($file)) { unlink($file); } } // Thumbnail delete $parts = pathinfo($file); $thumbnail = $this->options['destination_folder'] . $parts['filename'] . '_thumb.' . $parts['extension']; if (file_exists($thumbnail)) { unlink($thumbnail); } // Also remove the image from the gallery info file. GalleryHelper::removeImageFromGalleryInfoFile(rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $source); } } } /** * Returns the gallery style. * * @return string */ private function getStyle() { $style = $this->options['style']; // Get aspect ratio for source image, original image resized and thumbnail $thumb_height = intval($this->options['thumb_height']); $thumb_aspect_ratio = $thumb_height ? intval($this->options['thumb_width']) / $thumb_height : 0; $source_image_height = intval($this->options['source_image_resize_height']); $source_image_aspect_ratio = $source_image_height ? intval($this->options['source_image_resize_width']) / $source_image_height : 0; $original_image_height = intval($this->options['original_image_resize_height']); $original_image_aspect_ratio = $original_image_height ? intval($this->options['original_image_resize_width']) / $original_image_height : 0; // Check whether the aspect ratio for thumb and lightbox image are the same and use `masonry` style $checking_aspect_ratio = $this->options['original_image_resize'] ? $original_image_aspect_ratio : $source_image_aspect_ratio; if ($thumb_aspect_ratio && $checking_aspect_ratio && $thumb_aspect_ratio === $checking_aspect_ratio) { return 'masonry'; } /** * If both thumbnail width & height are equal we use the `grid` style. */ if ($this->options['thumb_width'] === $this->options['thumb_height']) { $style = 'grid'; } /** * If the style is grid and we do not have a null or 0 thumb_height set the fade lightbox CSS Class. * * This CSS Class tells PhotoSwipe to use the fade transition. */ if ($style === 'grid' && (!is_null($this->options['thumb_height']) && $this->options['thumb_height'] !== '0')) { $this->options['css_class'] .= ' lightbox-fade'; } return $style; } /** * Parses the gallery items by finding all iamges to display from all * different sources. * * @return void */ private function parseGalleryItems() { // If it's a string, we assume its a path to a folder and we convert it to an array. $this->options['items'] = (array) $this->options['items']; $items = []; foreach ($this->options['items'] as $key => $value) { if (!$data = GalleryHelper::parseGalleryItems($value, $this->getAllowedFileTypes())) { continue; } $items = array_merge($items, $data); } // Ensure only unique image paths are used $items = array_unique($items, SORT_REGULAR); $this->options['items'] = $items; } /** * Returns the allowed file types in an array format. * * @return array */ public function getAllowedFileTypes() { $types = explode(',', $this->options['allowed_file_types']); $types = array_filter(array_map('trim', array_map('strtolower', $types))); return $types; } /** * Resizes the source images. * * @return mixed */ private function resizeSourceImages() { if (!$this->options['source_image_resize']) { return; } // We require either original image resize or thumbnails to be enabled if (!$this->options['original_image_resize'] && !$this->options['thumbnails']) { return; } foreach ($this->options['items'] as $key => &$item) { if (!isset($item['path'])) { continue; } // Skip if source does not exist if (!is_file($item['path'])) { continue; } $source = $item['path']; // Find source image in the destination folder if ($image_data = GalleryHelper::findSourceImageDetails($source, $this->options['destination_folder'])) { // If force resizing is disabled, continue if (!$this->options['force_resizing']) { continue; } else { // If the destination image has not been edited and exists, abort if (!$image_data['edited'] && file_exists($image_data['path'])) { continue; } } } if (is_null($this->options['source_image_resize_height'])) { Image::resizeAndKeepAspectRatio( $source, $this->options['source_image_resize_width'], $this->options['source_image_resize_image_quality'] ); } else { Image::resize( $source, $this->options['source_image_resize_width'], $this->options['source_image_resize_height'], $this->options['source_image_resize_image_quality'], $this->options['source_image_resize_method'] ); } } } /** * Resizes the original images. * * @return mixed */ private function resizeOriginalImages() { if (!$this->options['original_image_resize']) { return; } // Create destination folder if missing File::createDirs($this->options['destination_folder']); foreach ($this->options['items'] as $key => &$item) { if (!isset($item['path'])) { continue; } // Skip if source does not exist if (!is_file($item['path'])) { continue; } $source = $item['path']; $unique = true; // Path to resized image in destination folder $destination = $this->options['destination_folder'] . basename($source); // Find source image in the destination folder if ($image_data = GalleryHelper::findSourceImageDetails($source, $this->options['destination_folder'])) { // If force resizing is disabled and the original image exists, set the URL of the destination image if (!$this->options['force_resizing'] && file_exists($image_data['path'])) { $item['url'] = GalleryHelper::directoryImageToURL($image_data['path']); continue; } else { // If the destination image has not been edited and exists, abort if (!$image_data['edited'] && file_exists($image_data['path'])) { $item['url'] = GalleryHelper::directoryImageToURL($image_data['path']); continue; } // Since we are forcing resizing, overwrite the existing image, do not create a new unique image $unique = false; // The destination path is the same resized image $destination = $image_data['path']; } } $original_image_file = is_null($this->options['original_image_resize_height']) ? Image::resizeAndKeepAspectRatio( $source, $this->options['original_image_resize_width'], $this->options['original_image_resize_image_quality'], $destination, $unique ) : Image::resize( $source, $this->options['original_image_resize_width'], $this->options['original_image_resize_height'], $this->options['original_image_resize_image_quality'], $this->options['original_image_resize_method'], $destination, $unique ); if (!$original_image_file) { continue; } // Set image URL $item = array_merge($item, [ 'url' => GalleryHelper::directoryImageToURL($original_image_file) ]); // Update image data in Gallery Info File GalleryHelper::updateImageDataInGalleryInfoFile($source, $item); } } /** * Creates thumbnails. * * If `force_resizing` is enabled, it will re-generate thumbsnails under the following cases: * * - If a thumbnail does not exist. * - If the original image has been edited. * * @return mixed */ private function createThumbnails() { if (!$this->options['thumbnails']) { return false; } // Create destination folder if missing File::createDirs($this->options['destination_folder']); foreach ($this->options['items'] as $key => &$item) { // Skip items that do not have a path set if (!isset($item['path'])) { continue; } // Skip if source does not exist if (!is_file($item['path'])) { continue; } $source = $item['path']; $unique = true; $parts = pathinfo($source); $destination = $this->options['destination_folder'] . $parts['filename'] . '_thumb.' . $parts['extension']; // Find source image in the destination folder if ($image_data = GalleryHelper::findSourceImageDetails($source, $this->options['destination_folder'])) { /** * Use the found original image path to produce the thumb file path. * * This is used as we have multiple files with the same which produce file names of _copy_X * and thus the above $destination will not be valid. Instead, we use the original file name * to find the thumbnail file. */ if ($this->options['original_image_resize']) { $parts = pathinfo($image_data['path']); $destination = $this->options['destination_folder'] . $parts['filename'] . '_thumb.' . $parts['extension']; } // If force resizing is disabled and the thumbnail exists, set the URL of the destination image if (!$this->options['force_resizing'] && file_exists($destination)) { $item['thumbnail_url'] = GalleryHelper::directoryImageToURL($destination); continue; } else { // If the destination image has not been edited and exists, abort if (!$image_data['edited'] && file_exists($destination)) { $item['thumbnail_url'] = GalleryHelper::directoryImageToURL($destination); continue; } // Since we are forcing resizing, overwrite the existing image, do not create a new unique image $unique = false; } } // Generate thumbnails $thumb_file = is_null($this->options['thumb_height']) ? Image::resizeAndKeepAspectRatio( $source, $this->options['thumb_width'], $this->options['thumb_resize_quality'], $destination, $unique ) : Image::resize( $source, $this->options['thumb_width'], $this->options['thumb_height'], $this->options['thumb_resize_quality'], $this->options['thumb_resize_method'], $destination, $unique ); if (!$thumb_file) { continue; } // Set image thumbnail URL $item = array_merge($item, [ 'thumbnail_url' => GalleryHelper::directoryImageToURL($thumb_file) ]); // Update image data in Gallery Info File GalleryHelper::updateImageDataInGalleryInfoFile($source, $item); } } /** * Prepares the items. * * - Sets the thumbnails image dimensions. * - Assures caption property exist. * * @return mixed */ private function prepareItems() { if (!is_array($this->options['items']) || !count($this->options['items'])) { return; } foreach ($this->options['items'] as $key => &$item) { // Initialize image atts $item['img_atts'] = ''; // Initializes caption if none given if (!isset($item['caption'])) { $item['caption'] = ''; } $item['alt'] = !empty($item['caption']) ? mb_substr($item['caption'], 0, 100) : pathinfo($item['url'], PATHINFO_FILENAME); // Ensure a thumbnail is given if (!isset($item['thumbnail_url'])) { // If no thumbnail is given, set it to the full image $item['thumbnail_url'] = $item['url']; continue; } // If the thumbnail size for this item is given, set the image attributes if (isset($item['thumbnail_size'])) { $item['img_atts'] = 'width="' . $item['thumbnail_size']['width'] . '" height="' . $item['thumbnail_size']['height'] . '"'; continue; } } } /** * Sets CSS variables for the widget. * * @return void */ private function setCSSVariables() { $data = array_merge( $this->getColumns(), $this->getGap() ); $css = ''; foreach ($data as $key => $value) { $css .= '--' . $key . ':' . $value . ';'; } \JFactory::getDocument()->addStyleDeclaration(' .nrf-widget.' . $this->options['id'] . ' { ' . $css . ' }'); } /** * Returns the columns of the gallery. * * @return array */ private function getColumns() { if (is_string($this->options['columns'])) { $this->options['columns'] = (int) $this->options['columns']; } if (!is_int($this->options['columns']) && !is_array($this->options['columns'])) { return []; } $columns_defaults = [ 'columns' => 4, 'tablet-columns' => 2, 'mobile-columns' => 1 ]; $columns = []; // String if (is_int($this->options['columns'])) { $columns = [ 'columns' => $this->options['columns'], 'tablet-columns' => $this->options['columns'] !== 1 ? 2 : 1, 'mobile-columns' => 1 ]; } // Array if (is_array($this->options['columns'])) { if (isset($this->options['columns']['desktop'])) { $columns['columns'] = $this->options['columns']['desktop']; } if (isset($this->options['columns']['tablet'])) { $columns['tablet-columns'] = $this->options['columns']['tablet']; } if (isset($this->options['columns']['mobile'])) { $columns['mobile-columns'] = $this->options['columns']['mobile']; } } return array_merge($columns_defaults, $columns); } /** * Returns the gaps of the gallery. * * @return array */ private function getGap() { if (is_string($this->options['gap'])) { $this->options['gap'] = (int) $this->options['gap']; } if (!is_int($this->options['gap']) && !is_array($this->options['gap'])) { return []; } $gap_defaults = [ 'gap' => 0, 'tablet-gap' => 0, 'mobile-gap' => 0 ]; $gaps = []; // String if (is_int($this->options['gap'])) { $gaps = [ 'gap' => $this->options['gap'] . 'px', 'tablet-gap' => $this->options['gap'] . 'px', 'mobile-gap' => $this->options['gap'] . 'px' ]; } // Array if (is_array($this->options['gap'])) { if (isset($this->options['gap']['desktop'])) { $gaps['gap'] = $this->options['gap']['desktop'] . 'px'; } if (isset($this->options['gap']['tablet'])) { $gaps['tablet-gap'] = $this->options['gap']['tablet'] . 'px'; } if (isset($this->options['gap']['mobile'])) { $gaps['mobile-gap'] = $this->options['gap']['mobile'] . 'px'; } } return array_merge($gap_defaults, $gaps); } }PK!uff6system/nrframework/NRFramework/Widgets/RangeSlider.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Widgets; defined('_JEXEC') or die; /** * The Range Slider widget */ class RangeSlider extends Widget { /** * Widget default options * * @var array */ protected $widget_options = [ // The default value of the widget. 'value' => 0, // The minimum value of the slider 'min' => 0, // The maximum value of the slider 'max' => 100, // The step of the slider 'step' => 1, // The main slider color 'color' => '#1976d2', // The input border color of the slider inputs 'input_border_color' => '#bdbdbd', // The input background color of the slider inputs 'input_bg_color' => 'transparent' ]; /** * Class constructor * * @param array $options */ public function __construct($options = []) { parent::__construct($options); // Base color is 20% of given color $this->options['base_color'] = $this->options['color'] . '33'; // Calculate value $this->options['value'] = (int) $this->options['value'] < $this->options['min'] ? $this->options['min'] : ((int) $this->options['value'] > $this->options['max'] ? $this->options['max'] : (int) $this->options['value']); // Calculate bar percentage $this->options['bar_percentage'] = $this->options['max'] ? ~~(100 * ($this->options['value'] - $this->options['min']) / ($this->options['max'] - $this->options['min'])) : $this->options['value']; } }PK!j 'system/nrframework/NRFramework/File.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; use NRFramework\Mimes; defined( '_JEXEC' ) or die( 'Restricted access' ); class File { /** * Upload file * * @param array $file The request file as posted by form * @param string $upload_folder The upload folder where the file must be uploaded * @param string $allowed_file_types A comma separated list of allowed file types like: .jpg, .gif, .png * @param bool $allow_unsafe Allow the upload of unsafe files. See JFilterInput::isSafeFile() method. * @param bool $random_prefix If is set to true, the filename will get a random unique prefix * * @return mixed String on success, Null on failure */ public static function upload($file, $upload_folder = null, $allowed_file_types = [], $allow_unsafe = false, $random_prefix = null) { // Make sure we have a valid file array if (!isset($file['name']) || !isset($file['tmp_name'])) { throw new \Exception(\JText::sprintf('NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE', $file['name'])); } // Check file type self::checkMimeOrDie($allowed_file_types, $file); /** * Try transiterating the file name using the native php function * * This is used in 4.0 version of makeSafe but not in 3.X. * * If the given filename is non-latin, then all characters will be removed from the filename via makeSafe and thus * we wont be able to upload the file. * * @see https://github.com/joomla/joomla-cms/pull/27974 */ if (!defined('nrJ4') && function_exists('transliterator_transliterate') && function_exists('iconv')) { // Using iconv to ignore characters that can't be transliterated $file['name'] = iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", transliterator_transliterate('Any-Latin; Latin-ASCII; Lower()', $file['name'])); } // Sanitize filename $filename = \JFile::makeSafe($file['name']); if (!is_null($random_prefix)) { $filename = uniqid($random_prefix) . '_' . $filename; } $filename = str_replace(' ', '_', $filename); // Setup the full file name $upload_folder = is_null($upload_folder) ? self::getTempFolder() : $upload_folder; $destination_file = implode(DIRECTORY_SEPARATOR, [$upload_folder, $filename]); // If file exists, rename to copy_X self::uniquefy($destination_file); $destination_file = \JPath::clean($destination_file); if (!\JFile::upload($file['tmp_name'], $destination_file, false, $allow_unsafe)) { throw new \Exception(\JText::sprintf('NR_UPLOAD_ERROR_CANNOT_UPLOAD_FILE', $file['name'])); } return $destination_file; } /** * Moves a file from one directory to another. Destination directories will be created if they are not exist. * * @param [type] $source_file The source file path * @param [type] $destination_file The destination file path * @param bool $replace_existing Replace same files names, otherwise create a copy in the format copy_X * * @return mixed String on success */ public static function move($source_file, $destination_file, $replace_existing = false) { $destination_folder = dirname($destination_file); // Create destination folders recursively if (!self::createDirs($destination_folder)) { throw new \Exception(\JText::sprintf('NR_CANNOT_CREATE_FOLDER', $destination_folder)); } // Don't replace files with the same name. Instead, append copy_x to this one. if (!$replace_existing) { self::uniquefy($destination_file); } // Move file to the destination folder if (!\JFile::move($source_file, $destination_file)) { throw new \Exception(\JText::sprintf('NR_CANNOT_MOVE_FILE', $destination_file)); } return \JPath::clean($destination_file); } /** * Reads (and checks) the temp Joomla folder * * @return string */ public static function getTempFolder() { $ds = DIRECTORY_SEPARATOR; $tmpdir = \JFactory::getConfig()->get('tmp_path'); if (realpath($tmpdir) == $ds . 'tmp') { $tmpdir = JPATH_SITE . $ds . 'tmp'; } elseif (!\JFolder::exists($tmpdir)) { $tmpdir = JPATH_SITE . $ds . 'tmp'; } return \JPath::clean(trim($tmpdir) . $ds); } /** * Checks if the path exists. If not creates the folders as well as subfolders. * * @param string $path The folder path * @param string $protect If set to true, each folder will be protected by disabling PHP engine and preventing folder browsing * * @return bool */ public static function createDirs($path, $protect = true) { if (!\JFolder::exists($path)) { mkdir($path, 0755, true); // New folder created. Let's protect it. if ($protect) { self::writeHtaccessFile($path); self::writeIndexHtmlFile($path); } } // Make sure the folder is writable return @is_writable($path); } /** * Checks whether a file type is in an allowed list * * @param mixed $allowed_types Array or a comma separated list of allowed file extensions or mime types. Eg: .jpg, .png, applicaton/pdf * @param string $file_object The uploaded file as appears in the $_FILES array * * @return bool */ public static function checkMimeOrDie($allowed_types, $file_object) { $file_path = $file_object['tmp_name']; $file_name = isset($file_object['name']) ? $file_object['name'] : basename($file_path); // Do we have a mime type detected? if (!$mime_type = Mimes::detectFileType($file_path)) { throw new \Exception(\JText::sprintf('NR_UPLOAD_NO_MIME_TYPE', $file_name)); } if (!Mimes::check($allowed_types, $mime_type)) { throw new \Exception(\JText::sprintf('NR_UPLOAD_INVALID_FILE_TYPE', $file_name, $mime_type, $allowed_types)); } } /** * Add an .htaccess file to the folder in order to disable PHP engine entirely * * @param string $path The path where to write the file * * @return void */ public static function writeHtaccessFile($path) { $content = ' # Block direct PHP access deny from all '; \JFile::write($path . '/.htaccess', $content); } /** * Creates an empty index.html file to prevent directory listing * * @param string $path The path where to write the file * * @return void */ public static function writeIndexHtmlFile($path) { \JFile::write($path . '/index.html', ''); } /** * Generates a unique filename in case the give name already exists by appending copy_X suffix to filename. * * @param strimg $path * * @return void */ public static function uniquefy(&$path) { $path_parts = self::pathinfo($path); $dir = $path_parts['dirname']; $ext = $path_parts['extension']; $actual_name = $path_parts['filename']; $original_name = $actual_name; $i = 1; while(\JFile::exists($dir . '/' . $actual_name . '.' . $ext)) { $actual_name = (string) $original_name . '_copy_' . $i; $path = $dir . '/' . $actual_name . '.' . $ext; $i++; } } /** * Returns information about a file path with multi-byte support * * @param string $path The path to be parsed. * * @return array */ public static function pathinfo($path) { // Store temporary the currenty locale $currentLocale = setlocale(LC_ALL, 0); setlocale(LC_ALL, 'C.UTF-8'); $pathinfo = pathinfo($path); // Set back to previus value setlocale(LC_ALL, $currentLocale); return $pathinfo; } }PK!˅,system/nrframework/NRFramework/SmartTags.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use \NRFramework\SmartTags\SmartTags instead. */ // No direct access defined('_JEXEC') or die;PK!']>system/nrframework/NRFramework/Conditions/ConditionsHelper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions; use NRFramework\Factory; defined('_JEXEC') or die; /** * Conditions Helper Class * * Singleton */ class ConditionsHelper { /** * Factory object * * @var \NRFramework\Factory */ protected $factory; /** * Class constructor */ public function __construct($factory = null) { $this->factory = is_null($factory) ? new Factory() : $factory; } /** * Get only one instance of the class * * @return object */ static public function getInstance($factory = null) { static $instance = null; if ($instance === null) { $instance = new ConditionsHelper($factory); } return $instance; } /** * Passes a set of groups which are connected with OR comparison operator. * * Expected object: * * $groups = [ * [ * mathing_method => string (all|any), * rules => array * ], * [ * mathing_method => string (all|any), * rules => array * ] * ... * ]; * * @param array $groups * * @return mixed On validation error return null, if validation runs return bool */ public function passSets($groups) { $pass = null; // Validations if (!is_array($groups) OR (is_array($groups) AND empty($groups))) { return $pass; } foreach ($groups as $group) { // Skip invalid groups if (!isset($group['rules']) OR !is_array($group['rules']) OR (is_array($group['rules']) AND empty($group['rules']))) { continue; } $matching_method = isset($group['matching_method']) ? $group['matching_method'] : 'all'; // If a group meets the condition, pass the check and abort so no further tests are executed. if ($pass = $this->passSet($group['rules'], $matching_method)) { break; } } return $pass; } /** * Passes a set of rules. * * Expected object for rules: * * $rules = [ * [ * name => string, * value => mixed, * operator => string, * params => array * ], * [ * name => string, * value => mixed, * operator => string, * params => array * ] * ... * ]; * * @param array $rules * @param string $matchingMethod * * @return bool */ public function passSet($rules, $matchingMethod) { $pass = null; // Validations if (!is_array($rules) OR (is_array($rules) AND empty($rules))) { return $pass; } foreach ($rules as $rule) { // Skip unknown rules if (!isset($rule['name'])) { continue; } // Validate rule $params = isset($rule['params']) ? $rule['params'] : null; $value = isset($rule['value']) ? $rule['value'] : ''; $operator = isset($rule['operator']) ? $rule['operator'] : ''; // Run checks $pass = $this->passOne($rule['name'], $value, $operator, $params); // Check no further the Ruleset when any of the following happens: // 1. We expect ALL Rules to pass but one fails. // 2. We expect ANY Rule to pass and one does so. if ((!$pass AND $matchingMethod == 'all') OR ($pass AND $matchingMethod == 'any')) { break; } } return $pass; } /** * Execute given rnule * * @param string $name The name of the rule. Case-sensitive. * @param mixed $selection The value to compare with the value returned by the rule. * @param string $operator The operator to use to do the comparison * @param array $params Optional rule parameters * @return mixed Null when the validation doesn't run properly, bool otherwize */ public function passOne($name, $selection, $operator, $params = []) { if (!$rule = $this->getCondition($name, $selection, str_replace('not_', '', $operator), $params)) { return; } $pass = $rule->pass(); if (is_null($pass)) { return $pass; } return strpos($operator, 'not_') !== false ? !$pass : $pass; } /** * Initialize the condition class object * * @param string $name The name of the rule. Case-sensitive. * @param mixed $selection The value to compare with the value returned by the rule. * @param string $operator The operator to use to do the comparison * @param array $params Optional rule parameters * @return mixed Null on failure, object on success */ public function getCondition($name, $selection = null, $operator = null, $params = null) { if (!$name) { return; } $class = __NAMESPACE__ . '\\Conditions\\' . $name; if (!class_exists($class)) { return; } // Prepare rule options $options = [ 'selection' => $selection, 'operator' => str_replace('not_', '', $operator), 'params' => $params ]; $rule = new $class($options, $this->factory); return $rule; } /** * Validate and manipulate rules before they are get stored into the database. * * @param array $rules * * @return void */ public function onBeforeSave(&$rules) { // If its a string, transform it into an array, otherwise, use the actual value (array) $rules = is_string($rules) ? json_decode($rules, true) : $rules; foreach ($rules as &$group) { if (!isset($group['rules'])) { continue; } foreach ($group['rules'] as &$rule) { if (!$condition = $this->getCondition($rule['name'])) { continue; } if (!\method_exists($condition, 'onBeforeSave')) { continue; } $condition->onBeforeSave($rule); } } } }PK!.΀@@Esystem/nrframework/NRFramework/Conditions/Conditions/ConvertForms.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class ConvertForms extends Condition { /** * Returns the assignment's value * * @return array List of campaign IDs */ public function value() { return $this->getCampaigns(); } /** * Returns campaigns list visitor is subscribed to * If the user is logged in, we try to get the campaigns by user's ID * Otherwise, the visitor cookie ID will be used instead * * @return array List of campaign IDs */ private function getCampaigns() { @include_once JPATH_ADMINISTRATOR . '/components/com_convertforms/helpers/convertforms.php'; if (!class_exists('ConvertFormsHelper')) { return; } return \ConvertFormsHelper::getVisitorCampaigns(); } }PK!?>>?system/nrframework/NRFramework/Conditions/Conditions/Device.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class Device extends Condition { /** * Returns the assignment's value * * @return string Device type */ public function value() { return $this->factory->getDevice(); } /** * A one-line text that describes the current value detected by the rule. Eg: The current time is %s. * * @return string */ public function getValueHint() { return parent::getValueHint() . ' ' . \JText::_('NR_ASSIGN_DEVICES_NOTE'); } }PK! R  <system/nrframework/NRFramework/Conditions/Conditions/URL.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; class URL extends URLBase { /** * Returns the assignment's value * * @return string Current URL */ public function value() { return $this->factory->getURL(); } }PK!VCsystem/nrframework/NRFramework/Conditions/Conditions/AkeebaSubs.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class AkeebaSubs extends Condition { /** * Returns the assignment's value * * @return array Akeeba Subscriptions */ public function value() { return $this->getlevels(); } /** * Returns all user's active subscriptions * * @param int $userid User's id * * @return array Akeeba Subscriptions */ private function getLevels() { if (!$user = $this->user->id) { return false; } if (!defined('FOF30_INCLUDED') && !@include_once(JPATH_LIBRARIES . '/fof30/include.php')) { return false; } // Get the Akeeba Subscriptions container. Also includes the autoloader. $container = \FOF30\Container\Container::getInstance('com_akeebasubs'); $subscriptionsModel = $container->factory->model('Subscriptions')->tmpInstance(); $items = $subscriptionsModel ->user_id($user) ->enabled(1) ->get(); if (!$items->count()) { return false; } $levels = array(); foreach ($items as $subscription) { $levels[] = $subscription->akeebasubs_level_id; } return array_unique($levels); } }PK!\llBsystem/nrframework/NRFramework/Conditions/Conditions/Pageviews.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class Pageviews extends Condition { /** * Returns the assignment's value * * @return int Number of page visits */ public function value() { return $this->factory->getSession()->get('session.counter', 0); } }PK!&CC@system/nrframework/NRFramework/Conditions/Conditions/URLBase.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Functions; use NRFramework\Conditions\Condition; class URLBase extends Condition { public function prepareSelection() { return Functions::makeArray($this->getSelection()); } /** * Pass URL. * * @return bool Returns true if the current URL contains any of the selection URLs */ public function pass() { return $this->passURL(); } /** * Pass URL * * @param mixed $url If null, the current URL will be used. Otherwise we need a valid absolute URL. * * @return bool Returns true if the URL contains any of the selection URLs */ public function passURL($url = null) { // Get the current URL if none is passed $url = is_null($url) ? $this->factory->getURL() : $url; // Create an array with all possible values of the URL $urls = array( html_entity_decode(urldecode($url), ENT_COMPAT, 'UTF-8'), urldecode($url), html_entity_decode($url, ENT_COMPAT, 'UTF-8'), $url ); // Remove duplicates and invalid URLs $urls = array_filter(array_unique($urls)); $regex = $this->params->get('regex', false); $pass = false; foreach ($urls as $url) { foreach ($this->getSelection() as $s) { // Skip empty selection URLs $s = trim($s); if (empty($s)) { continue; } // Regular expression check if ($regex) { $url_part = str_replace(array('#', '&'), array('\#', '(&|&)'), $s); $s = '#' . $url_part . '#si'; if (@preg_match($s . 'u', $url) || @preg_match($s, $url)) { $pass = true; break; } continue; } // String check if (strpos($url, $s) !== false) { $pass = true; break; } } if ($pass) { break; } } return $pass; } }PK!Ea^^Isystem/nrframework/NRFramework/Conditions/Conditions/Joomla/Component.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Joomla; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class Component extends Condition { /** * Returns the assignment's value * * @return string The component's name */ public function value() { return $this->app->input->get('option'); } }PK!Dsystem/nrframework/NRFramework/Conditions/Conditions/Joomla/Menu.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Joomla; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class Menu extends Condition { protected $itemID = null; public function __construct($options, $factory) { parent::__construct($options, $factory); $this->itemID = $this->app->input->getInt('Itemid', 0); } /** * Pass check for menu items * * @return bool */ public function pass() { $includeChildren = $this->params->get('inc_children', false); $includeNoItemID = $this->params->get('noitem', false); // Pass if selection is empty or the itemid is missing if (!$this->itemID || empty($this->selection)) { return $includeNoItemID; } // return true if menu type is in selection $menutype = 'type.' . $this->getMenuType(); if ($includeChildren && in_array($menutype, $this->selection)) { return true; } // return true if menu is in selection and we are not including child items only if (in_array($this->itemID, $this->selection)) { return ($includeChildren != 2); } // Let's discover child items. // Obviously if the option is disabled return false. if (!$includeChildren) { return false; } // Get menu item parents $parent_ids = $this->getParentIds($this->itemID); $parent_ids = array_diff($parent_ids, array('1')); foreach ($parent_ids as $id) { if (!in_array($id, $this->selection)) { continue; } return true; } return false; } /** * Returns the assignment's value * * @return integer Menu ID */ public function value() { return $this->itemID; } /** * Get active menu items's menu type * * @return bool False on failure, string on success */ private function getMenuType() { if (empty($this->itemID)) { return; } $menu = $this->app->getMenu()->getItem((int) $this->itemID); return isset($menu->menutype) ? $menu->menutype : false; } }PK!Ԯ3 Hsystem/nrframework/NRFramework/Conditions/Conditions/Joomla/Language.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Joomla; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class Language extends Condition { /** * Returns the assignment's value * * @return array Language strings */ public function value() { $lang = $this->factory->getLanguage(); $lang_strings = $lang->getLocale(); $lang_strings[] = $lang->getTag(); return $lang_strings; } }PK!yKna((Fsystem/nrframework/NRFramework/Conditions/Conditions/Joomla/UserID.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Joomla; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class UserID extends Condition { /** * Returns the assignment's value * * @return int User ID */ public function value() { return $this->user->id; } }PK!r쵗Isystem/nrframework/NRFramework/Conditions/Conditions/Joomla/UserGroup.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Joomla; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class UserGroup extends Condition { /** * Get the user's authorized groups * * @return array User groups */ public function value() { return $this->user->getAuthorisedGroups(); } /** * A one-line text that describes the current value detected by the rule. Eg: The current time is %s. * * @return string */ public function getValueHint() { $db = $this->db; $query = $db->getQuery(true) ->select($db->qn('title')) ->from('#__usergroups') ->where($db->qn('id') . ' IN ' . '(' . implode(',', $this->value()) . ')'); $db->setQuery($query); $value = implode(', ', $db->loadColumn()); return \JText::sprintf('NR_DISPLAY_CONDITIONS_HINT_' . strtoupper($this->getName()), $value); } }PK!cxKsystem/nrframework/NRFramework/Conditions/Conditions/Joomla/AccessLevel.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Joomla; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class AccessLevel extends Condition { /** * Get the user's authorized view levels * * @return array User groups */ public function value() { return $this->user->getAuthorisedViewLevels(); } /** * A one-line text that describes the current value detected by the rule. Eg: The current time is %s. * * @return string */ public function getValueHint() { $db = $this->db; $query = $db->getQuery(true) ->select($db->qn('title')) ->from('#__viewlevels') ->where($db->qn('id') . ' IN ' . '(' . implode(',', $this->value()) . ')'); $db->setQuery($query); $value = implode(', ', $db->loadColumn()); return \JText::sprintf('NR_DISPLAY_CONDITIONS_HINT_' . strtoupper($this->getName()), $value); } }PK!^ooCsystem/nrframework/NRFramework/Conditions/Conditions/TimeOnSite.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class TimeOnSite extends Condition { /** * Returns the assignment's value * * @return int Time on site in seconds */ public function value() { return $this->getTimeOnSite(); } /** * Returns the user's time on site in seconds * * @return int */ public function getTimeOnSite() { if (!$sessionStartTime = strtotime($this->getSessionStartTime())) { return; } $dateTimeNow = strtotime(\NRFramework\Functions::dateTimeNow()); return $dateTimeNow - $sessionStartTime; } /** * Returns the sessions start time * * @return string */ private function getSessionStartTime() { $session = $this->factory->getSession(); $var = 'starttime'; $sessionStartTime = $session->get($var); if (!$sessionStartTime) { $date = \NRFramework\Functions::dateTimeNow(); $session->set($var, $date); } return $session->get($var); } }PK!99@system/nrframework/NRFramework/Conditions/Conditions/Browser.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class Browser extends Condition { /** * Returns the assignment's value * * @return string Browser name */ public function value() { return $this->factory->getBrowser()['name']; } }PK!Z;system/nrframework/NRFramework/Conditions/Conditions/OS.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\WebClient; use NRFramework\Functions; use NRFramework\Conditions\Condition; class OS extends Condition { /** * Check the client's operating system * * @return bool */ public function prepareSelection() { $selection = Functions::makeArray($this->getSelection()); // backwards compatibility check // replace 'iphone' and 'ipad' selection values with 'ios' return array_map(function($os_selection) { if ($os_selection === 'iphone' || $os_selection === 'ipad') { return 'ios'; } return $os_selection; }, $selection); } /** * Returns the assignment's value * * @return string OS name */ public function value() { return WebClient::getOS(); } }PK!! iRsystem/nrframework/NRFramework/Conditions/Conditions/Component/JCalProCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JCalProCategory extends JCalProBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('categories', 'parent_id'); } }PK!Nsystem/nrframework/NRFramework/Conditions/Conditions/Component/SobiProBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class SobiProBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'entry'; /** * The component's option name * * @var string */ protected $component_option = 'com_sobipro'; /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options, $factory) { parent::__construct($options, $factory); $this->request->view = 'entry'; // Make sure SPRequest is loaded if (!class_exists('SPRequest')) { return; } $this->request->id = (int) \SPRequest::sid(); } /** * Indicates whether the page is a single page * * @return boolean */ public function isSinglePage() { return (parent::isSinglePage() && $this->request->task == 'entry.details'); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('pid') ->from('#__sobipro_relations') ->where($db->quoteName('id') . '=' . $db->q($id)) ->where($db->quoteName('oType') . " = 'entry'"); $db->setQuery($query); return $db->loadColumn(); } }PK!бٍQsystem/nrframework/NRFramework/Conditions/Conditions/Component/EasyBlogSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EasyBlogSingle extends EasyBlogBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!? Lsystem/nrframework/NRFramework/Conditions/Conditions/Component/ZooSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class ZooSingle extends ZooBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK! WPsystem/nrframework/NRFramework/Conditions/Conditions/Component/SobiProSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class SobiProSingle extends SobiProBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!-33Osystem/nrframework/NRFramework/Conditions/Conditions/Component/EasyBlogBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EasyBlogBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'entry'; /** * The component's option name * * @var string */ protected $component_option = 'com_easyblog'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('category_id') ->from('#__easyblog_post') ->where($db->quoteName('id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!qSsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJEventsCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJEventsCategory extends DJEventsBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('djev_cats', 'parent_id'); } }PK!몙Hsystem/nrframework/NRFramework/Conditions/Conditions/Component/K2Tag.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class K2Tag extends K2Base { /** * Pass check for K2 Tags * * @return bool */ public function pass() { if (empty($this->selection) || !$this->passContext()) { return false; } return parent::pass(); } /** * Returns the assignment's value * * @return array K2 item tags */ public function value() { return $this->getK2tags(); } }PK! )<<Osystem/nrframework/NRFramework/Conditions/Conditions/Component/DJEventsBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJEventsBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'event'; /** * The component's option name * * @var string */ protected $component_option = 'com_djevents'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select($db->quoteName('cat_id')) ->from('#__djev_events') ->where($db->quoteName('id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!Ř..^system/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryEventBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryEventBase extends JBusinessDirectoryBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'event'; /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options = null, $factory = null) { parent::__construct($options, $factory); $this->request->id = (int) $this->app->input->getInt('eventId'); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select($db->quoteName('categoryId')) ->from('#__jbusinessdirectory_company_event_category') ->where($db->quoteName('eventId') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!SA..^system/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryOfferBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryOfferBase extends JBusinessDirectoryBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'offer'; /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options = null, $factory = null) { parent::__construct($options, $factory); $this->request->id = (int) $this->app->input->getInt('offerId'); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select($db->quoteName('categoryId')) ->from('#__jbusinessdirectory_company_offer_category') ->where($db->quoteName('offerId') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!y )Nsystem/nrframework/NRFramework/Conditions/Conditions/Component/J2StoreBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class J2StoreBase extends ComponentBase { /** * The component's option name * * @var string */ protected $component_option = 'com_j2store'; /** * Indicates whether the page is a category page * * @return boolean */ protected function isCategory() { return is_null($this->request->task); } /** * Indicates whether the page is a single page * * @return boolean */ public function isSinglePage() { return (in_array($this->request->view, ['products', 'producttags']) && $this->request->task == 'view'); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { // Get product information require_once JPATH_ADMINISTRATOR . '/components/com_j2store/helpers/product.php'; // Make sure J2Store is loaded if (!class_exists('J2Product')) { return; } $item = \J2Product::getInstance()->setId($this->request->id)->getProduct(); if (!is_object($item) || !isset($item->source)) { return; } return $item->source->catid; } }PK!$#fVsystem/nrframework/NRFramework/Conditions/Conditions/Component/SPPageBuilderSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class SPPageBuilderSingle extends SPPageBuilderBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!ܙJsystem/nrframework/NRFramework/Conditions/Conditions/Component/ZooBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class ZooBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'item'; /** * The component's option name * * @var string */ protected $component_option = 'com_zoo'; /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options, $factory) { parent::__construct($options, $factory); $this->request->view = $this->app->input->get('view', $this->app->input->get('task')); // Normally the item's id can be read by the request parameters BUT if the item // is assosiated to a menu item the item_id parameter is not yet available and // we can only find it out through the menu's parameters. $this->request->id = (int) $this->app->input->getInt('item_id', $this->app->getMenu()->getActive()->getParams()->get('item_id')); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('category_id') ->from('#__zoo_category_item') ->where($db->quoteName('item_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!Rfcsystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryBusinessSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryBusinessSingle extends JBusinessDirectoryBusinessBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!*[*Qsystem/nrframework/NRFramework/Conditions/Conditions/Component/RSBlogCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class RSBlogCategory extends RSBlogBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('rsblog_categories', 'parent_id'); } }PK! Msystem/nrframework/NRFramework/Conditions/Conditions/Component/K2Pagetype.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class K2Pagetype extends K2Base { /** * Pass check for K2 page types * * @return bool */ public function pass() { if (empty($this->selection) || !$this->passContext()) { return false; } return parent::pass(); } /** * Returns the assignment's value * * @return string Pagetype */ public function value() { return $this->getPageType(); } }PK!$>66Tsystem/nrframework/NRFramework/Conditions/Conditions/Component/SPPageBuilderBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class SPPageBuilderBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'page'; /** * The component's option name * * @var string */ protected $component_option = 'com_sppagebuilder'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('catid') ->from('#__sppagebuilder') ->where($db->quoteName('id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!mUsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJCatalog2Category.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJCatalog2Category extends DJCatalog2Base { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('djc2_categories'); } }PK!PAmTPsystem/nrframework/NRFramework/Conditions/Conditions/Component/JShoppingBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JShoppingBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'product'; /** * The component's option name * * @var string */ protected $component_option = 'com_jshopping'; /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options, $factory) { parent::__construct($options, $factory); $this->request->view = $this->app->input->get('view', $this->app->input->get('controller')); $this->request->id = $this->app->input->getInt('product_id'); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('category_id') ->from('#__jshopping_products_to_categories') ->where($db->quoteName('product_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!Psystem/nrframework/NRFramework/Conditions/Conditions/Component/GridboxSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class GridboxSingle extends GridboxBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!EKsystem/nrframework/NRFramework/Conditions/Conditions/Component/QuixBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class QuixBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'page'; /** * The component's option name * * @var string */ protected $component_option = 'com_quix'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('catid') ->from('#__quix') ->where($db->quoteName('id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!"wmDDbsystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryOfferCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryOfferCategory extends JBusinessDirectoryOfferBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('jbusinessdirectory_categories', 'parent_id'); } }PK!\JJesystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryBusinessCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryBusinessCategory extends JBusinessDirectoryBusinessBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('jbusinessdirectory_categories', 'parent_id'); } }PK!!ćOsystem/nrframework/NRFramework/Conditions/Conditions/Component/HikashopBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class HikaShopBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'product'; /** * The component's option name * * @var string */ protected $component_option = 'com_hikashop'; /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options, $factory) { parent::__construct($options, $factory); $this->request->id = $this->app->input->get('cid', $this->app->input->getInt('product_id')); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('category_id') ->from('#__hikashop_product_category') ->where($db->quoteName('product_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!']ˍQsystem/nrframework/NRFramework/Conditions/Conditions/Component/HikashopSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class HikashopSingle extends HikashopBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!/Wsystem/nrframework/NRFramework/Conditions/Conditions/Component/EventBookingCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EventBookingCategory extends EventBookingBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('eb_categories', 'parent'); } }PK!6 nasystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryBusinessBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryBusinessBase extends JBusinessDirectoryBase { /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options = null, $factory = null) { parent::__construct($options, $factory); $this->request->id = (int) $this->app->input->getInt('companyId'); } }PK!—Nsystem/nrframework/NRFramework/Conditions/Conditions/Component/EshopSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EshopSingle extends EshopBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!~&`system/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryOfferSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryOfferSingle extends JBusinessDirectoryOfferBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!m)Rsystem/nrframework/NRFramework/Conditions/Conditions/Component/ContentCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class ContentCategory extends ContentBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories(); } }PK!<Ssystem/nrframework/NRFramework/Conditions/Conditions/Component/EasyBlogCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EasyBlogCategory extends EasyBlogBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('easyblog_category', 'parent_id'); } }PK!Qsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJEventsSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJEventsSingle extends DJEventsBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!Msystem/nrframework/NRFramework/Conditions/Conditions/Component/QuixSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class QuixSingle extends QuixBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!4.ZOsystem/nrframework/NRFramework/Conditions/Conditions/Component/RSBlogSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class RSBlogSingle extends RSBlogBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!@Usystem/nrframework/NRFramework/Conditions/Conditions/Component/EventBookingSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EventBookingSingle extends EventBookingBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!+eiRsystem/nrframework/NRFramework/Conditions/Conditions/Component/JShoppingSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JShoppingSingle extends JShoppingBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!KPsystem/nrframework/NRFramework/Conditions/Conditions/Component/ComponentBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; use NRFramework\Functions; /** * Base class used by component-based assignments. Class properties defaults to com_content. */ abstract class ComponentBase extends Condition { /** * The component's Category Page view name * * @var string */ protected $viewCategory = 'category'; /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'article'; /** * The component's option name * * @var string */ protected $component_option = 'com_content'; /** * Request information * * @var mixed */ protected $request = null; /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options = null, $factory = null) { parent::__construct($options, $factory); $request = new \stdClass; $request->view = $this->app->input->get('view'); $request->task = $this->app->input->get('task'); $request->option = $this->app->input->get('option'); $request->layout = $this->app->input->get('layout'); $request->id = $this->app->input->getInt('id'); $this->request = $request; } /** * Returns the assignment's value * * @return array Category IDs */ public function value() { return $this->getCategoryIds(); } /** * Indicates whether the current view concerns a Category view * * @return boolean */ protected function isCategoryPage() { return ($this->request->view == $this->viewCategory); } /** * Indicates whether the current view concerncs a Single Page view * * @return boolean */ public function isSinglePage() { return ($this->request->view == $this->viewSingle); } /** * Check if we are in the right context and we're manipulating the correct component * * @return bool */ protected function passContext() { return ($this->request->option == $this->component_option); } /** * Returns category IDs based * * @return array */ protected function getCategoryIDs() { $id = $this->request->id; // Make sure we have an ID. if (empty($id)) { return; } // If this is a Category page, return the Category ID from the Query String if ($this->isCategoryPage()) { return (array) $id; } // If this is a Single Page, return all assosiated Category IDs. if ($this->isSinglePage()) { return $this->getSinglePageCategories($id); } } /** * Checks whether the current page is within the selected categories * * @param string $ref_table The referenced table * @param string $ref_parent_column The name of the parent column in the referenced table * * @return boolean */ protected function passCategories($ref_table = 'categories', $ref_parent_column = 'parent_id') { if (empty($this->selection) || !$this->passContext()) { return false; } // Include Children switch: 0 = No, 1 = Yes, 2 = Child Only $inc_children = $this->params->get('inc_children'); // Setup supported views $view_single = $this->params->get('view_single', true); $view_category = $this->params->get('view_category', false); // Check if we are in a valid context if (!($view_category && $this->isCategoryPage()) && !($view_single && $this->isSinglePage())) { return false; } // Start Checks $pass = false; // Get current page assosiated category IDs. It can be a single ID of the current Category view or multiple IDs assosiated to active item. $catids = $this->getCategoryIds(); $catids = is_array($catids) ? $catids : (array) $catids; foreach ($catids as $catid) { $pass = in_array($catid, $this->selection); if ($pass) { // If inc_children is either disabled or set to 'Also on Childs', there's no need for further checks. // The condition is already passed. if (in_array($this->params->get('inc_children'), [0, 1])) { break; } // We are here because we need childs only. Disable pass and continue checking parent IDs. $pass = false; } // Pass check for child items if (!$pass && $this->params->get('inc_children')) { $parent_ids = $this->getParentIDs($catid, $ref_table, $ref_parent_column); foreach ($parent_ids as $id) { if (in_array($id, $this->selection)) { $pass = true; break 2; } } unset($parent_ids); } } return $pass; } /** * Check whether this page passes the validation * * @return void */ protected function passSinglePage() { // Make sure we are in the right context if (empty($this->selection) || !$this->passContext() || !$this->isSinglePage()) { return false; } if (!is_array($this->selection)) { $this->selection = Functions::makeArray($this->selection); } return parent::pass(); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * @return array */ abstract protected function getSinglePageCategories($id); }PK!CmDDbsystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryEventCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryEventCategory extends JBusinessDirectoryEventBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('jbusinessdirectory_categories', 'parent_id'); } }PK!ɉqSsystem/nrframework/NRFramework/Conditions/Conditions/Component/VirtueMartSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class VirtueMartSingle extends VirtueMartBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!":ĺMsystem/nrframework/NRFramework/Conditions/Conditions/Component/K2Category.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class K2Category extends K2Base { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('k2_categories', 'parent'); } }PK!DSsystem/nrframework/NRFramework/Conditions/Conditions/Component/HikashopCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class HikashopCategory extends HikashopBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('hikashop_category', 'category_parent_id'); } /** * Returns all parent rows * * @param integer $id Row primary key * @param string $table Table name * @param string $parent Parent column name * @param string $child Child column name * * @return array Array with IDs */ public function getParentIds($id = 0, $table = 'hikashop_category', $parent = 'category_parent_id', $child = 'category_id') { return parent::getParentIds($id, $table, $parent, $child); } }PK!^TAwwYsystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'companies'; /** * The component's option name * * @var string */ protected $component_option = 'com_jbusinessdirectory'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select($db->quoteName('categoryId')) ->from('#__jbusinessdirectory_company_category') ->where($db->quoteName('companyId') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!}22Nsystem/nrframework/NRFramework/Conditions/Conditions/Component/GridboxBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class GridboxBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'page'; /** * The component's option name * * @var string */ protected $component_option = 'com_gridbox'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('page_category') ->from('#__gridbox_pages') ->where($db->quoteName('id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!aΑSsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJCatalog2Single.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJCatalog2Single extends DJCatalog2Base { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!c$Vsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJClassifiedsSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJClassifiedsSingle extends DJClassifiedsBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!DOOSsystem/nrframework/NRFramework/Conditions/Conditions/Component/EventBookingBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EventBookingBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'event'; /** * The component's option name * * @var string */ protected $component_option = 'com_eventbooking'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('category_id') ->from('#__eb_event_categories') ->where($db->quoteName('event_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!vRsystem/nrframework/NRFramework/Conditions/Conditions/Component/GridboxCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class GridboxCategory extends GridboxBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('gridbox_categories', 'parent'); } }PK!`?cNsystem/nrframework/NRFramework/Conditions/Conditions/Component/ZooCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class ZooCategory extends ZooBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('zoo_category', 'parent'); } }PK!WPsystem/nrframework/NRFramework/Conditions/Conditions/Component/J2StoreSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class J2StoreSingle extends J2StoreBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!Rsystem/nrframework/NRFramework/Conditions/Conditions/Component/J2StoreCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class J2StoreCategory extends J2StoreBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories(); } }PK!ͦ|88Msystem/nrframework/NRFramework/Conditions/Conditions/Component/RSBlogBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class RSBlogBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'post'; /** * The component's option name * * @var string */ protected $component_option = 'com_rsblog'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('cat_id') ->from('#__rsblog_posts_categories') ->where($db->quoteName('post_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!n Isystem/nrframework/NRFramework/Conditions/Conditions/Component/K2Base.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class K2Base extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'item'; /** * The component's option name * * @var string */ protected $component_option = 'com_k2'; /** * Get single page's assosiated categories * * @param integer The Single Page id * * @return integer */ protected function getSinglePageCategories($id) { $item = $this->getK2Item(); return isset($item->catid) ? $item->catid : null; } /** * Indicates whether the current view concerns a Category view * * @return boolean */ protected function isCategoryPage() { return ($this->request->layout == 'category' || $this->request->task == 'category' || $this->request->view == 'latest'); } /** * Returns a K2 item * * @return object|null */ public function getK2Item() { $cache = $this->factory->getcache(); $hash = md5('k2assitem'); if ($cache->has($hash)) { return $cache->get($hash); } return $cache->set($hash, \JModelLegacy::getInstance('Item', 'K2Model')->getData()); } /** * Return tags of a K2 item * * @param int $id K2 item ID * * @return array */ public function getK2tags($id = null) { $id = is_null($id) ? $this->request->id : $id; if (!$id) { return []; } $cache = $this->factory->getcache(); $hash = md5('k2_item_tags' . $id); if ($cache->has($hash)) { return $cache->get($hash); } $q = $this->db->getQuery(true) ->select('t.id') ->from('#__k2_tags_xref AS tx') ->join('LEFT', '#__k2_tags AS t ON t.id = tx.tagID') ->where('tx.itemID = ' . $this->db->q($id)) ->where('t.published = 1'); $this->db->setQuery($q); return $cache->set($hash, $this->db->loadColumn()); } /** * Get current view layout string * * @return string */ public function getPageType() { $view = $this->request->view; $layout = $this->request->layout; if (is_null($layout)) { switch ($view) { case 'item': $layout = 'item'; break; default: $layout = $this->request->task; break; } } $pagetype = $view . '_' . $layout; return $pagetype; } }PK!hm##Xsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJClassifiedsCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJClassifiedsCategory extends DJClassifiedsBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('djcf_categories', 'parent_id'); } }PK!אQsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJCatalog2Base.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJCatalog2Base extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'item'; /** * The component's Category Page view name * * @var string */ protected $viewCategory = 'items'; /** * The component's option name * * @var string */ protected $component_option = 'com_djcatalog2'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select($db->quoteName('category_id')) ->from($db->quoteName('#__djc2_items_categories')) ->where($db->quoteName('item_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!XPsystem/nrframework/NRFramework/Conditions/Conditions/Component/EshopCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EshopCategory extends EshopBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('eshop_categories', 'category_parent_id'); } }PK!2rBBNsystem/nrframework/NRFramework/Conditions/Conditions/Component/JCalProBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JCalProBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'event'; /** * The component's option name * * @var string */ protected $component_option = 'com_jcalpro'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('category_id') ->from('#__jcalpro_event_categories') ->where($db->quoteName('event_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!q^__Nsystem/nrframework/NRFramework/Conditions/Conditions/Component/ContentView.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class ContentView extends ContentBase { /** * Pass check for Joomla! Articles * * @return bool * @return bool */ public function pass() { // Make sure we are in the right context if (empty($this->selection) || !$this->passContext()) { return false; } // In the Joomla Content component, the 'view' query parameter equals to 'category' in both Category List and Category Blog views. // In order to distinguish them we are using the 'layout' parameter as well. if ($this->request->view == 'category' && $this->request->layout) { $this->request->view .= '_' . $this->request->layout; } return $this->passByOperator($this->request->view, $this->selection, 'includes'); } }PK!T Z88Tsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJClassifiedsBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class DJClassifiedsBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'item'; /** * The component's option name * * @var string */ protected $component_option = 'com_djclassifieds'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('cat_id') ->from('#__djcf_items') ->where($db->quoteName('id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK! ~"Psystem/nrframework/NRFramework/Conditions/Conditions/Component/JCalProSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JCalProSingle extends JCalProBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!.LHHHNsystem/nrframework/NRFramework/Conditions/Conditions/Component/ContentBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class ContentBase extends ComponentBase { /** * Get single page's assosiated categories * * @param integer The Single Page id * * @return integer */ protected function getSinglePageCategories($id) { // If the article is not assigned to any menu item, the cat id should be available in the query string. Let's check it. if ($requestCatID = $this->app->input->getInt('catid', null)) { return $requestCatID; } // Apparently, the catid is not available in the Query String. Let's ask Article model. $item = $this->getItem($id); if (is_object($item) && isset($item->catid)) { return $item->catid; } } /** * Load a Joomla article data object. * * @return object */ public function getItem($id = null) { $id = is_null($id) ? $this->request->id : $id; $hash = md5('contentItem' . $id); $cache = $this->factory->getCache(); if ($cache->has($hash)) { return $cache->get($hash); } // Setup model if (defined('nrJ4')) { $model = new \Joomla\Component\Content\Site\Model\ArticleModel(['ignore_request' => true]); $model->setState('article.id', $id); $model->setState('params', $this->app->getParams()); } else { require_once JPATH_SITE . '/components/com_content/models/article.php'; $model = \JModelLegacy::getInstance('Article', 'ContentModel'); } try { $item = $model->getItem($id); return $cache->set($hash, $item); } catch (\JException $e) { return null; } } }PK!KZQsystem/nrframework/NRFramework/Conditions/Conditions/Component/ContentArticle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class ContentArticle extends ContentBase { /** * Pass check for Joomla! Articles * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int Article ID */ public function value() { return $this->request->id; } }PK!:]Xsystem/nrframework/NRFramework/Conditions/Conditions/Component/SPPageBuilderCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class SPPageBuilderCategory extends SPPageBuilderBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('categories', 'parent_id'); } }PK!l7 Isystem/nrframework/NRFramework/Conditions/Conditions/Component/K2Item.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; use NRFramework\Functions; defined('_JEXEC') or die; class K2Item extends K2Base { /** * Pass check * * @return bool */ public function pass() { $pass = $this->passSinglePage(); // Keywords Checking $contentKeywords = $this->params->get('cont_keywords', ''); $metaKeywords = $this->params->get('meta_keywords', ''); // If both are empty, do not maky any further check if (empty($contentKeywords) && empty($metaKeywords)) { return $pass; } // Load current K2 Item object if (!$item = $this->getK2Item()) { return false; } // check items's text if (!empty($contentKeywords)) { $pass = $this->passArrayInString($contentKeywords, $item->introtext . $item->fulltext); } // check item's metakeywords if (!empty($metaKeywords)) { $pass = $this->passArrayInString($metaKeywords, $item->metakey); } return $pass; } /** * Returns the assignment's value * * @return int Article ID */ public function value() { return $this->request->id; } /** * Checks if an array of values (needle) exists in a text (haystack). * * @param array $needle The searched array of values. * @param string $haystack The text * * @return bool */ private function passArrayInString($needle, $haystack) { if (empty($needle) || empty($haystack)) { return false; } $needle = Functions::makeArray($needle); return \NRFramework\Functions::strpos_arr($needle, $haystack); } }PK!͞׫`system/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryEventSingle.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JBusinessDirectoryEventSingle extends JBusinessDirectoryEventBase { /** * Pass check * * @return bool */ public function pass() { return $this->passSinglePage(); } /** * Returns the assignment's value * * @return int */ public function value() { return $this->request->id; } }PK!sQsystem/nrframework/NRFramework/Conditions/Conditions/Component/VirtueMartBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class VirtueMartBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'productdetails'; /** * The component's option name * * @var string */ protected $component_option = 'com_virtuemart'; /** * Class Constructor * * @param object $options * @param object $factory */ public function __construct($options, $factory) { parent::__construct($options, $factory); $this->request->id = $this->app->input->getInt('virtuemart_product_id'); } /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('virtuemart_category_id') ->from('#__virtuemart_product_categories') ->where($db->quoteName('virtuemart_product_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!sҢ##Tsystem/nrframework/NRFramework/Conditions/Conditions/Component/JShoppingCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class JShoppingCategory extends JShoppingBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('jshopping_categories', 'category_parent_id'); } /** * Returns all parent rows * * @param integer $id Row primary key * @param string $table Table name * @param string $parent Parent column name * @param string $child Child column name * * @return array Array with IDs */ public function getParentIds($id = 0, $table = 'jshopping_categories', $parent = 'category_parent_id', $child = 'category_id') { return parent::getParentIds($id, $table, $parent, $child); } }PK!ACGGLsystem/nrframework/NRFramework/Conditions/Conditions/Component/EshopBase.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class EshopBase extends ComponentBase { /** * The component's Single Page view name * * @var string */ protected $viewSingle = 'product'; /** * The component's option name * * @var string */ protected $component_option = 'com_eshop'; /** * Get single page's assosiated categories * * @param Integer The Single Page id * * @return array */ protected function getSinglePageCategories($id) { $db = $this->db; $query = $db->getQuery(true) ->select('category_id') ->from('#__eshop_productcategories') ->where($db->quoteName('product_id') . '=' . $db->q($id)); $db->setQuery($query); return $db->loadColumn(); } }PK!f Rsystem/nrframework/NRFramework/Conditions/Conditions/Component/SobiProCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class SobiProCategory extends SobiProBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('sobipro_relations', 'id'); } }PK!Jj88Usystem/nrframework/NRFramework/Conditions/Conditions/Component/VirtueMartCategory.phpnu[ or later */ namespace NRFramework\Conditions\Conditions\Component; defined('_JEXEC') or die; class VirtueMartCategory extends VirtueMartBase { /** * Pass check * * @return bool */ public function pass() { return $this->passCategories('virtuemart_product_categories', 'virtuemart_category_id'); } }PK!'tBsystem/nrframework/NRFramework/Conditions/Conditions/Date/Date.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Date; defined('_JEXEC') or die; class Date extends DateBase { /** * Checks if current date passes the given date range. * Dates must be always passed in format: Y-m-d H:i:s * * @return bool */ public function pass() { $publish_up = $this->params->get('publish_up'); $publish_down = $this->params->get('publish_down'); // No valid dates if (!$publish_up && !$publish_up) { return false; } $up = $publish_up ? $this->getDate($publish_up) : null; $down = $publish_down ? $this->getDate($publish_down) : null; return $this->checkRange($up, $down); } /** * Returns the assignment's value * * @return \Date Current date */ public function value() { return $this->date; } /** * This method is called before the value of the condition is stored into the database. * * Dates should be always stored in the database in GMT. Thus, we remove the timezone offset from the date. * * @param array $rule The condition object. * * @return void */ public function onBeforeSave(&$rule) { \NRFramework\Functions::fixDateOffset($rule['params']['publish_up']); \NRFramework\Functions::fixDateOffset($rule['params']['publish_down']); } }PK!XFsystem/nrframework/NRFramework/Conditions/Conditions/Date/DateBase.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Date; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class DateBase extends Condition { /** * Server's Timezone * * @var DateTimeZone */ protected $tz; /** * If set to True, dates will be constructed with modified offset based on the passed timezone * * @var Boolean */ protected $modify_offset = true; /** * Class constructor * * @param object $assignment */ public function __construct($assignment = null, $factory = null) { parent::__construct($assignment, $factory); // Set timezone if ($timezone = $this->params->get('timezone')) { $this->tz = new \DateTimeZone($timezone); } else { $this->tz = new \DateTimeZone($this->app->getCfg('offset', 'GMT')); } // Set modify offset switch $this->modify_offset = $this->params->get('modify_offset', true); // Set now date $now = $this->params->get('now', 'now'); $this->date = $this->getDate($now); } /** * Checks if the current datetime is between the specified range * * @param JDate &$up_date * @param JDate &$down_date * * @return bool */ protected function checkRange(&$up_date, &$down_date) { if (!$up_date && !$down_date) { return false; } $now = $this->date->getTimestamp(); if (((bool)$up_date && $up_date->getTimestamp() > $now) || ((bool)$down_date && $down_date->getTimestamp() < $now)) { return false; } return true; } /** * Create a date object based on the given string and apply timezone. * * @param String $date * * @return void */ protected function getDate($date = 'now') { // Fix the date string \NRFramework\Functions::fixDate($date); if ($this->modify_offset) { // Create date, set timezone and modify offset $date = $this->factory->getDate($date)->setTimeZone($this->tz); } else { // Create date and set timezone without modifyig offset $date = $this->factory->getDate($date, $this->tz); } return $date; } }PK!᮱/Asystem/nrframework/NRFramework/Conditions/Conditions/Date/Day.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Date; defined('_JEXEC') or die; class Day extends DateBase { /** * Cover special cases where the user checks whether the current day is a Weekday or Weekend. * * @param mixed $selection The current selection * * @return array */ public function prepareSelection() { $selection = (array) $this->getSelection(); foreach ($selection as $str) { $str = \strtolower($str); if (strpos($str, 'weekday') !== false) { $selection = array_merge($selection, range(1, 5)); continue; } if (strpos($str, 'weekend') !== false) { $selection = array_merge($selection, [6, 7]); } } return $selection; } /** * Return a list with all different formats of the current day. * * This returns the day in non-localized strings. * * @return array */ public function value() { return [ $this->date->format('l', false, false), // 'Friday' $this->date->format('D', false, false), // 'Fri' $this->date->format('N', false, false), // '1' (Monday) to '7' (Sunday) ]; } }PK![8Csystem/nrframework/NRFramework/Conditions/Conditions/Date/Month.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Date; defined('_JEXEC') or die; class Month extends DateBase { /** * Returns the assignment's value * * This returns the month in non-localized strings. * * @return string Name of the current month */ public function value() { return [ $this->date->format('F', false, false), $this->date->format('M', false, false), $this->date->format('n', false, false), $this->date->format('m', false, false), ]; } }PK!%k!!Gsystem/nrframework/NRFramework/Conditions/Conditions/Date/Scheduler.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Date; defined('_JEXEC') or die; /** * DateTime Assignment Scheduling helper */ class Scheduler { /** * Starting date * * @var object \DateTime */ protected $start_date; /** * Ending date * * @var object \DateTime */ protected $end_date; /** * Date to test against * * @var object \DateTime */ protected $current_date; /** * @var string */ protected $repetitionFrequency; /** * @var int */ protected $repetitionStep; /** * Used by 'weekly' repetition frequency * * @var array */ protected $weekdays; /** * The interval between the starting and current date * http://php.net/manual/en/class.dateinterval.php * * @var object \DateInterval */ protected $interval; /** * Scheduler constructor * * @param array $options: Scheduling options * start_date: * end_date: * current_date: * repetitionFrequency: one of 'daily', 'weekly', 'monthly', 'yearly' * repetitionStep: integer (1,2,3,...) * weekdays: Array, used with 'weekly' repetitionFrequency, any of 'Monday', 'Tuesday', etc. * Defaults to start_date's day name if empty */ public function __construct($options) { $this->start_date = $options['start_date']; $this->end_date = array_key_exists('end_date', $options) ? $options['end_date'] : null; $this->current_date = $options['current_date']; $this->repetitionFrequency = $options['repetitionFrequency']; $this->repetitionStep = $options['repetitionStep']; $this->weekdays = array_key_exists('weekdays', $options) ? array_map('ucfirst', $options['weekdays']) : null; //create a DateInterval object from current and start dates $this->interval = $this->start_date->diff($this->current_date); } /** * @return bool */ public function repeat() { //check if we are within the start/end date range (inclusive) if (!$this->checkDateRange()) { return false; } $result = false; // switch ($this->repetitionFrequency) { case 'daily': $result = $this->repeatDaily(); break; case 'weekly': $result = $this->repeatWeekly(); break; case 'monthly': $result = $this->repeatMonthly(); break; case 'yearly': $result = $this->repeatYearly(); break; } return $result; } /** * Daily repetition check * * @return bool */ protected function repeatDaily() { //get the number of days that have passed since start_date $num_days = $this->interval->days; if ($num_days % $this->repetitionStep !== 0) { return false; } return true; } /** * Weekly repetition check * * @return bool */ protected function repeatWeekly() { //get current_date's day name $today_name = $this->current_date->format('l'); // if $this->weekdays is empty use start_date's day name if (empty($this->weekdays)) { $start_day_name = $this->start_date->format('l'); if ($start_day_name !== $today_name) { return false; } } else { if (!in_array($today_name, $this->weekdays)) { return false; } } //get the number of weeks that passed since start_date $num_weeks = floor($this->interval->days / 7); if ($num_weeks % $this->repetitionStep !== 0) { return false; } return true; } /** * Monthly repetition check * * @return bool */ protected function repeatMonthly() { //check if we are on the same day of the month $start_day = $this->start_date->format('d'); $current_day = $this->current_date->format('d'); if ($start_day !== $current_day) { return false; } //get the number of months that have passed since start_date $num_months = ($this->interval->y * 12) + $interval->m; if ($num_months % $this->repetitionStep !== 0) { return false; } return true; } /** * Yearly repetition check * * @return bool */ protected function repeatYearly() { //check if we are on the same month and day $start_day_month = $this->start_date->format('d-m'); $current_day_month = $this->current_date->format('d-m'); if ($start_day_month !== $current_day_month) { return false; } //get the number of years that have passed since start_date $num_years = $this->interval->y; if ($num_years % $this->repetitionStep !== 0) { return false; } return true; } /** * Checks if the current date is between the start/end range (inclusive) * * @return bool */ protected function checkDateRange() { if ($this->start_date > $this->current_date) { return false; } if (!empty($this->end_date) && $this->end_date < $this->current_date) { return false; } return true; } }PK!M@Bsystem/nrframework/NRFramework/Conditions/Conditions/Date/Time.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Date; defined('_JEXEC') or die; class Time extends DateBase { /** * If set to True, dates will be constructed with modified offset based on the passed timezone * * @var Boolean */ protected $modify_offset = false; /** * Checks if current time passes the given time range * * @return bool */ public function pass() { $up = $this->date->format('Y-m-d', true) . ' ' . $this->params->get('publish_up'); $down = $this->date->format('Y-m-d', true) . ' ' . $this->params->get('publish_down'); $up = $this->factory->getDate((string) $up, $this->tz); $down = $this->factory->getDate((string) $down, $this->tz); return $this->checkRange($up, $down); } /** * Returns the assignment's value * * @return \Date Current date */ public function value() { return $this->date; } /** * A one-line text that describes the current value detected by the rule. Eg: The current time is %s. * * @return string */ public function getValueHint() { return \JText::sprintf('NR_DISPLAY_CONDITIONS_HINT_' . strtoupper($this->getName()), $this->date->format('H:i', true)); } }PK!7uAsystem/nrframework/NRFramework/Conditions/Conditions/Referrer.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; class Referrer extends URLBase { /** * Pass Referrer URL. * * @return bool Returns true if the Referrer URL contains any of the selection URLs */ public function pass() { return $this->passURL($this->value()); } /** * Returns the assignment's value * * @return string Referrer URL */ public function value() { return $this->app->input->server->get('HTTP_REFERER', '', 'RAW'); } }PK!'Bsystem/nrframework/NRFramework/Conditions/Conditions/EngageBox.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class EngageBox extends Condition { /** * Checks if the user viewed any of the given boxes * * @return bool */ public function pass() { // Skip if the visitorID is not set $visitorID = \NRFramework\VisitorToken::getInstance()->get(); if (empty($visitorID)) { return true; } $box_ids = $this->selection; if (!is_array($box_ids) || empty($box_ids)) { return true; } $box_ids = implode(',', $box_ids); $db = \JFactory::getDBO(); $query = $db->getQuery(true); $query ->select('COUNT(id)') ->from($db->quoteName('#__rstbox_logs')) ->where($db->quoteName('event') . ' = 1') ->where($db->quoteName('box') . " IN ( $box_ids )") ->where($db->quoteName('visitorid') . ' = '. $db->quote($visitorID)); $db->setQuery($query); $pass = (int) $db->loadResult(); return (bool) $pass; } }PK!}7 7 Csystem/nrframework/NRFramework/Conditions/Conditions/AcyMailing.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class AcyMailing extends Condition { /** * Returns the assignment's value * * @return array AcyMailing lists */ public function value() { return $this->getSubscribedLists(); } /** * Returns all AcyMailing lists the user is subscribed to * * @return array AcyMailing lists */ private function getSubscribedLists() { if (!$user = $this->user->id) { return false; } // Get a db connection. $db = $this->db; // Create a new query object. $query = $db->getQuery(true); $lists = []; // Read AcyMailing v5 lists if (\NRFramework\Extension::isInstalled('com_acymailing')) { $query ->select(array('list.listid')) ->from($db->quoteName('#__acymailing_listsub', 'list')) ->join('INNER', $db->quoteName('#__acymailing_subscriber', 'sub') . ' ON (' . $db->quoteName('list.subid') . '=' . $db->quoteName('sub.subid') . ')') ->where($db->quoteName('list.status') . ' = 1') ->where($db->quoteName('sub.userid') . ' = ' . $user) ->where($db->quoteName('sub.confirmed') . ' = 1') ->where($db->quoteName('sub.enabled') . ' = 1'); // Reset the query using our newly populated query object. $db->setQuery($query); if ($cols = $db->loadColumn()) { $lists = array_merge($lists, $cols); } } // Read AcyMailing > v5 lists if (\NRFramework\Extension::isInstalled('com_acym')) { // Create a new query object. $query = $db->getQuery(true); $query ->select(['list.id']) ->from($db->quoteName('#__acym_user_has_list', 'userlist')) ->join('INNER', $db->quoteName('#__acym_list', 'list') . ' ON (' . $db->quoteName('list.id') . '=' . $db->quoteName('userlist.list_id') . ')') ->join('INNER', $db->quoteName('#__acym_user', 'user') . ' ON (' . $db->quoteName('user.id') . '=' . $db->quoteName('userlist.user_id') . ')') ->where($db->quoteName('user.cms_id') . ' = ' . $user) ->where($db->quoteName('userlist.status') . ' = 1') ->where($db->quoteName('userlist.unsubscribe_date') . ' IS NULL'); // Reset the query using our newly populated query object. $db->setQuery($query); $cols = $db->loadColumn(); foreach ($cols as $value) { $lists[] = '6:' . $value; } } return $lists; } } PK!yk Dsystem/nrframework/NRFramework/Conditions/Conditions/Geo/GeoBase.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Geo; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; use NRFramework\User; /** * IP addresses sample * * Greece / Dodecanese: 94.67.238.3 * Belgium / Flanders: 37.62.255.255 * USA / New York: 72.229.28.185 */ class GeoBase extends Condition { /** * GeoIP Class * * @var class */ protected $geo; /** * Indicates whether we detected successfully the user's geographical location * * @var bool */ protected $success; /** * Class constructor * * @param object $options * @param object $factory */ public function __construct($options = null, $factory = null) { parent::__construct($options, $factory); $ip = $this->params->get('ip', null); $this->loadGeo($ip); } /** * Load GeoIP Classes * * @return void */ private function loadGeo($ip) { if (!class_exists('TGeoIP')) { $path = JPATH_PLUGINS . '/system/tgeoip'; if (@file_exists($path . '/helper/tgeoip.php')) { if (@include_once($path . '/vendor/autoload.php')) { @include_once $path . '/helper/tgeoip.php'; } } // If for some reason the tgeoip plugin files do not exist, abort if (!class_exists('TGeoIP')) { return; } } $this->geo = new \TGeoIP($ip); $record = $this->geo->getRecord(); $this->success = ($record !== false AND !is_null($record)); } /** * A one-line text that describes the current value detected by the rule. Eg: The current time is %s. * * @return string */ public function getValueHint() { if (!$this->success) { return \JText::sprintf('NR_DISPLAY_CONDITIONS_HINT_GEO_ERROR', User::getIP()); } // If the rule returns an array, use the 1st one. $value = $this->value(); $value = is_array($value) ? $value[0] : $value; return \JText::sprintf('NR_DISPLAY_CONDITIONS_HINT_GEO', User::getIP(), $this->getName(), ucfirst(strtolower($value))); } }PK!^IKTTFsystem/nrframework/NRFramework/Conditions/Conditions/Geo/Continent.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Geo; defined('_JEXEC') or die; use NRFramework\Functions; class Continent extends GeoBase { /** * Continent check * * @return bool */ public function prepareSelection() { $selection = Functions::makeArray($this->getSelection()); // Try to convert continent names to codes return array_map(function($c) { if (strlen($c) > 2) { $c = \NRFramework\Continents::getCode($c); } return $c; }, $selection); } /** * Return the Continent's code and full name * * @return string Country code */ public function value() { return [ $this->geo->getContinentName('en'), $this->geo->getContinentCode() ]; } }PK! WAsystem/nrframework/NRFramework/Conditions/Conditions/Geo/City.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Geo; defined('_JEXEC') or die; class City extends GeoBase { /** * Returns the assignment's value * * @return string City name */ public function value() { return $this->geo->getCity(); } }PK!WDsystem/nrframework/NRFramework/Conditions/Conditions/Geo/Country.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Geo; defined('_JEXEC') or die; use NRFramework\Countries; use NRFramework\Functions; class Country extends GeoBase { /** * Country check * * @return bool */ public function prepareSelection() { $selection = Functions::makeArray($this->getSelection()); return array_map(function($c) { if (strlen($c) > 2) { $c = Countries::getCode($c); } return $c; }, $selection); } /** * Returns the assignment's value * * @return string Country code */ public function value() { return [ $this->geo->getCountryName(), $this->geo->getCountryCode() ]; } }PK!Mp77Csystem/nrframework/NRFramework/Conditions/Conditions/Geo/Region.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions\Geo; defined('_JEXEC') or die; class Region extends GeoBase { /** * Returns the assignment's value * * @return string Region codes */ public function value() { return $this->getRegions(); } /** * Get list of all ISO 3611 Country Region Codes * * @return array */ private function getRegions() { $regionCodes = []; $record = $this->geo->getRecord(); if ($record === false || is_null($record)) { return $regionCodes; } // Skip if no regions found if (!$regions = $record->subdivisions) { return $regionCodes; } foreach ($regions as $key => $region) { // Get the Region's full name $regionCodes[] = $region->names['en']; // Get the Region's code by preppending the country isocode to the region code $regionCodes[] = $record->country->isoCode . '-' . $region->isoCode; } return $regionCodes; } }PK!{{{?system/nrframework/NRFramework/Conditions/Conditions/Cookie.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class Cookie extends Condition { /** * When we need to compare the user's value with the cookie value, we change the $selection to the value entered by the user. * * @return void */ public function prepareSelection() { if (in_array($this->operator, ['exists', 'empty'])) { return $this->getSelection(); } return $this->params->get('content', ''); } /** * Return the value of the cookie as stored in the user's browser * * @return string The value of the cookie */ public function value() { /** * $this->selection is not used here as prepareSelection() above, called in \NRFramework\Conditions\Condition->setSelection() method changes its value * and thus we do not always have the correct Cookie Name to search for. * * $this->options->get('selection') will always have the correct cookie name. */ return $this->factory->getCookie($this->options->get('selection')); } }PK!{IT T ;system/nrframework/NRFramework/Conditions/Conditions/IP.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\User; use NRFramework\Functions; use NRFramework\Conditions\Condition; class IP extends Condition { public function prepareSelection() { return Functions::makeArray($this->getSelection()); } /** * Checks if the user's ip address is within the specified ranges * * @return bool */ public function pass() { // get the user's ip address $user_ip = $this->value(); // get the supplied ip addresses/ranges as an array foreach ($this->getSelection() as $ip_range) { if ($this->isInRange($user_ip, $ip_range)) { return true; } } return false; } /** * Returns the assignment's value * * @return string User IP */ public function value() { return User::getIP(); } /** * Checks if an IP address falls within an IP range * Todo: factor out common logic... * @param string $user_ip * @param string $range * @return boolean */ protected function isInRange($user_ip, $range) { if (empty($user_ip) || empty($range)) { return false; } // break ip addresses/ranges into parts $user_ip_parts = explode('.', $user_ip); $ip_range_parts = explode('.', $range); for ($i = 0; $i < count($ip_range_parts); $i++) { $r = $ip_range_parts[$i]; // parse and check range if (strpos($r, '-') !== FALSE) { list($range_start, $range_end) = explode('-', $r); // format checks... if (!is_numeric($range_start) || !is_numeric($range_end)) { return false; } // cast strings to integers $range_start = (int) $range_start; $range_end = (int) $range_end; if ($range_start > $range_end || $range_start < 0 || $range_end > 255) { return false; } if ((int)$user_ip_parts[$i] < $range_start || (int)$user_ip_parts[$i] > $range_end) { return false; } } else { // format checks... if (!is_numeric($r)) { return false; } $r = (int)$r; if ($r < 0 || $r > 255) { return false; } if ((int)$user_ip_parts[$i] !== $r) { return false; } } } //for loop return true; } }PK!N`<system/nrframework/NRFramework/Conditions/Conditions/PHP.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions\Conditions; defined('_JEXEC') or die; use NRFramework\Conditions\Condition; class PHP extends Condition { /** * Pass check Custom PHP * * @return bool */ public function pass() { return (bool) $this->value(); } public function value() { // Enable buffer output ob_start(); $pass = $this->factory->getExecuter($this->selection)->run(); ob_end_clean(); return $pass; } }PK![~!~!7system/nrframework/NRFramework/Conditions/Condition.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions; defined('_JEXEC') or die; use Joomla\Registry\Registry; use Joomla\String\StringHelper; /** * Assignment Class */ class Condition { /** * Application Object * * @var object */ protected $app; /** * Document Object * * @var object */ protected $doc; /** * Date Object * * @var object */ protected $date; /** * Database Object * * @var object */ protected $db; /** * User Object * * @var object */ protected $user; /** * Assignment Selection * * @var mixed */ protected $selection; /** * Assignment Parameters * * @var mixed */ protected $params; /** * Assignment State (Include|Exclude) * * @var string */ public $assignment; /** * Options * * @var object */ public $options; /** * Framework factory object * * @var object */ public $factory; /** * The default operator that will be used to compare haystack with needle. * * @var string */ protected $operator; /** * Class constructor * * @param array $options The rule options. Expected properties: selection, value, params * @param object $factory The framework's factory class. */ public function __construct($options = null, $factory = null) { $this->factory = is_null($factory) ? new \NRFramework\Factory() : $factory; // Set General Joomla Objects $this->db = $this->factory->getDbo(); $this->app = $this->factory->getApplication(); $this->doc = $this->factory->getDocument(); $this->user = $this->factory->getUser(); $this->options = new Registry($options); $this->setParams($this->options->get('params')); $this->setOperator($this->options->get('operator', 'includesSome')); // For performance reasons we might move this inside the pass() method $this->setSelection($this->options->get('selection', '')); } /** * Set the rule's user selected value * * @param mixed $selection * @return object */ public function setSelection($selection) { $this->selection = $selection; if (method_exists($this, 'prepareSelection')) { $this->selection = $this->prepareSelection(); } return $this; } /** * Undocumented function * * @return void */ public function getSelection() { return $this->selection; } /** * Set the operator that will be used for the comparison * * @param string $operator * @return object */ public function setOperator($operator) { $this->operator = $operator; return $this; } /** * Set the rule's parameters * * @param array $params */ public function setParams($params) { $this->params = new Registry($params); } public function getParams() { return $this->params; } /** * Checks the validitity of two values based on the given operator. * * Consider converting this method as a Trait. * * @param mixed $value * @param mixed $selection * @param string $operator * @param array $options ignoreCase: true,false * * @return bool */ public function passByOperator($value = null, $selection = null, $operator = null, $options = null) { $value = is_null($value) ? $this->value() : $value; if (!is_null($selection)) { $this->setSelection($selection); } $selection = $this->getSelection(); $options = new Registry($options); $ignoreCase = $options->get('ignoreCase', true); if (is_object($value)) { $value = (array) $value; } if (is_object($selection)) { $selection = (array) $selection; } if ($ignoreCase) { if (is_string($value)) { $value = strtolower($value); } if (is_string($selection)) { $selection = strtolower($selection); } if (is_array($value)) { $value = array_map('strtolower', $value); } if (is_array($selection)) { $selection = array_map('strtolower', $selection); } } $operator = (is_null($operator) OR empty($operator)) ? $this->operator : $operator; $pass = false; switch ($operator) { case 'exists': $pass = !is_null($value); break; // Determines whether haystack is empty. Accepts: array, string case 'empty': if (is_array($value)) { $pass = empty($value); } if (is_string($value)) { $pass = $value == '' || trim($value) == ''; } break; // Determine whether haystack is less than needle. case 'less_than': $pass = $value < $selection; break; // Determine whether haystack is less than or equal to needle. case 'less_than_or_equal_to': $pass = $value <= $selection; break; // Determine whether haystack is greater than needle. case 'greater_than': $pass = $value > $selection; break; // Determine whether haystack is greater than or equal to needle. case 'greater_than_or_equal_to': $pass = $value >= $selection; break; // Determine whether haystack contains all elements in needle. case 'includesAll': $pass = count(array_intersect((array) $selection, (array) $value)) == count((array) $selection); break; // Determine whether haystack contains at least one element from needle. case 'includesSome': $pass = !empty(array_intersect((array) $value, (array) $selection)); break; // Determine whether haystack contains at least one element from needle. Accepts; string, array. case 'includes': if (is_string($value) && $value != '' && is_string($selection) && $selection != '') { if (StringHelper::strpos($value, $selection) !== false) { $pass = true; } } if (is_array($value) || is_array($selection)) { $pass = $this->passByOperator($value, $selection, 'includesSome', $options); } break; // Determine whether haystack starts with needle. Accepts: string case 'starts_with': $pass = StringHelper::substr($value, 0, StringHelper::strlen($selection)) === $selection; break; // Determine whether haystack ends with needle. Accepts: string case 'ends_with': $pass = StringHelper::substr($value, -StringHelper::strlen($selection)) === $selection; break; // Determine whether haystack equals to needle. Accepts any object. default: $pass = $value == $selection; } return $pass; } /** * Base assignment check * * @return bool */ public function pass() { return $this->passByOperator(); } /** * Returns all parent rows * * This method doesn't belong here. Move it to Functions.php. * * @param integer $id Row primary key * @param string $table Table name * @param string $parent Parent column name * @param string $child Child column name * * @return array Array with IDs */ public function getParentIds($id = 0, $table = 'menu', $parent = 'parent_id', $child = 'id') { if (!$id) { return []; } $cache = $this->factory->getCache(); $hash = md5('getParentIds_' . $id . '_' . $table . '_' . $parent . '_' . $child); if ($cache->has($hash)) { return $cache->get($hash); } $parent_ids = array(); while ($id) { $query = $this->db->getQuery(true) ->select('t.' . $parent) ->from('#__' . $table . ' as t') ->where('t.' . $child . ' = ' . (int) $id); $this->db->setQuery($query); $id = $this->db->loadResult(); // Break if no parent is found or parent already found before for some reason if (!$id || in_array($id, $parent_ids)) { break; } $parent_ids[] = $id; } return $cache->set($hash, $parent_ids); } /** * A one-line text that describes the current value detected by the rule. Eg: The current time is %s. * * @return string */ public function getValueHint() { $value = $this->value(); // If the rule returns an array, use the 1st one. $value = is_array($value) ? $value[0] : $value; return \JText::sprintf('NR_DISPLAY_CONDITIONS_HINT_' . strtoupper($this->getName()), ucfirst(strtolower($value))); } /** * Return the rule name * * @return string */ protected function getName() { $classParts = explode('\\', get_called_class()); return array_pop($classParts); } }PK!E>6system/nrframework/NRFramework/Conditions/Migrator.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions; use NRFramework\Assignments; defined('_JEXEC') or die; class Migrator { /** * Migrate old Assignments data to the new Condition Builder object. * * @since 5.0.1 * * @param object $box * * @return void */ public static function do(&$params) { if ($params->get('mirror') == '1') { $params->set('display_conditions_type', 'mirror'); return; } $assignmentsClass = new Assignments(); $matching_method_map = [ 'and' => 'all', 'or' => 'any' ]; $rules = [ 0 => [ 'matching_method' => $matching_method_map[$params->get('assignmentMatchingMethod', 'and')], 'enabled' => 1, 'rules' => [] ] ]; foreach ($params as $paramKey => $paramValue) { if (strpos($paramKey, 'assign_') !== 0) { continue; } $oldName = str_replace('assign_', '', $paramKey); $newName = $assignmentsClass->aliasToClassname($oldName); // Skip unknown conditions if (!$newName) { continue; } // Skip disabled conditions if ($paramValue == '0') { continue; } // Date assignment doesn't use the value property if ($newName == 'Date\Date') { $params->set($paramKey . '_list', true); $publish_up = $params->get('assign_'. $oldName .'_param_publish_up'); $publish_down = $params->get('assign_'. $oldName .'_param_publish_down'); \NRFramework\Functions::fixDateOffset($publish_up); \NRFramework\Functions::fixDateOffset($publish_down); $params->set('assign_'. $oldName .'_param_publish_up', $publish_up); $params->set('assign_'. $oldName .'_param_publish_down', $publish_down); } // Date assignment doesn't use the value property if ($newName == 'Date\Time') { $params->set($paramKey . '_list', true); } // Skip conditions with no value if (!$value = $params->get($paramKey . '_list')) { continue; } $operator = $paramValue == '1' ? 'includes' : 'not_includes'; // These Conditions have custom operators if (in_array($newName, ['Date\Date', 'Date\Time'])) { $operator = $paramValue == '1' ? 'equal' : 'not_equal'; } if ($newName == 'Cookie') { $operatorMap = [ 'exists' => 'exists', 'not_exists' => 'not_exists', 'equal' => 'equal', 'not_equal' => 'not_equal', 'contains' => 'includes', 'not_contains' => 'not_includes', 'starts' => 'starts_with', 'not_start' => 'not_starts_with', 'ends' => 'ends_with', 'not_end' => 'not_ends_with', ]; if ($paramValue == '2') { switch ($value) { case 'exists': $value = 'not_exists'; break; case 'equal': $value = 'not_equal'; break; case 'contains': $value = 'not_contains'; break; case 'starts': $value = 'not_start'; break; case 'ends': $value = 'not_end'; break; } } $operator = $operatorMap[$value]; $params->set('assign_cookiename_param_operator', $operator); $value = $params->get('assign_cookiename_param_name'); } if ($newName == 'Pageviews') { $operatorMap = [ 'exactly' => 'equal', 'not_equal' => 'not_equal', 'fewer' => 'less_than', 'greater' => 'greater_than', ]; if ($paramValue == '2') { switch ($value) { case 'exactly': $value = 'not_equal'; break; case 'fewer': $value = 'greater'; break; case 'greater': $value = 'fewer'; break; } } $operator = $operatorMap[$value]; $value = $params->get('assign_pageviews_param_views'); } $data = [ 'name' => $newName, 'enabled' => 1, 'operator' => $operator, 'value' => $value ]; // Find params foreach ($params as $assignParamKey => $assignParamValue) { if (strpos($assignParamKey, $paramKey . '_param') !== 0) { continue; } if ($assignParamValue == '') { continue; } $realParamName = str_replace($paramKey . '_param_', '', $assignParamKey); $data['params'][$realParamName] = $assignParamValue; } $rules[0]['rules'][] = $data; } if (!empty($rules[0]['rules'])) { // Finally, set the rules $params->set('display_conditions_type', 'custom'); $params->set('rules', $rules); } } }PK!Y~]-]->system/nrframework/NRFramework/Conditions/ConditionBuilder.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Conditions; defined('_JEXEC') or die; use Joomla\CMS\Layout\LayoutHelper; use NRFramework\Conditions\ConditionsHelper; use NRFramework\Extension; class ConditionBuilder { public static function pass($rules) { $rules = self::prepareRules($rules); if (empty($rules)) { return true; } return ConditionsHelper::getInstance()->passSets($rules); } /** * Prepare rules object to run checks * * @return void */ public static function prepareRules($rules) { $rules_ = []; foreach ($rules as $key => $group) { if (isset($group['enabled']) AND !(bool) $group['enabled']) { continue; } // A group without rules, doesn't make sense. if (!isset($group['rules']) OR (isset($group['rules']) AND empty($group['rules']))) { continue; } $validRules = []; foreach ($group['rules'] as $rule) { // Make sure rule has a name. if (!isset($rule['name']) OR (isset($rule['name']) AND empty($rule['name']))) { continue; } // Rule is invalid if both value and params properties are empty if (!isset($rule['value']) && !isset($rule['params'])) { continue; } // Skip disabled rules if (isset($rule['enabled']) && !(bool) $rule['enabled']) { continue; } // We don't need this property. unset($rule['enabled']); // Prepare rule value if necessary if (isset($rule['value'])) { $rule['value'] = self::prepareTFRepeaterValue($rule['value']); } // Verify operator if (!isset($rule['operator']) OR (isset($rule['operator']) && empty($rule['operator']))) { $rule['operator'] = isset($rule['params']['operator']) ? $rule['params']['operator'] : ''; } $validRules[] = $rule; } if (count($validRules) > 0) { $group['rules'] = $validRules; if (!isset($group['matching_method']) OR (isset($group['matching_method']) AND empty($group['matching_method']))) { $group['matching_method'] = 'all'; } unset($group['enabled']); $rules_[] = $group; } } return $rules_; } /** * Parse the value of the TF Repeater Input field. * * @param array $selection * * @return mixed */ private static function prepareTFRepeaterValue($selection) { // Only proceed when we have an array of arrays selection. if (!is_array($selection)) { return $selection; } $first = array_values($selection)[0]; if (!is_array($first)) { return $selection; } if (!isset($first['value'])) { return $selection; } $new_selection = []; foreach ($selection as $value) { /** * We expect a `value` key for TFInputRepeater fields or a key,value pair * for plain arrays. */ if (!isset($value['value'])) { /** * If no value exists, it means that the passed $assignment->selection is a key,value pair array so we use the value * as our returned selection. * * This happens when we pass a key,value pair array as $assignment->selection when we expect a TFInputRepeater value * so we need to take this into consideration. */ $new_selection[] = $value; continue; } // value must not be empty if (empty(trim($value['value']))) { continue; } $new_selection[] = $value['value']; } return $new_selection; } /** * Returns the TGeoIP plugin modal. * * @return string */ public static function getGeoModal() { // Do not proceed if the database is up-to-date if (!\NRFramework\Extension::geoPluginNeedsUpdate()) { return; } \Joomla\CMS\HTML\HTMLHelper::_('bootstrap.modal'); $modalName = 'tf-geodbchecker-modal'; // The TGeoIP Plugin URL $url = \JURI::base(true) . '/index.php?option=com_plugins&view=plugin&tmpl=component&layout=modal&extension_id=' . \NRFramework\Functions::getExtensionID('tgeoip', 'system'); $options = [ 'title' => \JText::_('NR_EDIT'), 'url' => $url, 'height' => '400px', 'backdrop' => 'static', 'bodyHeight' => '70', 'modalWidth' => '70', 'footer' => ' ', ]; return \JHtml::_('bootstrap.renderModal', $modalName, $options); } /** * Prepares the given rules list. * * @param array $list * * @return array */ public static function prepareXmlRulesList($list) { if (is_array($list)) { $list = implode(',', array_map('trim', $list)); } else if (is_string($list)) { $list = str_replace(' ', '', $list); } return $list; } /** * Adds a new condition item or group. * * @param string $controlGroup The name of the input used to store the data. * @param string $groupKey The group index ID. * @param string $conditionKey The added condition item index ID. * @param array $condition The condition name we are adding. * @param string $include_rules The list of included conditions that override the available conditions. * @param string $exclude_rules The list of excluded conditions that override the available conditions. * * @return string */ public static function add($controlGroup, $groupKey, $conditionKey, $condition = null, $include_rules = [], $exclude_rules = []) { $controlGroup_ = $controlGroup . "[$groupKey][rules][$conditionKey]"; // @Todo - rename input namespace to 'conditions' $form = self::getForm('conditionbuilder/base.xml', $controlGroup_, $condition); $form->setFieldAttribute('name', 'include_rules', is_array($include_rules) ? implode(',', $include_rules) : $include_rules); $form->setFieldAttribute('name', 'exclude_rules', is_array($exclude_rules) ? implode(',', $exclude_rules) : $exclude_rules); $options = [ 'name' => $controlGroup_, 'enabled' => !isset($condition['enabled']) ? true : (string) $condition['enabled'] == '1', 'toolbar' => $form, 'groupKey' => $groupKey, 'conditionKey' => $conditionKey, 'options' => '' ]; if (isset($condition['name'])) { $optionsHTML = self::renderOptions($condition['name'], $controlGroup_, $condition); $options['condition_name'] = $condition['name']; $options['options'] = $optionsHTML; } return self::getLayout('conditionbuilder_row', $options); } /** * Render condition item settings. * * @param string $name The name of the condition item. * @param string $controlGroup The name of the input used to store the data. * @param object $formData The data that will be bound to the form. * * @return string */ public static function renderOptions($name, $controlGroup = null, $formData = null) { if (!$form = self::getForm('conditions/' . strtolower(str_replace('\\', '/', $name)) . '.xml', $controlGroup, $formData)) { return; } $form->setFieldAttribute('note', 'ruleName', $name); return $form->renderFieldset('general'); } /** * Handles loading condition builder given a payload. * * @param array $payload * * @return string */ public static function initLoad($payload = []) { if (!$payload) { return; } if (!isset($payload['data']) && !isset($payload['name'])) { return; } if (!$data = json_decode($payload['data'])) { return; } // transform object to assosiative array $data = json_decode(json_encode($data), true); // html of condition builder $html = ''; $include_rules = isset($payload['include_rules']) ? $payload['include_rules'] : []; $exclude_rules = isset($payload['exclude_rules']) ? $payload['exclude_rules'] : []; foreach ($data as $groupKey => $groupConditions) { $payload = [ 'name' => $payload['name'], 'groupKey' => $groupKey, 'groupConditions' => $groupConditions, 'include_rules' => $include_rules, 'exclude_rules' => $exclude_rules ]; $html .= self::getLayout('conditionbuilder_group', $payload); } return $html; } /** * Render a layout given its name and payload. * * @param string $name * @param array $payload * * @return string */ public static function getLayout($name, $payload) { return LayoutHelper::render($name, $payload, JPATH_PLUGINS . '/system/nrframework/layouts'); } /** * Returns the form by binding given data. * * @param string $name * @param string $controlGroup * @param array $data * * @return object */ private static function getForm($name, $controlGroup, $data = null) { if (!file_exists(JPATH_PLUGINS . '/system/nrframework/xml/' . $name)) { return; } $form = new \JForm('cb', ['control' => $controlGroup]); $form->addFieldPath(JPATH_PLUGINS . '/system/nrframework/fields'); $form->loadFile(JPATH_PLUGINS . '/system/nrframework/xml/' . $name); if (!is_null($data)) { $form->bind($data); } return $form; } }PK!'system/nrframework/NRFramework/User.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; use NRFramework\Cache; defined('_JEXEC') or die('Restricted access'); class User { /** * Return the user object * * @param mixed $id The primary key of the user * * @return mixed object on success, null on failure */ public static function get($id = null) { // Return current active user if (is_null($id)) { return \JFactory::getUser(); } // Prevent Joomla from displaying a warning from missing user by checking if the user exists first if (!self::exists($id)) { return; } return \JFactory::getUser($id); } /** * Checks whether the user does exist in the database * * @param integer $id The primary key of the user * * @return bool */ public static function exists($id) { $hash = 'user' . $id; if (Cache::has($hash)) { return Cache::get($hash); } $db = \JFactory::getDbo(); $query = $db->getQuery(true) ->select('count(id)') ->from('#__users') ->where('id = ' . $db->quote($id)); $db->setQuery($query); // Cache result return Cache::set($hash, $db->loadResult()); } /** * Get the IP address of the user * * @return string */ public static function getIP() { $server = \JFactory::getApplication()->input->server; // Whether ip is from the share internet if (!empty($server->get('HTTP_CLIENT_IP'))) { return $server->get('HTTP_CLIENT_IP', '', 'string'); } //whether ip is from the proxy if (!empty($server->get('HTTP_X_FORWARDED_FOR'))) { return $server->get('HTTP_X_FORWARDED_FOR', '', 'string'); } return $server->get('REMOTE_ADDR', '', 'string'); } }PK!#UU-system/nrframework/NRFramework/Continents.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined('_JEXEC') or die('Restricted access'); /** * Helper class to work with continent names/codes */ class Continents { /** * Return a continent code from it's name * * @param string $cont * @return string|void */ public static function getCode($cont) { $cont = \ucwords(strtolower($cont)); foreach (self::getContinentsList() as $key => $value) { if (strpos($value, $cont) !== false) { return $key; } } return null; } /** * Returns a list of continents * * @return array */ public static function getContinentsList() { return [ 'AF' => \JText::_('NR_CONTINENT_AF'), 'AS' => \JText::_('NR_CONTINENT_AS'), 'EU' => \JText::_('NR_CONTINENT_EU'), 'NA' => \JText::_('NR_CONTINENT_NA'), 'SA' => \JText::_('NR_CONTINENT_SA'), 'OC' => \JText::_('NR_CONTINENT_OC'), 'AN' => \JText::_('NR_CONTINENT_AN'), ]; } }PK!|~\3\3,system/nrframework/NRFramework/Extension.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; use NRFramework\Cache; use Joomla\Registry\Registry; defined( '_JEXEC' ) or die( 'Restricted access' ); class Extension { /** * Indicates the base url of Tassos.gr Joomla Extensions * * @var string */ public static $product_base_url = 'https://www.tassos.gr/joomla-extensions'; /** * Array including already loaded extensions * * @var array */ public static $cache = []; /** * Get extension ID * * @param string $element The extension element name * @param string $type The extension type: component, plugin, library e.t.c * @param mixed $folder The plugin folder: system, content e.t.c * * @return mixed False on failure, Integer on success */ public static function getID($element, $type = 'component', $folder = null) { if (!$extension = self::get($element, $type, $folder)) { return false; } return (int) $extension['extension_id']; } /** * Get extension data by ID * * @param string $extension_id The extension primary key * * @return void */ public static function getByID($extension_id) { // Check if element is already cached if (isset(self::$cache[$extension_id])) { return self::$cache[$extension_id]; } // Let's call the database $db = \JFactory::getDBO(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__extensions')) ->where($db->quoteName('extension_id') . ' = ' . $extension_id); $db->setQuery($query); return self::$cache[$extension_id] = $db->loadAssoc(); } /** * Get extension information from database * * @param string $element The extension element name * @param string $type The extension type: component, plugin, library e.t.c * @param mixed $folder The plugin folder: system, content e.t.c * * @return array */ public static function get($element, $type = 'component', $folder = null) { // Check if element is already cached $hash = md5($element . '_' . $type . '_' . $folder); if (isset(self::$cache[$hash])) { return self::$cache[$hash]; } // Let's call the database $db = \JFactory::getDBO(); switch ($type) { case 'component': $element = 'com_' . str_replace('com_', '', $element); break; case 'module': $element = 'mod_' . str_replace('mod_', '', $element); break; } $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($element)) ->where($db->quoteName('type') . ' = ' . $db->quote($type)); if (!is_null($folder)) { $query->where($db->quoteName('folder') . ' = ' . $db->quote($folder)); } $db->setQuery($query); return self::$cache[$hash] = $db->loadAssoc(); } /** * Get Novarain Framework plugin data * * @return array */ public static function getFramework() { return self::get('nrframework', 'plugin', 'system'); } /** * Helper method to check if a plugin is enabled * * @param string $element The extension element name * @param string $type The extension type: component, plugin, library e.t.c * * @return boolean */ public static function pluginIsEnabled($element, $folder = 'system') { return self::isEnabled($element, 'plugin', $folder); } /** * Helper method to check if a component is enabled * * @param string $element The component element name * * @return boolean */ public static function componentIsEnabled($element) { return self::isEnabled($element); } /** * Checks if an extension is enabled * * @param string $element The extension element name * @param string $type The extension type: component, plugin, library e.t.c * @param mixed $folder The plugin folder: system, content e.t.c * * @return boolean */ public static function isEnabled($element, $type = 'component', $folder = 'system') { switch ($type) { case 'component': if (!$extension = self::get($element)) { return false; } return (bool) $extension['enabled']; break; case 'plugin': if (!$extension = self::get($element, $type = 'plugin', $folder)) { return false; } return (bool) $extension['enabled']; break; } } /** * Checks if an extension is installed * * @param string $extension The extension element name * @param string $type The extension's type * @param string $folder Plugin folder * * @return boolean Returns true if extension is installed */ public static function isInstalled($extension, $type = 'component', $folder = 'system') { $db = \JFactory::getDbo(); switch ($type) { case 'component': $extension_data = self::get('com_' . str_replace('com_', '', $extension)); return isset($extension_data['extension_id']); break; case 'plugin': return \JFile::exists(JPATH_PLUGINS . '/' . $folder . '/' . $extension . '/' . $extension . '.php'); case 'module': return (\JFile::exists(JPATH_ADMINISTRATOR . '/modules/mod_' . $extension . '/' . $extension . '.php') || \JFile::exists(JPATH_ADMINISTRATOR . '/modules/mod_' . $extension . '/mod_' . $extension . '.php') || \JFile::exists(JPATH_SITE . '/modules/mod_' . $extension . '/' . $extension . '.php') || \JFile::exists(JPATH_SITE . '/modules/mod_' . $extension . '/mod_' . $extension . '.php') ); case 'library': return \JFolder::exists(JPATH_LIBRARIES . '/' . $extension); } return false; } /** * Discover extension's name based on the query string * * @param boolean $translate If set to yes, the name will be returned translated * * @return string */ public static function getExtensionNameByRequest($translate = false) { $input = \JFactory::getApplication()->input; $option = $input->get('option'); switch ($option) { case 'com_fields': $name = 'plg_system_acf'; break; case 'com_plugins': $plugin = self::getByID($input->get('extension_id')); if (is_array($plugin)) { $name = $plugin['name']; } break; default: $name = $option; break; } if ($translate) { $name = explode(' - ', \JText::_($name)); return end($name); } return $name; } /** * Returns Tassos.gr extension checkout URL * * @param string $name The extension's element name * * @return string */ public static function getTassosExtensionUpgradeURL($name = null) { $name = is_null($name) ? strtolower(self::getExtensionNameByRequest()) : $name; switch ($name) { case 'com_gsd': $path = 'google-structured-data-markup/subscribe/google-structured-data-professional'; break; case 'com_rstbox': $path = 'engagebox/subscribe/engagebox-professional'; break; case 'com_convertforms': $path = 'convert-forms/subscribe/convert-forms-professional'; break; case 'plg_system_tweetme': $path = 'tweetme/subscribe/tweetme-professional'; break; case 'plg_system_acf': $path = 'advanced-custom-fields/subscribe/advanced-custom-fields-professional'; break; default: $path = ''; } // Google Analytics UTM Parameters $utm = 'utm_source=Joomla&utm_medium=upgradebutton&utm_campaign=freeversion'; return self::$product_base_url . '/' . $path . '/sign-up?coupon_code=FREE2PRO&' . $utm; } public static function getProductAlias($extension) { $extension = is_null($extension) ? self::getExtensionNameByRequest() : $extension; switch ($extension) { case 'com_gsd': case 'plg_system_gsd': return 'google-structured-data-markup'; case 'com_rstbox': return 'engagebox'; case 'com_convertforms': return 'convert-forms'; case 'plg_system_tweetme': return 'tweetme'; case 'plg_system_acf': return 'advanced-custom-fields'; case 'plg_system_restrictcontent': case 'com_restrictcontent': return 'restrict-conten'; } } public static function getProductURL($extension) { return self::$product_base_url . '/' . self::getProductAlias($extension); } public static function getPath($element) { $parts = explode('_', $element); switch ($parts[0]) { case 'com': return JPATH_ADMINISTRATOR . '/components/' . $element; case 'plg': return JPATH_SITE . '/plugins/' . $parts[1] . '/' . $parts[2]; } } public static function getVersion($extension, $include_type = false) { $xml = self::getXML($extension); if (!$xml || !isset($xml->version)) { return; } $version = (string) $xml->version; // If enabled, it returns EngageBox Pro if ($include_type) { $isPro = self::isPro($extension); $version_type = $isPro ? 'Pro' : 'Free'; $version .= ' ' . $version_type; } return $version; } public static function elementToAlias($element) { $parts = explode('_', $element); return end($parts); } public static function getXML($element) { if (!$path = self::getPath($element)) { return; } $extension_alias = self::elementToAlias($element); $xml = $path . '/' . $extension_alias . '.xml'; return simplexml_load_file($xml); } /** * Returns a URL where we can check for extension updates. * * @param strong $extension * * @return mixed Null of fail, String on success */ public static function getUpdateServer($extension) { $xml = self::getXML($extension); if (!$xml || !isset($xml->updateservers)) { return; } $updateserver = trim($xml->updateservers->server); // Remove unwanted string added by Free / Pro versions $pp = strpos($updateserver, '@'); if ($pp !== false) { $updateserver = substr($updateserver, 0, $pp); } return $updateserver; } /** * Get the latest extension version from the remote update server * * @param string $extension * * @return mixed Null on failure, String on success */ public static function getLatestVersion($extension) { // Get the extension's update server URL if (!$updateserver = self::getUpdateServer($extension)) { return; } // Call the Update Server and make sure the response is valid $response = \JHttpFactory::getHttp()->get($updateserver); if ($response->code != 200 || strpos($response->body, '') === false) { return; } $body = new \SimpleXMLElement($response->body); $version = (string) $body->update[0]->version; return $version; } /** * Check if we have the Pro version of the extension * * @param string $element * * @return bool */ public static function isPro($element) { if (!$path = self::getPath($element)) { return false; } $versionFile = $path . '/version.php'; // If version file does not exist we assume a PRO version if (!\JFile::exists($versionFile)) { return true; } require $versionFile; // If the NR_PRO variable is not set we're probably under development mode. Assume a Pro version. if (!isset($NR_PRO)) { return true; } return (bool) $NR_PRO; } /** * Checks whether an extension is outdated. * * @param string $extension * @param int $days_old * * @return bool */ public static function isOutdated($extension, $days_old = 120) { $versionFile = Functions::getExtensionPath($extension) . "/version.php"; if (!file_exists($versionFile)) { return false; } require $versionFile; if (!isset($RELEASE_DATE)) { return false; } if (!$then = strtotime($RELEASE_DATE)) { return false; } $days_old = (int) $days_old; $now = time(); $diff = $now - $then; $days_diff = round($diff / (60 * 60 * 24)); if ($days_diff <= $days_old) { return false; } return true; } /** * Checks whether the geolocation plugin needs an update. * * @return bool */ public static function geoPluginNeedsUpdate() { // Check if TGeoIP plugin is enabled if (!self::pluginIsEnabled('tgeoip')) { return false; } $plugin_path = JPATH_PLUGINS . '/system/tgeoip/'; // Load plugin language (Needed by Joomla 4) \JFactory::getLanguage()->load('plg_system_tgeoip', $plugin_path); // Load TGeoIP classes @include_once $plugin_path . 'vendor/autoload.php'; @include_once $plugin_path . 'helper/tgeoip.php'; if (!class_exists('TGeoIP')) { return false; } // Check if database needs update. $geo = new \TGeoIP(); if (!$geo->needsUpdate()) { return false; } // Database is too old and needs an update! Let's inform user. return true; } }PK!}3 ,system/nrframework/NRFramework/WebClient.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined( '_JEXEC' ) or die( 'Restricted access' ); class WebClient { /** * Joomla Application Client * * @var object */ public static $client; /** * Get visitor's Device Type * * @param string $ua User Agent string, if null use the implicit one from the server's enviroment * * @return string The client's device type. Can be: tablet, mobile, desktop */ public static function getDeviceType($ua = null) { if (!class_exists('Mobile_Detect')) { \JLoader::register('Mobile_Detect', JPATH_PLUGINS . '/system/nrframework/helpers/vendors/Mobile_Detect.php'); } $detect = new \Mobile_Detect(null, $ua); return ($detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'mobile') : 'desktop'); } /** * Get visitor's Operating System * * @param string $ua User Agent string, if null use the implicit one from the server's enviroment * * @return string Possible values: any of JApplicationWebClient's OS constants (except 'iphone' and 'ipad'), * 'ios', 'chromeos' */ public static function getOS($ua = null) { // detect iOS and CromeOS (not handled by JApplicationWebClient) $ua = self::getClient($ua)->userAgent; $ios_regex = '/iPhone|iPad|iPod/i'; if (preg_match($ios_regex, $ua)) { return 'ios'; } $chromeos_regex = '/CrOS/i'; if (preg_match($chromeos_regex, $ua)) { return 'chromeos'; } // use JApplicationWebClient for OS detection $platformInt = self::getClient($ua)->platform; $constants = self::getClientConstants(); if (isset($constants[$platformInt])) { return strtolower($constants[$platformInt]); } } /** * Get visitor's Browser name / version * * @param string $ua User Agent string, if null use the implicit one from the server's enviroment * * @return array */ public static function getBrowser($ua = null) { $browser = new \Joomla\CMS\Environment\Browser($ua); // Keep IE's name as 'ie' instead of 'msie' to prevent breaking existing assignments $browserName = $browser->getBrowser() == 'msie' ? 'ie' : $browser->getBrowser(); return [ 'name' => $browserName, 'version' => $browser->getVersion() ]; } /** * Get the constants from JApplicationWebClient as an array using the Reflection API * * @return array */ private static function getClientConstants() { $r = new \ReflectionClass('\\Joomla\\Application\\Web\\WebClient'); $constantsArray = $r->getConstants(); // flip the associative array return array_flip($constantsArray); } /** * Get the Application Client helper * see https://api.joomla.org/cms-3/classes/Joomla.Application.Web.WebClient.html * * @param string $ua User Agent string, if null use the implicit one from the server's enviroment * * @return object */ public static function getClient($ua = null) { if (is_object(self::$client) && $ua == null) { return self::$client; } return (self::$client = new \Joomla\Application\Web\WebClient($ua)); } }PK!H(system/nrframework/NRFramework/Fonts.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined( '_JEXEC' ) or die( 'Restricted access' ); /** * Fonts Class */ class Fonts { /** * Classic Fonts * * @var array */ private static $classic = array( 'Arial', 'Arial Black', 'Georgia', 'Tahoma', 'Franklin Gothic Medium', 'Calibri', 'Cambria', 'Century Gothic', 'Consolas', 'Corbel', 'Courier New', 'Times New Roman', 'Impact', 'Lucida Console', 'Palatino Linotype', 'Trebuchet MS', 'Verdana' ); /** * Google Fonts List * * @var array */ private static $google = array( 'Roboto', 'Staatliches', 'Thasadith', 'Open Sans', 'Sarabun', 'Slabo 27px', 'Lato', 'Oswald', 'Charm', 'Roboto Condensed', 'Source Sans Pro', 'Montserrat', 'Raleway', 'PT Sans', 'Poppins', 'Roboto Slab', 'Lora', 'Droid Sans', 'Merriweather', 'Ubuntu', 'Droid Serif', 'Arimo', 'Noto Sans', 'PT Sans Narro' ); /** * Returns all font groups alphabetically sorted * * @return array */ public static function getFontGroups() { return array( 'Google Fonts' => self::getFontGroup('google'), 'Classic' => self::getFontGroup('classic') ); } /** * Returns a font group alphabetically sorted * * @param string $name The Font Group * * @return array */ public static function getFontGroup($name) { $fonts = self::$$name; sort($fonts); return $fonts; } /** * Loads Google font to the document * * @param mixed $name The Google font name * * @return void */ public static function loadFont($names) { if (!$names) { return; } if (!is_array($names)) { $names = array($names); } foreach ($names as $key => $value) { // If font is a Google Font then load it into the document if (in_array($value, self::$google)) { \JFactory::getDocument()->addStylesheet('//fonts.googleapis.com/css?family=' . urlencode($value)); } } } }PK!7\*system/nrframework/NRFramework/Factory.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; use \NRFramework\WebClient; use \NRFramework\CacheManager; defined('_JEXEC') or die; /** * Framework Factory Class * * Used to decouple the framework from it's dependencies and make unit testing easier. * * @todo Rename class to Container and make all methods static. */ class Factory { public function isFrontend() { return $this->getApplication()->isClient('site'); } public static function getCondition($name) { return \NRFramework\Conditions\ConditionsHelper::getInstance()->getCondition($name); } public function getDbo() { return \JFactory::getDbo(); } public function getApplication() { return \JFactory::getApplication(); } public function getCookie($cookie_name) { return \JFactory::getApplication()->input->cookie->get($cookie_name); } public function getDocument() { return \JFactory::getDocument(); } public function getUser($id = null) { return \NRFramework\User::get($id); } public function getCache() { return CacheManager::getInstance(\JFactory::getCache('novarain', '')); } public function getDate($date = 'now', $tz = null) { return \JFactory::getDate($date, $tz); } public function getURI() { return \JURI::getInstance(); } public function getURL() { return \JURI::getInstance()->toString(); } public function getLanguage() { return \JFactory::getLanguage(); } public function getSession() { return \JFactory::getSession(); } public function getDevice() { return WebClient::getDeviceType(); } public function getBrowser() { return WebClient::getBrowser(); } public function getExecuter($php_code) { return new \NRFramework\Executer($php_code); } }PK!Y\ .system/nrframework/NRFramework/Updatesites.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined('_JEXEC') or die('Restricted access'); class Updatesites { /** * Joomla Database Class * * @var object */ private $db; /** * Consturction method * * @param string $key Download Key */ public function __construct($key = null) { $this->db = \JFactory::getDBO(); $this->key = ($key) ? $key : $this->getDownloadKey(); } /** * Main method */ public function update() { $this->removeDuplicates(); $this->updateHttptoHttps(); } /** * Reads the Download Key saved in the Novarain Framework system plugin parameters * * @return string The Download Key */ public function getDownloadKey() { $query = $this->db->getQuery(true) ->select('e.params') ->from('#__extensions as e') ->where('e.element = ' . $this->db->quote('nrframework')); $this->db->setQuery($query); if (!$params = $this->db->loadResult()) { return; } $params = json_decode($params); if (!isset($params->key)) { return; } return trim($params->key); } /** * Update http to https * * @return void */ private function updateHttptoHttps() { $query = $this->db->getQuery(true) ->update('#__update_sites') ->set($this->db->quoteName('location') . ' = REPLACE(' . $this->db->quoteName('location') . ', ' . $this->db->quote('http://') . ', ' . $this->db->quote('https://') . ')') ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%tassos.gr%')); $this->db->setQuery($query); $this->db->execute(); } /** * Remove duplicate update sites created by upgrading from Free to Pro version * * @return void */ private function removeDuplicates() { $db = $this->db; // Find duplicates first $query = 'SELECT name, COUNT(*) c FROM #__update_sites where location like "%tassos.gr%" GROUP BY name HAVING c > 1'; $db->setQuery($query); if (!$duplicates = $db->loadObjectList()) { return; } // OK we have duplicates. Let's remove them. foreach ($duplicates as $key => $duplicate) { // Get all IDs $query = $db->getQuery(true) ->select('update_site_id') ->from('#__update_sites') ->where('name = ' . $db->quote($duplicate->name)) ->order('update_site_id DESC'); $db->setQuery($query); if (!$update_site_ids = $db->loadObjectList()) { return; } // Skip the 1st index which represents the last created and valid. unset($update_site_ids[0]); foreach ($update_site_ids as $key => $update_site_id) { $id = $update_site_id->update_site_id; $query->clear() ->delete('#__update_sites') ->where($db->quoteName('update_site_id') . ' = ' . (int) $id); $db->setQuery($query); $db->execute(); $query->clear() ->delete('#__update_sites_extensions') ->where($db->quoteName('update_site_id') . ' = ' . (int) $id); $db->setQuery($query); $db->execute(); } } } }PK!6system/nrframework/NRFramework/Rules/nrcoordinates.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class JFormRuleNRCoordinates extends JFormRule { /** * The regular expression to use in testing a form field value. * * @var string * @since 11.1 * @link http://www.w3.org/TR/html-markup/input.email.html */ protected $regex = '^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$'; public function test(SimpleXMLElement $element, $value, $group = null, Joomla\Registry\Registry $input = null, JForm $form = null) { $value = trim($value); // If the field is empty and not required, the field is valid. $required = ((string) $element['required'] == 'true' || (string) $element['required'] == 'required'); if (!$required && empty($value)) { return true; } // Test the value against the regular expression. return parent::test($element, $value, $group, $input, $form); } }PK!bNf/system/nrframework/NRFramework/Rules/nrdate.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class JFormRuleNRDate extends JFormRule { public function test(SimpleXMLElement $element, $value, $group = null, Joomla\Registry\Registry $input = null, JForm $form = null) { if (!$value = trim($value)) { return true; } $format = (string) $element->attributes()->timeformat; return $this->validateDate($value, $format); } /** * Validates the given date with the given format * * @param string $date * @param string $format * * @return boolean */ private function validateDate($date, $format = 'Y-m-d') { $d = DateTime::createFromFormat($format, $date); return $d && $d->format($format) === $date; } }PK!Cf f (system/nrframework/NRFramework/Cache.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ /** * This file is deprecated. Use CacheManager instead of Cache. */ namespace NRFramework; defined('_JEXEC') or die; use \NRFramework\CacheManager; /** * Caching mechanism */ class Cache { /** * Check if has alrady exists in memory * * @param string $hash The hash string * * @return boolean */ static public function has($hash) { $cache = CacheManager::getInstance(\JFactory::getCache('novarain', '')); return $cache->has($hash); } /** * Returns hash value * * @param string $hash The hash string * * @return mixed False on error, Object on success */ static public function get($hash) { $cache = CacheManager::getInstance(\JFactory::getCache('novarain', '')); return $cache->get($hash); } /** * Sets on memory the hash value * * @param string $hash The hash string * @param mixed $data Can be string or object * * @return mixed */ static public function set($hash, $data) { $cache = CacheManager::getInstance(\JFactory::getCache('novarain', '')); return $cache->set($hash, $data); } /** * Reads hash value from memory or file * * @param string $hash The hash string * @param boolean $force If true, the filesystem will be used as well on the /cache/ folder * * @return mixed The hash object valuw */ static public function read($hash, $force = false) { $cache = CacheManager::getInstance(\JFactory::getCache('novarain', '')); return $cache->read($hash, $force); } /** * Writes hash value in cache folder * * @param string $hash The hash string * @param mixed $data Can be string or object * @param integer $ttl Expiration duration in milliseconds * * @return mixed The hash object value */ static public function write($hash, $data, $ttl = 0) { $cache = CacheManager::getInstance(\JFactory::getCache('novarain', '')); return $cache->write($hash, $data, $ttl); } /** * Memoize a function to run once per runtime * * @param string $key The key to store the result of the callback * @param callback $callback The callable anonymous function to call * * @return mixed */ static public function memo($key, callable $callback) { $hash = md5($key); if (Cache::has($hash)) { return Cache::get($hash); } return Cache::set($hash, $callback()); } }PK!@ /system/nrframework/NRFramework/CacheManager.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined('_JEXEC') or die; /** * Cache Manager * * Singleton */ class CacheManager { /** * 'static' cache array * @var array */ protected $cache = []; /** * Cache mechanism object * @var object */ protected $cache_mechanism = null; /** * Construct */ protected function __construct($cache_mechanism) { $this->cache_mechanism = $cache_mechanism; } static public function getInstance($cache_mechanism) { static $instance = null; if ($instance === null) { $instance = new CacheManager($cache_mechanism); } return $instance; } /** * Check if a hash already exists in memory * * @param string $hash The hash string * * @return boolean */ public function has($hash) { return isset($this->cache[$hash]); } /** * Returns a hash's value * * @param string $hash The hash string * * @return mixed False on error, Object on success */ public function get($hash) { if (!$this->has($hash)) { return false; } return is_object($this->cache[$hash]) ? clone $this->cache[$hash] : $this->cache[$hash]; } /** * Sets a hash value * * @param string $hash The hash string * @param mixed $data Can be string or object * * @return mixed */ public function set($hash, $data) { $this->cache[$hash] = $data; return $data; } /** * Reads a hash value from memory or file * * @param string $hash The hash string * @param boolean $force If true, the filesystem will be used as well on the /cache/ folder * * @return mixed The hash object value */ public function read($hash, $force = false) { if ($this->has($hash)) { return $this->get($hash); } if ($force) { $this->cache_mechanism->setCaching(true); } return $this->cache_mechanism->get($hash); } /** * Writes hash value in cache folder * * @param string $hash The hash string * @param mixed $data Can be string or object * @param integer $ttl Expiration duration in milliseconds * * @return mixed The hash object value */ public function write($hash, $data, $ttl = 0) { if ($ttl) { $this->cache_mechanism->setLifeTime($ttl * 60); } $this->cache_mechanism->setCaching(true); $this->cache_mechanism->store($data, $hash); $this->set($hash, $data); return $data; } }PK!軼8||0system/nrframework/NRFramework/SmartTags/URL.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class URL extends SmartTag { /** * Returns the URL * * @return string */ public function getURL() { return $this->factory->getURI()->toString(); } /** * Returns the URL encoded * * @return string */ public function getEncoded() { return urlencode($this->factory->getURI()->toString()); } /** * Returns the site URL * * @return string */ public function getPath() { $url = $this->factory->getURI(); return $url::current(); } }PK!y>EE6system/nrframework/NRFramework/SmartTags/SmartTags.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); use NRFramework\Cache; use Joomla\Registry\Registry; use Joomla\String\StringHelper; /** * SmartTags replaces placeholder variables in a string */ class SmartTags { /** * Factory Class * * @var object */ protected $factory; /** * Path where each extension stores * their Smart Tags. * * @var array */ protected $paths; /** * Tags Array * * @var array */ protected $tags = []; /** * All the options that we were given. * This is stored in case we were given options * other then the prefix/placeholder such as a user. * This is useful for other plugins to manipulate the user, etc... * * @var array */ protected $options; /** * The Smart Tags pattern used to find all available Smart Tags in a subject. * * @var string */ protected $pattern; /** * The Smart Tag prefix * * @var string */ protected $prefix = ''; /** * The Smart Tag placeholder * * @var string */ private $placeholder = '{}'; /** * List of excluded files within the NRFramework\SmartTags namespace * * @var array */ protected $excluded_smart_tags_files = [ '.', '..', 'index.php', 'SmartTag.php', 'SmartTags.php' ]; /** * Smart Tags Constructor * * @param array $opts An array of options(prefix, placeholder) * @param Factory $factory NRFramework Factory */ public function __construct($opts = [], $factory = null) { $this->options = $opts; // set options if (is_array($opts)) { $this->prefix = isset($opts['prefix']) ? $opts['prefix'] : $this->prefix; $this->placeholder = isset($opts['placeholder']) ? $opts['placeholder'] : $this->placeholder; } $this->pattern = $this->getPattern(); // Set Factory if (!$factory) { $factory = new \NRFramework\Factory(); } $this->factory = $factory; // register NRFramework Smart Tags $this->register('\NRFramework\SmartTags', dirname(__DIR__) . '/SmartTags'); } /** * Get a cache instance of the class * * @param array $opts An array of options(prefix, placeholder) * @param object $factory The framework's factory class * * @return object */ static public function getInstance($opts = [], $factory = null) { static $instance = null; if ($instance === null) { $instance = new SmartTags($opts, $factory); } return $instance; } /** * Registers a namespace, path and some data where Smart Tags are stored. * * @param string $namespace * @param string $path * @param array $data * * @return void */ public function register($namespace, $path, $data = []) { if (!$namespace || !$path) { return; } if (isset($this->paths[$namespace])) { return; } $this->paths[$namespace] = [ 'path' => $path ]; if (isset($data)) { $this->paths[$namespace]['data'] = $data; } } /** * Adds Custom Tags to the list * * @param mixed $tags Tags list (Array or Object) * @param string $prefix A string to prefix all keys */ public function add($tags, $prefix = null) { if (!$tags || !is_array($tags)) { return; } // Start of Convert Forms View Submissions Compatibility Issue // This block is added to handle the backwards compatibility issue occured in the front-end submissions view // in Convert Forms which adds submissions smart tags with curly brackets {}. // @deprecated - Scheduled to be removed at the end of 2021 foreach ($tags as $key => $value) { if (strpos($key, '{') === false) { continue; } $newKey = ltrim($key, '{'); $newKey = rtrim($newKey, '}'); $tags[$newKey] = $value; } // End of Convert Forms View Submissions Compatibility Issue // Add Prefix to keys if ($prefix) { foreach ($tags as $key => $value) { $newKey = strtolower($prefix . $key); $tags[$newKey] = $value; unset($tags[$key]); } } $this->tags = array_merge($this->tags, $tags); return $this; } /** * Returns placeholder in 2 pieces * * @return array */ protected function getPlaceholder() { return str_split($this->placeholder, strlen($this->placeholder) / 2); } /** * Replace tags in object recursively * * @param mixed $obj The data object to search for Smart Tags * * @return mixed */ public function replace($subject) { if (is_string($subject)) { $this->replaceFoundSmartTags($subject); } if (is_array($subject) || is_object($subject)) { foreach ($subject as $key => &$subject_item) { $subject_item = $this->replace($subject_item); } } return $subject; } /** * Finds and replaces found Smart Tags in given content * * @param string $content * * @return void */ private function replaceFoundSmartTags(&$content) { // if no smart tags exist in content, abort if (!$this->textHasShortcode($content)) { return; } // find all Smart Tags preg_match_all($this->pattern, $content, $matches); // find all Smart Tags and keep the unique only $foundSmartTags = array_unique($matches[0]); // replaces all Smart Tags in given content $this->replaceSmartTagsInContent($content, $foundSmartTags); return $content; } /** * Replaces all Smart Tags in given content * * @param string $string * @param array $foundSmartTags * * @return void */ private function replaceSmartTagsInContent(&$content, $foundSmartTags) { $tag_value_pairs = []; // find values for each Smart Tag foreach ($foundSmartTags as $tag) { // prepare the smart tag that is going to be processed if (!$shortCodeObject = $this->parseShortcode($tag)) { continue; } $smartTagName = $shortCodeObject['name']; $smartTagClassName = $shortCodeObject['group']; // Check if the tag is already processed by a previous operation or its value provided in the payload. if (isset($this->tags[$smartTagName])) { $tag_value_pairs[$tag] = $this->tags[$smartTagName]; continue; } // OK, we don't know the value yet. Let's see if there's a method available we can call to get a value. $smartTagNamespace = $shortCodeObject['namespace']; // get the Smart Tag class if (!$smartTag = $this->getSmartTagClassByName($smartTagNamespace, $smartTagClassName, $shortCodeObject['options'])) { /** * No method found to call. If the current Smart Tag was added via add(), remove it, otherwise, leave it as is. * * This is due to without this check, a Smart Tag may be given i.e. {convertforms 1} which would be removed and thus Convert Forms * wouldn't be able to replace it. We must only remove Smart Tags that were added by add(). */ if (count($this->tags)) { foreach ($this->tags as $key => $value) { if (strpos($key, $shortCodeObject['group']) !== 0) { continue; } $tag_value_pairs[$tag] = ''; break; } } continue; } // Set data for Smart Tag if they exist in the path data. if (isset($this->paths[$smartTagNamespace]['data'])) { $smartTag->setData($this->paths[$smartTagNamespace]['data']); } // Make sure the Smart Tag can do replacements. if (!$smartTag->canRun()) { continue; } // Get the Smart Tag value $value = $this->getSmartTagValue($smartTag, $shortCodeObject); // parse the value to ensure we can save it $layout = $shortCodeObject['options'] ? $shortCodeObject['options']->get('layout', '') : null; $this->prepareSmartTagValue($value, $layout); // cache value $this->tags[$smartTagName] = $value; // replace all instances of Smart Tag with its value $tag_value_pairs[$tag] = $value; } if (!$tag_value_pairs) { return; } // replace all found Smart Tag key,value pairs foreach ($tag_value_pairs as $tag => $value) { $content = str_ireplace($tag, (string) $value, $content); } } /** * Prepares the Smart Tag value prior to saving it * * @param string $value * * @return void */ protected function prepareSmartTagValue(&$value, $layout = '') { if (!$value) { return $value; } // Convert string or objects to array $values = (array) $value; if (empty($layout)) { $value = implode(',', $values); return; } $result = ''; foreach ($values as $value) { $result .= str_replace('%value%', $value, $layout); } $value = $result; } /** * Parse shortcode and return an array of the shortcode information like, classname, method name e.t.c. * * The expected shortcode syntax is as follow: {GROUP[.NAME]} * * The GROUP part is required and must be pointing to \NRFramework\SmartTags\GROUP file which must declare a class with the name GROUP. * Eg: The shortcode {customer} will try to find a class with the name Customer in the \NRFramework\SmartTags\Customer namespace. * * The NAME part represents the name of the method in the called class. * For example, the shortcode {customer.name} will call the getName() method in the \NRFramework\SmartTags\Customer class. * * If the NAME part is ommitted or is invalid, Smart Tags fallbacks to a method with the same name as the class. * For example, the shortcode {customer} will call the getCustomer() method in the \NRFramework\SmartTags\Customer class. * * @param string $text * * @return array */ private function parseShortcode($text) { if (empty($text)) { return; } // Remove placeholders and prefix from the shortcode. {device} becomes device $placeholder = $this->getPlaceholder(); $text = ltrim($text, $placeholder[0] . $this->prefix); $text = rtrim($text, $placeholder[1]); $shortcodeTag = $text; $shortcodeOptions = null; // Split shortcode into 2 parts. First part should be the Smart Tag itself and the 2nd part should be the parameters. $firstOptionPos = strpos($text, '--'); if ($firstOptionPos !== false) { $shortcodeOptions = substr($text, $firstOptionPos - strlen($text)); $shortcodeTag = substr($text, 0, $firstOptionPos - 1); } // We expect a shortcode in 2 parts separated by a dot. // The 1st part is the Smart Tags Group (Class Name) and the 2nd part is the Name of the actual Smart Tag (Method name, optional). $textParts = explode('.', $shortcodeTag, 2); $group = $textParts[0]; $key = isset($textParts[1]) ? $textParts[1] : $textParts[0]; // Find shortcode options --option=value if (!is_null($shortcodeOptions)) { $shortcodeOptions = $this->parseOptions($shortcodeOptions); } return [ 'name' => $text, // Rename to shortcode 'group' => $group, 'key' => $key, 'method_name' => 'get' . $key, 'namespace' => $this->getSmartTagNamespace($group), 'options' => $shortcodeOptions ]; } /** * Parase shortcode options * * @param string $text The original short code * * @return mixed Null when no options are found, Registry object otherwise. */ public function parseOptions($text) { // A quick test to determine whether to proceed or not. if (strpos($text, '--') === false) { return; } $regex = '--(.*?)[\W]'; preg_match_all('/' . $regex . '/is', $text, $params); $options = []; // @Todo use Regex to parse both option name and value. for ($i = 0; $i < count($params[1]); $i++) { $paramName = $params[0][$i]; $thisParamPosition = mb_strpos($text, $params[0][$i]); $nextParamPosition = isset($params[0][$i + 1]) ? mb_strpos($text, $params[0][$i + 1]) - strlen($text) : null; $paramValue = \mb_substr($text, $thisParamPosition + strlen($paramName), $nextParamPosition); $options[strtolower($params[1][$i])] = trim($paramValue); } return new Registry($options); } /** * Returns the Smart Tags Value * * @param SmartTag $smartTag * @param array $shortCodeObject The parsed shortcode object * * @return mixed */ protected function getSmartTagValue($smartTag, $shortCodeObject) { // Smart Tags method name $smartTagMethod = $shortCodeObject['method_name']; // make sure method exists in the Smart Tag class if (method_exists($smartTag, $smartTagMethod)) { return $smartTag->{$smartTagMethod}(); } /** * Check if the Smart Tag contains a method * to fetch the Smart Tag we are trying to replace. */ if (method_exists($smartTag, 'fetchValue')) { return $smartTag->fetchValue($shortCodeObject['key']); } } /** * Returns the Smart Tag Class given the name of the Smart Tag * * @param string $smartTagNamespace * @param string $smartTagClassName * * @return mixed */ private function getSmartTagClassByName($smartTagNamespace, $smartTagClassName, $shortcodeOptions = null) { // get namespace classes $namespace_classes = $this->getNamespaceClasses($smartTagNamespace); if (!isset($namespace_classes[strtolower($smartTagClassName)])) { return false; } $smartTagClass = $smartTagNamespace . '\\' . $namespace_classes[strtolower($smartTagClassName)]; $options = $this->options; $options['options'] = $shortcodeOptions; // return smart class return new $smartTagClass($this->factory, $options); } /** * Retrieves the cached namespace clases or finds them in the given path * * @param string $namespace * @param string $path * * @return array */ private function getNamespaceClasses($namespace, $path = null) { $cache = $this->factory->getCache(); $hash = md5('nrf_smarttags_' . $namespace); // if namespace classes are cached, retrieve them if ($cache->has($hash)) { return $cache->get($hash); } // if no cached namespace classes exist, ensure we were given a valid path if (!$path && !is_string($path)) { return []; } // find namespace classes $namespace_classes = \JFolder::files($path, '.', false, false, $this->excluded_smart_tags_files); // stores the final strtolower(class name) => actual class file name data $classes_data = []; // retrieve the strtolower(class name) => class file name array foreach ($namespace_classes as $className) { $base_class_name = str_replace('.php', '', $className); $classes_data[strtolower($base_class_name)] = $base_class_name; } // cache it return $cache->set($hash, $classes_data); } /** * Find the namespace of the class in the path list * * @param string $class_name * * @return mixed */ private function getSmartTagNamespace($class_name) { if (!$class_name && !is_string($class_name)) { return false; } foreach ($this->paths as $namespace => $path_data) { // get namespace classes $namespace_classes = $this->getNamespaceClasses($namespace, $path_data['path']); if (!isset($namespace_classes[strtolower($class_name)])) { continue; } return $namespace; } return false; } /** * Return the regular expression pattern that will be used for searches * * @return string */ private function getPattern() { $placeholder = $this->getPlaceholder(); $prefix = $this->prefix ? preg_quote($this->prefix) . '.' : ''; return '#(\\' . $placeholder[0] . $prefix . '([a-zA-Z]\\' . $placeholder[0] . '??[^\\' . $placeholder[0] . ']*?\\' . $placeholder[1] . '))#'; } /** * Super fast way to determine whether given text includes shortcodes * * @param string $text * * @return boolean */ private function textHasShortcode($text) { return StringHelper::strpos($text, $this->getPlaceholder()[0] . $this->prefix) !== false; } /** * Returns list of all tags found in given paths * * Currently used in the Convert Forms Front-end Submissions Menu Type and in the EngageBox SmartTags modal. * * @deprecated since 4.5.6 * * @return array */ public function get() { $placeholder = $this->getPlaceholder(); // get all tags that have already been added to the list $smart_tags_data = $this->tags; // loop all registered paths foreach ($this->paths as $namespace => $path_data) { if (!isset($path_data['path'])) { continue; } if (!is_dir($path_data['path'])) { continue; } // find all smart tags $files = \JFolder::files($path_data['path'], '.', false, false, $this->excluded_smart_tags_files); // search all files foreach ($files as $className) { $baseClassName = str_replace('.php', '', $className); $className = $namespace . '\\' . $baseClassName; if (!class_exists($className)) { continue; } // reflection class of smart tag $reflectionSmartTag = new \ReflectionClass($className); // search all methods foreach($reflectionSmartTag->getMethods() as $method) { // Only parse Smart Tags of current class and not from its parent if ($method->class != ltrim($className, '\\')) { continue; } // get smart tag name from each getSmartTag method if (strpos($method->name, 'get') !== 0) { continue; } $funcNameSplit = explode('get', $method->name); $suffix = ''; if (strtolower($funcNameSplit[1]) != strtolower($reflectionSmartTag->getShortName())) { $suffix = '.' . $funcNameSplit[1]; } $smartTagPrefix = $placeholder[0] . strtolower($reflectionSmartTag->getShortName() . $suffix) . $placeholder[1]; $smart_tags_data[$smartTagPrefix] = ''; } } } return $smart_tags_data; } }PK!41system/nrframework/NRFramework/SmartTags/User.phpnu[ or later */ namespace NRFramework\SmartTags; use NRFramework\Cache; defined('_JEXEC') or die('Restricted access'); class User extends SmartTag { /** * Fetch a property from the User object * * @param string $key The name of the property to return * * @return mixed Null if property is not found, mixed if property is found */ public function fetchValue($key) { // Just in case, deny access to the 'password' property if ($key == 'password') { return; } // Case custom fields: {user.field.age} if (strpos($key, 'field.') !== false) { $fieldname = str_replace('field.', '', $key); if ($fields = $this->fetchUserFields()) { if (array_key_exists($fieldname, $fields)) { return $fields[$fieldname]->value; } } return; } // Standard user info: {user.name} $user = $this->getUser(); if (is_null($user) || $user->id == 0 || !isset($user->{$key})) { return; } return $user->{$key}; } /** * Return an assosiative array with user custoom fields * * @return mixed Array on success, null on failure */ private function fetchUserFields() { $callback = function() { \JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'); if (!$fields = \FieldsHelper::getFields('com_users.user', $this->getUser(), true)) { return; } $fieldsAssoc = []; foreach ($fields as $field) { $fieldsAssoc[$field->name] = $field; } return $fieldsAssoc; }; return Cache::memo('fetchUserFields', $callback); } /** * Return the user object * * @return Juser */ private function getUser() { return $this->factory->getUser(isset($this->options['user']) ? $this->options['user'] : null); } /** * Returns the name of the user capitalized * * @return string */ public function getName() { return ucwords(strtolower($this->fetchValue('name'))); } /** * Returns the user first name * * @return string */ public function getFirstname() { // Set first name $nameParts = explode(' ', $this->getName(), 2); $firstname = trim($nameParts[0]); return $firstname; } /** * Returns the user last name * * @return string */ public function getLastname() { // Set last name $nameParts = explode(' ', $this->getName(), 2); $lastname = isset($nameParts[1]) ? trim($nameParts[1]) : $nameParts[0]; return $lastname; } /** * Returns the user login * * @deprecated Use {user.username} * * @return string */ public function getLogin() { return $this->fetchValue('username'); } /** * Returns the user register date * * @return string */ public function getRegisterDate() { if (!$date = $this->fetchValue('registerDate')) { return; } return \JHtml::_('date', $date, \JText::_('DATE_FORMAT_LC5')); } }PK!*kGD4system/nrframework/NRFramework/SmartTags/Article.phpnu[ or later */ namespace NRFramework\SmartTags; use NRFramework\Conditions\Conditions\Component\ContentBase; defined('_JEXEC') or die('Restricted access'); class Article extends SmartTag { /** * Fetch a property from the User object * * @param string $key The name of the property to return * * @return mixed Null if property is not found, mixed if property is found */ public function fetchValue($key) { $contentAssignment = new ContentBase(); if (!$contentAssignment->isSinglePage()) { return; } // Why the heck $isSinglePage below returns false? // $articleAssignment = new \NRFramework\Conditions\Component\ContentArticle(); // $isSinglePage = $articleAssignment->pass(); $article = $contentAssignment->getItem(); if (!isset($article->{$key}) || is_object($article->{$key})) { return; } return $article->{$key}; } }PK!|`--1system/nrframework/NRFramework/SmartTags/Date.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Date extends SmartTag { /** * Constructor * * @param object $factory The framework factory object * @param array $options Assignment configuration options */ public function __construct($factory = null, $options = null) { parent::__construct($factory, $options); $this->tz = new \DateTimeZone($this->factory->getApplication()->getCfg('offset', 'GMT')); $this->date = $this->factory->getDate()->setTimezone($this->tz); } /** * Returns the current date * * @return string */ public function getDate() { $format = $this->parsedOptions->get('format', 'Y-m-d H:i:s'); return $this->date->format($format, true); } }PK!4GY:1system/nrframework/NRFramework/SmartTags/Page.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Page extends SmartTag { /** * Returns the page title * * @return string */ public function getTitle() { return $this->doc->getTitle(); } /** * Returns the page description * * @return string */ public function getDesc() { return $this->doc->getMetaData('description'); } /** * Returns the page keywords * * @return string */ public function getKeywords() { return $this->doc->getMetaData('keywords'); } /** * Returns the locale * * @return string */ public function getLang() { return $this->doc->getLanguage(); } /** * Returns the language code used in URLs * * @return string */ public function getLangURL() { return explode('-', $this->doc->getLanguage())[0]; } /** * Returns the page generator * * @return string */ public function getGenerator() { return $this->doc->getGenerator(); } /** * Returns the browser title * * @return string */ public function getBrowserTitle() { if (!$menu = $this->app->getMenu()->getActive()) { return ''; } return $menu->getParams()->get('page_title'); } }PK!5system/nrframework/NRFramework/SmartTags/Language.phpnu[ or later */ namespace NRFramework\SmartTags; use Joomla\CMS\Language\Text; defined('_JEXEC') or die('Restricted access'); class Language extends SmartTag { /** * Fetch specific translation string value * * @param string $key * * @return string */ public function fetchValue($key) { $key = strtolower($key); $key_parts = explode('_', $key); $lang = $this->factory->getLanguage(); // Load language overrides: On front-end load administrator's override and vice versa. $overridePath = $this->factory->isFrontend() ? JPATH_ADMINISTRATOR : JPATH_SITE; $lang->load($lang->getTag() . '.override', $overridePath, 'overrides'); switch ($key_parts[0]) { case 'com': if (isset($key_parts[1]) && !empty($key_parts[1])) { $extension = 'com_' . $key_parts[1]; } $lang->load($extension, JPATH_ADMINISTRATOR); $lang->load($extension, JPATH_SITE); break; case 'plg': if (isset($key_parts[1]) && !empty($key_parts[1]) && isset($key_parts[2]) && !empty($key_parts[2])) { $extension = implode('_', ['plg', $key_parts[1], $key_parts[2]]); } $path = implode(DIRECTORY_SEPARATOR, [JPATH_PLUGINS, $key_parts[1], $key_parts[2]]); $lang->load($extension, $path); break; } return Text::_($key); } }PK!OKK8system/nrframework/NRFramework/SmartTags/QueryString.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class QueryString extends SmartTag { /** * Fetch value of a specific query string * * @param string $key * * @return string */ public function fetchValue($key) { $query = $this->factory->getURI()->getQuery(true); if (empty($query)) { return; } // Convert array keys to lowercase $query = array_change_key_case($query); // Convert key to lowercase too $key = strtolower($key); return array_key_exists($key, $query) ? \JFilterInput::getInstance()->clean($query[$key]) : ''; } }PK!YL0system/nrframework/NRFramework/SmartTags/Day.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Day extends Date { /** * Returns the current day * * @return string */ public function getDay() { return $this->date->format('j'); } }PK!-((3system/nrframework/NRFramework/SmartTags/Client.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Client extends SmartTag { /** * Returns the device * * @return string */ public function getDevice() { return \NRFramework\WebClient::getDeviceType(); } /** * Returns the OS * * @return string */ public function getOS() { return \NRFramework\WebClient::getOS(); } /** * Returns the browser * * @return string */ public function getBrowser() { return \NRFramework\WebClient::getBrowser()['name']; } /** * Returns the current user agent * * @return string */ public function getUserAgent() { return \NRFramework\WebClient::getClient()->userAgent; } }PK!45system/nrframework/NRFramework/SmartTags/RandomID.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class RandomID extends SmartTag { /** * Returns a random ID * * @return string */ public function getRandomID() { return bin2hex(\JCrypt::genRandomBytes(8)); } }PK!sO2system/nrframework/NRFramework/SmartTags/Month.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Month extends Date { /** * Returns the current month * * @return string */ public function getMonth() { return $this->date->format('n'); } }PK!_1system/nrframework/NRFramework/SmartTags/Year.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Year extends Date { /** * Returns the current year * * @return string */ public function getYear() { return $this->date->format('Y'); } }PK!9S 5system/nrframework/NRFramework/SmartTags/SmartTag.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); use Joomla\Registry\Registry; abstract class SmartTag { /** * Factory Class * * @var object */ protected $factory; /** * Joomla Application object * * @var object */ protected $app; /** * Joomla Document * * @var object */ protected $doc; /** * Useful data used by a Smart Tag * * @var array */ protected $data; /** * Smart Tags Configuration Options * * @var array */ protected $options; public function __construct($factory = null, $options = null) { if (!$factory) { $factory = new \NRFramework\Factory(); } $this->factory = $factory; $this->app = $this->factory->getApplication(); $this->doc = $this->factory->getDocument(); $this->parsedOptions = isset($options['options']) ? $options['options'] : new Registry(); $this->options = $options; } /** * Set the data * * @param array $data * * @return void */ public function setData($data) { $this->data = $data; } /** * This method runs before replacements and determines whether the class can be executed and do replacements or not. * * THE PROBLEM: * * Let's say we have a bunch of Smart Tags in a namespaced folder and we register them using the register() method. * The Smart Tags include, Foo and Bar. Let's say our replacement subject is: 'lorem {foo.x} ipsum {foo.y} lorem ipsum {bar.x}' * and we'd like to replace {foo.x} and {foo.y} and leave {bar.x} untouched. Right now this is not possible. * All 3 Smart Tags will be replaced in the subject because all classes are already registered. * * This problem occurs also in Convert Forms during form rendering. When a form is using Calculations, it's very likely * a calculation formula in the form {field.XXX} + {field.YYY} is included in the form's HTML layout. * In Convert Forms, Smart Tag replacements run during page load. Since we have a Smart Tag for Fields {field.XXX} already registered, * the Smart Tags found in the Calculations formula will be replaced by empty space (there's no submitted data yet) breaking Calculation. * * We need a way to determine during runtime whether a Smart Tag can run or not. * * We could write a new method so 3rd party extension can register individual classes conditionally but this would add more work on the extension's side. * * @return boolean */ public function canRun() { return true; } }PK!2``1system/nrframework/NRFramework/SmartTags/Site.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Site extends SmartTag { /** * Returns the site email * * @return string */ public function getEmail() { return $this->app->get('mailfrom'); } /** * Returns the site name * * @return string */ public function getName() { return $this->app->get('sitename'); } /** * Returns the site URL * * @return string */ public function getURL() { $url = $this->factory->getURI(); return $url::root(); } }PK! (--5system/nrframework/NRFramework/SmartTags/Referrer.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Referrer extends SmartTag { /** * Returns the current Referrer * * @return string */ public function getReferrer() { return $this->app->input->server->get('HTTP_REFERER', '', 'RAW'); } }PK!Ƙ݋1system/nrframework/NRFramework/SmartTags/Time.phpnu[ or later */ namespace NRFramework\SmartTags; defined('_JEXEC') or die('Restricted access'); class Time extends Date { /** * Returns the current time * * @return string */ public function getTime() { return $this->date->format('H:i', true); } }PK!е/system/nrframework/NRFramework/SmartTags/IP.phpnu[ or later */ namespace NRFramework\SmartTags; use NRFramework\User; defined('_JEXEC') or die('Restricted access'); class IP extends SmartTag { /** * Returns the IP address * * @return string */ public function getIP() { return User::getIP(); } }PK!*( :system/nrframework/NRFramework/Integrations/ConvertKit.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; use Joomla\String\StringHelper; class ConvertKit extends Integration { /** * Create a new instance * * @param string $api_key Your ConvertKit API Key */ public function __construct($api_key) { parent::__construct(); $this->setKey($api_key); $this->setEndpoint('https://api.convertkit.com/v3'); } /** * Subscribe a user to a ConvertKit Form * * API Reference: * http://help.convertkit.com/article/33-api-documentation-v3 * * @param string $email The subscriber's email * @param string $formid The account owner's form id * @param array $params The form's parameters * * @return boolean */ public function subscribe($email, $formid, $params) { $first_name = (isset($params['first_name'])) ? $params['first_name'] : ''; $tags = (isset($params['tags'])) ? $this->convertTagnamesToTagIDs($params['tags']) : ''; $fields = $this->validateCustomFields($params); $data = array( 'api_key' => $this->key, 'email' => $email, 'first_name' => $first_name, 'tags' => $tags, 'fields' => $fields, ); $this->post('forms/' . $formid . '/subscribe', $data); return true; } /** * Converts tag names to tag IDs for the subscribe method * * @param string $tagnames comma separated list of tagnames * * @return string comma separated list of tag IDs */ public function convertTagnamesToTagIDs($tagnames) { if (empty($tagnames)) { return; } $tagArray = !is_array($tagnames) ? explode(',', $tagnames) : $tagnames; $tagnames = array_map('trim', $tagArray); $accountTags = $this->get('tags', array('api_key' => $this->key)); if (empty($accountTags) || !$this->request_successful) { return; } $tagIDs = array(); foreach ($accountTags['tags'] as $tag) { foreach ($tagnames as $tagname) { if (StringHelper::strcasecmp($tag['name'], $tagname) == 0) { $tagIDs[] = $tag['id']; break; } } } return implode(',', $tagIDs); } /** * Returns a new array with valid only custom fields * * @param array $formCustomFields Array of custom fields * * @return array Array of valid only custom fields */ public function validateCustomFields($formCustomFields) { if (!is_array($formCustomFields)) { return; } $customFields = $this->get('custom_fields', array('api_key' => $this->key)); if (!$this->request_successful) { return; } $fields = array(); $formCustomFieldsKeys = array_keys($formCustomFields); foreach ($customFields['custom_fields'] as $customField) { if (in_array($customField['key'], $formCustomFieldsKeys)) { $fields[$customField['key']] = $formCustomFields[$customField['key']]; } } return $fields; } /** * Get the last error returned by either the network transport, or by the API. * * @return string */ public function getLastError() { $body = $this->last_response->body; $message = ''; if (isset($body['error']) && !empty($body['error'])) { $message = $body['error']; } if (isset($body['message']) && !empty($body['message'])) { $message .= ' - ' . $body['message']; } return $message; } }PK!d"";system/nrframework/NRFramework/Integrations/Integration.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; jimport('joomla.log.log'); use Joomla\Registry\Registry; class Integration { protected $key; protected $endpoint; protected $request_successful = false; protected $last_error = ''; protected $last_response = []; protected $last_request = []; protected $timeout = 60; protected $options; protected $encode = true; protected $response_type = 'json'; public function __construct() { $this->options = new \JRegistry; $this->options->set('timeout', $this->timeout); $this->options->set('headers.Accept', 'application/json'); $this->options->set('headers.Content-Type', 'application/json'); } /** * Setter method for the API Key or Access Token * * @param string $apiKey */ public function setKey($apiKey) { $apiKey = is_array($apiKey) && isset($apiKey['api']) ? $apiKey['api'] : $apiKey; if (!is_string($apiKey) || empty($apiKey) || is_null($apiKey)) { throw new \Exception('Invalid API Key supplied.'); } $this->key = trim($apiKey); } /** * Setter method for the endpoint * @param string $url The URL which is set in the account's developer settings * @throws \Exception */ public function setEndpoint($url) { if (!empty($url)) { $this->endpoint = $url; } else { throw new \Exception("Invalid Endpoint URL `{$url}` supplied."); } } /** * Was the last request successful? * @return bool True for success, false for failure */ public function success() { return $this->request_successful; } /** * Get the last error returned by either the network transport, or by the API. * If something didn't work, this should contain the string describing the problem. * @return array|false describing the error */ public function getLastError() { return $this->last_error ?: false; } /** * Get an array containing the HTTP headers and the body of the API response. * @return array Assoc array with keys 'headers' and 'body' */ public function getLastResponse() { return $this->last_response; } /** * Get an array containing the HTTP headers and the body of the API request. * @return array Assoc array */ public function getLastRequest() { return $this->last_request; } /** * Make an HTTP DELETE request - for deleting data * @param string $method URL of the API request method * @param array $args Assoc array of arguments (if any) * @return array|false Assoc array of API response, decoded from JSON */ public function delete($method, $args = []) { return $this->makeRequest('delete', $method, $args); } /** * Make an HTTP GET request - for retrieving data * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @return array|false Assoc array of API response, decoded from JSON */ public function get($method, $args = []) { return $this->makeRequest('get', $method, $args); } /** * Make an HTTP PATCH request - for performing partial updates * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @return array|false Assoc array of API response, decoded from JSON */ public function patch($method, $args = []) { return $this->makeRequest('patch', $method, $args); } /** * Make an HTTP POST request - for creating and updating items * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @return array|false Assoc array of API response, decoded from JSON */ public function post($method, $args = []) { return $this->makeRequest('post', $method, $args); } /** * Make an HTTP PUT request - for creating new items * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @return array|false Assoc array of API response, decoded from JSON */ public function put($method, $args = []) { return $this->makeRequest('put', $method, $args); } /** * Performs the underlying HTTP request. Not very exciting. * @param string $http_verb The HTTP verb to use: get, post, put, patch, delete * @param string $method The API method to be called * @param array $args Assoc array of parameters to be passed * @return array|false Assoc array of decoded result * @throws \Exception */ protected function makeRequest($http_verb, $method, $args = []) { $url = $this->endpoint; if (!empty($method) && !is_null($method) && strpos($url, '?') === false) { $url .= '/' . $method; } $this->last_error = ''; $this->request_successful = false; $this->last_response = []; $this->last_request = [ 'method' => $http_verb, 'path' => $method, 'url' => $url, 'body' => '', 'timeout' => $this->timeout, ]; $http = \JHttpFactory::getHttp($this->options); switch ($http_verb) { case 'post': $this->attachRequestPayload($args); $response = $http->post($url, $this->last_request['body']); break; case 'get': $query = http_build_query($args, '', '&'); $this->last_request['body'] = $query; $response = (strpos($url,'?') !== false) ? $http->get($url . '&' . $query) : $http->get($url . '?' . $query); break; case 'delete': $response = $http->delete($url); break; case 'patch': $this->attachRequestPayload($args); $response = $http->patch($url, $this->last_request['body']); break; case 'put': $this->attachRequestPayload($args); $response = $http->put($url, $this->last_request['body']); break; } // Convert body JSON - Do we really need this line? $response->body = $this->convertResponse($response->body); // Format response object to array $this->last_response = $response; $this->determineSuccess(); // Log request if debug is enabled. if (JDEBUG) { $this->logRequest(); } return $this->last_response->body; } /** * Log API request to framework's log file to help troubleshoot issues. * * @return void */ private function logRequest() { $output = ' Request --------------------------------------------------------------------------- ' . print_r($this->last_request, true) . ' Response --------------------------------------------------------------------------- ' . print_r($this->last_response, true) . ' '; try { \JLog::add($output, \JLog::DEBUG, 'nrframework'); } catch (\Throwable $th) { } } /** * Encode the data and attach it to the request * @param array $data Assoc array of data to attach */ protected function attachRequestPayload($data) { if (!$this->encode) { $this->last_request['body'] = http_build_query($data); return; } $this->last_request['body'] = json_encode($data); } /** * Check if the response was successful or a failure. If it failed, store the error. * * @return bool If the request was successful */ protected function determineSuccess() { $status = $this->last_response->code; $success = ($status >= 200 && $status <= 299) ? true : false; return ($this->request_successful = $success); } /** * Converts the HTTP Call response to a traversable type * * @param json|xml $response * * @return array|object */ protected function convertResponse($response) { switch ($this->response_type) { case 'json': return json_decode($response, true); case 'xml': return new \SimpleXMLElement($response); case 'text': return $response; } } /** * Search Custom Fields declared by the user for a specific custom field. If exists return its value. * * @param array $needles The custom field names * @param array $haystack The custom fields array * * @return string The value of the custom field or an empty string if not found */ protected function getCustomFieldValue($needles, $haystack) { $needles = is_array($needles) ? $needles : (array) $needles; $haystack = array_change_key_case($haystack); $found = ''; foreach ($needles as $needle) { $needle = strtolower($needle); if (array_key_exists($needle, $haystack)) { $found = trim($haystack[$needle]); break; } } return $found; } /** * Set encode * * @param boolean $encode * * @return void */ public function setEncode($encode) { $this->encode = $encode; } }PK!ð?system/nrframework/NRFramework/Integrations/CampaignMonitor.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class CampaignMonitor extends Integration { /** * Create a new instance * * @param array $options The service's required options */ public function __construct($options) { parent::__construct(); $this->setKey($options); $this->setEndpoint('https://api.createsend.com/api/v3.1'); $this->options->set('userauth', $this->key); $this->options->set('passwordauth', 'nopass'); } /** * Subscribe user to Campaign Monitor * * API References: * https://www.campaignmonitor.com/api/subscribers/#importing_many_subscribers * Reminder: * The classic add_subscriber method of Campaign Monitor's API is NOT instantaneous! * It is suggested to use their import method for instantaneous subscriptions! * * @param string $email User's email address * @param string $name User's Name * @param string $list The Campaign Monitor list unique ID * @param array $custom_fields Custom Fields * * @return void */ public function subscribe($email, $name, $list, $customFields = array()) { $data = array( 'Subscribers' => array( array( 'EmailAddress' => $email, 'Name' => $name, 'Resubscribe' => true, ), ), ); if (is_array($customFields) && count($customFields)) { $data['Subscribers'][0]['CustomFields'] = $this->validateCustomFields($customFields, $list); } $this->post('subscribers/' . $list . '/import.json', $data); return true; } /** * Returns a new array with valid only custom fields * * @param array $formCustomFields Array of custom fields * * @return array Array of valid only custom fields */ public function validateCustomFields($formCustomFields, $list) { $fields = array(); if (!is_array($formCustomFields)) { return $fields; } $listCustomFields = $this->get('lists/' . $list . '/customfields.json'); if (!$this->request_successful) { return $fields; } $formCustomFieldsKeys = array_keys($formCustomFields); foreach ($listCustomFields as $listCustomField) { $field_name = $listCustomField['FieldName']; if (!in_array($field_name, $formCustomFieldsKeys)) { continue; } $value = $formCustomFields[$field_name]; // Always convert custom field value to array, to support multiple values in a custom field. $value = is_array($value) ? $value : (array) $value; foreach ($value as $val) { $fields[] = array( 'Key' => $field_name, 'Value' => $val, ); } } return $fields; } /** * Get the last error returned by either the network transport, or by the API. * * @return string */ public function getLastError() { $body = $this->last_response->body; $message = ''; if (isset($body['Message'])) { $message = $body['Message']; } if (isset($body['ResultData']['FailureDetails'][0]['Message'])) { $message .= ' - ' . $body['ResultData']['FailureDetails'][0]['Message']; } return $message; } /** * Returns all Client lists * * https://www.campaignmonitor.com/api/clients/#getting-subscriber-lists * * @return array */ public function getLists() { $clients = $this->getClients(); if (!is_array($clients)) { return; } $lists = array(); foreach ($clients as $key => $client) { if (!isset($client['ClientID'])) { continue; } $clientLists = $this->get('/clients/' . $client['ClientID'] . '/lists.json'); if (!is_array($clientLists)) { continue; } foreach ($clientLists as $key => $clientList) { $lists[] = array( 'id' => $clientList['ListID'], 'name' => $clientList['Name'] ); } } return $lists; } /** * Get Clients * * https://www.campaignmonitor.com/api/account/ * * @return mixed Array on success, Null on fail */ private function getClients() { $clients = $this->get('/clients.json'); if (!$this->success()) { return; } return $clients; } }PK!@q*, , 9system/nrframework/NRFramework/Integrations/ReCaptcha.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; /** * The reCAPTCHA Wrapper */ class ReCaptcha extends Integration { /** * Service Endpoint * * @var string */ protected $endpoint = 'https://www.google.com/recaptcha/api/siteverify'; /** * Create a new instance * * @param array $options * * @throws \Exception */ public function __construct($options = array()) { parent::__construct(); if (!array_key_exists('secret', $options)) { $this->setError('NR_RECAPTCHA_INVALID_SECRET_KEY'); throw new \Exception($this->getLastError()); } $this->setKey($options['secret']); } /** * Calls the reCAPTCHA siteverify API to verify whether the user passes reCAPTCHA test. * * @param string $response Response string from recaptcha verification. * @param string $remoteip IP address of end user * * @return bool Returns true if the user passes reCAPTCHA test */ public function validate($response, $remoteip = null) { if (empty($response) || is_null($response)) { return $this->setError('NR_RECAPTCHA_PLEASE_VALIDATE'); } $data = array( 'secret' => $this->key, 'response' => $response, 'remoteip' => $remoteip ?: \NRFramework\User::getIP(), ); $this->get('', $data); return true; } /** * Check if the response was successful or a failure. If it failed, store the error. * * @return bool If the request was successful */ protected function determineSuccess() { $success = parent::determineSuccess(); $body = $this->last_response->body; if ($body['success'] == false && array_key_exists('error-codes', $body) && count($body['error-codes']) > 0) { $success = $this->setError(implode(', ', $body['error-codes'])); } return ($this->request_successful = $success); } /** * Set wrapper error text * * @param String $error The error message to display */ private function setError($error) { $this->last_error = \JText::_('NR_RECAPTCHA') . ': ' . \JText::_($error); return false; } }PK!E3jTT:system/nrframework/NRFramework/Integrations/Salesforce.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class SalesForce extends Integration { /** * Service API Endpoint * * @var string */ protected $endpoint = 'https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8'; /** * Encode data before sending the request * * @var boolean */ protected $encode = false; /** * Create a new instance * @param string $organizationID Your SalesForce Organization ID * @throws \Exception */ public function __construct($organization_id) { parent::__construct(); $organization_id = is_array($organization_id) ? $organization_id['api'] : $organization_id; $this->setKey($organization_id); $this->options->set('headers.Content-Type', 'application/x-www-form-urlencoded'); } /** * Subscribe user to SalesForce * * API References: * https://developer.salesforce.com/page/Wordpress-to-lead * * @param string $email User's email address * @param array $params All the form fields * * @return void */ public function subscribe($email, $params) { $data = array( "email" => $email, "oid" => $this->key ); if (is_array($params) && count($params)) { $data = array_merge($data, $params); } $this->post('', $data); return true; } /** * Determine if the Lead has been stored successfully in SalesForce * * @return string */ public function determineSuccess() { $status = $this->last_response->code; if ($status < 200 && $status > 299) { return false; } $headers = $this->last_response->headers; if (isset($headers['Is-Processed']) && (strpos($headers['Is-Processed'], 'Exception') !== false)) { $this->last_error = \JText::_('PLG_CONVERTFORMS_SALESFORCE_ERROR'); return false; } return ($this->request_successful = true); } }PK!0I< 8system/nrframework/NRFramework/Integrations/HCaptcha.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; /** * The HCaptcha Wrapper */ class HCaptcha extends Integration { /** * Service Endpoint * * @var string */ protected $endpoint = 'https://hcaptcha.com/siteverify'; /** * Create a new instance * * @param array $options * * @throws \Exception */ public function __construct($options = []) { parent::__construct(); if (!array_key_exists('secret', $options)) { $this->setError('NR_RECAPTCHA_INVALID_SECRET_KEY'); throw new \Exception($this->getLastError()); } $this->setKey($options['secret']); } /** * Calls the hCaptcha siteverify API to verify whether the user passes hCaptcha test. * * @param string $response Response string from hCaptcha verification. * @param string $remoteip IP address of end user * * @return bool Returns true if the user passes hCaptcha test */ public function validate($response, $remoteip = null) { if (empty($response) || is_null($response)) { return $this->setError('NR_RECAPTCHA_PLEASE_VALIDATE'); } // remove these headers in order for hCaptcha to be abl to process the request $this->options->remove('headers.Accept'); $this->options->remove('headers.Content-Type'); // do not encode request $this->setEncode(false); $data = [ 'secret' => $this->key, 'response' => $response, ]; $this->post('', $data); return true; } /** * Check if the response was successful or a failure. If it failed, store the error. * * @return bool If the request was successful */ protected function determineSuccess() { $success = parent::determineSuccess(); $body = $this->last_response->body; if ($body['success'] == false && array_key_exists('error-codes', $body) && count($body['error-codes']) > 0) { $success = $this->setError(implode(', ', $body['error-codes'])); } return ($this->request_successful = $success); } /** * Set wrapper error text * * @param String $error The error message to display */ private function setError($error) { $this->last_error = \JText::_('NR_HCAPTCHA') . ': ' . \JText::_($error); return false; } }PK!?g*&*&>system/nrframework/NRFramework/Integrations/ActiveCampaign.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class ActiveCampaign extends Integration { /** * Create a new instance * @param array $options The service's required options */ public function __construct($options) { parent::__construct(); $this->setKey($options); $this->setEndpoint($options['endpoint'] . '/api/3'); $this->options->set('headers.Api-Token', $this->key); } /** * Subscribe user to ActiveCampaign List * * https://developers.activecampaign.com/v3/reference#create-contact * * @param string $email The Email of the Contact * @param string $name The name of the Contact (Name can be also declared in Custom Fields) * @param string $list List ID * @param string $tags Tags for this contact (comma-separated). Example: "tag1, tag2, etc" * @param array $customfields Custom Fields * @param boolean $updateexisting Update Existing User * * @return void */ public function subscribe($email, $name = null, $lists, $tags = '', $customfields = array(), $updateexisting) { // Detect name $name = (is_null($name) || empty($name)) ? $this->getNameFromCustomFields($customfields) : explode(' ', $name, 2); $apiAction = ($updateexisting) ? 'contact/sync' : 'contacts'; $data = [ 'contact' => [ 'email' => $email, 'firstName' => isset($name[0]) ? $name[0] : null, 'lastName' => isset($name[1]) ? $name[1] : null, 'phone' => $this->getCustomFieldValue('phone', $customfields) ], ]; $this->post($apiAction, $data); if (!$this->request_successful) { return; } // Retrive the contact's ID $contact_id = $this->getContactIDFromResponse(); // Add Lists to Contact $this->addListsToContact($contact_id, $lists); // Add Tags to Contact if (!empty($tags)) { $tags = is_array($tags) ? $tags : explode(',', $tags); $tag_ids = $this->convertTagNamesToIDs($tags); if ($tag_ids && !empty($tag_ids)) { $this->addTagsToContact($tag_ids, $contact_id); } } // Add Custom Fields to Contact $this->addCustomFieldsToContact($customfields, $contact_id); } /** * Update Custom Field Values for a Contact * * API Reference: https://developers.activecampaign.com/v3/reference#fieldvalues * * @param array $custom_fields Array of custom field values * @param integer $contact_id The contact's ID * * @return mixed Null on failure, void on success */ private function addCustomFieldsToContact($custom_fields, $contact_id) { if (empty($custom_fields)) { return; } $custom_fields = array_change_key_case($custom_fields); if (!$all_custom_fields = $this->getAllCustomFields()) { return; } foreach ($custom_fields as $custom_field_key => $custom_field_value) { if (empty($custom_field_value)) { continue; } $custom_field = strtolower(trim($custom_field_key)); if (!array_key_exists($custom_field, $all_custom_fields)) { continue; } // Let's add Custom Field to our contact $custom_field_data = $all_custom_fields[$custom_field]; // Radio buttons expect a string. Not an array. if ($custom_field_data['type'] == 'checkbox' && is_array($custom_field_value)) { $custom_field_value = implode('||', $custom_field_value); $custom_field_value = '||' . $custom_field_value . '||'; } $this->post('fieldValues', [ 'fieldValue' => [ 'contact' => $contact_id, 'field' => $custom_field_data['id'], 'value' => $custom_field_value ] ]); } } /** * Add tags to contact * * API Reference: https://developers.activecampaign.com/v3/reference#create-contact-tag * * @param array $tag_ids Array of tag IDs * @param integer $contact_id The contact's ID * * @return void */ private function addTagsToContact($tag_ids, $contact_id) { foreach ($tag_ids as $tag_id) { $this->post('contactTags', [ 'contactTag' => [ 'contact' => $contact_id, 'tag' => $tag_id, ] ]); } } /** * Convert a list of tag names to tag IDs * * @param array $tags Array ot tag names * * @return mixed Null on failure, assosiative tag name-based array on success. */ private function convertTagNamesToIDs($tags) { if (!$account_tags = $this->getAllTags()) { return; } $account_tags = array_map('strtolower', $account_tags); $tag_ids = []; foreach ($tags as $tag) { if (empty($tag)) { continue; } $tag = strtolower(trim($tag)); if (!$tag_id = array_search($tag, $account_tags)) { continue; } $tag_ids[] = $tag_id; } return $tag_ids; } /** * Retrieve all contact-based tags * * API Reference: https://developers.activecampaign.com/v3/reference#list-all-tasks * * @return mixed Null on failure, assosiative array on success */ private function getAllTags() { $tags = $this->get('tags'); if (!$tags || !is_array($tags) || !isset($tags['tags'])) { return; } $tags_ = []; foreach ($tags['tags'] as $tag) { if ($tag['tagType'] != 'contact') { continue; } $tags_[$tag['id']] = $tag['tag']; } return $tags_; } /** * Add lists to contact * * @param integer $contact_id The Active Campaign Contact ID * @param mixed $lists The list ID to add the contact to. * * @return void */ private function addListsToContact($contact_id, $lists) { $lists = is_array($lists) ? $lists : explode(',', $lists); foreach ($lists as $list) { $this->post('contactLists', [ 'contactList' => [ 'list' => $list, 'contact' => $contact_id, 'status' => 1 ] ]); } } /** * Determine the newly created contact's ID * * @return string */ private function getContactIDFromResponse() { $response = $this->last_response; if (isset($response->body) && isset($response->body['contact']) && isset($response->body['contact']['id'])) { return $response->body['contact']['id']; } } /** * Search for First Name and Last Name in Custom Fields and return an array with both values. * * @param array $customfields The Custom Fields array passed by the user. * * @return array */ private function getNameFromCustomFields($customfields) { return [ (string) $this->getCustomFieldValue(['first_name', 'First Name'], $customfields), (string) $this->getCustomFieldValue(['last_name', 'Last Name'], $customfields) ]; } /** * Retrieve all account lists * * API Reference: https://developers.activecampaign.com/v3/reference#retrieve-all-lists * * @return mixed Null on failure, Array on success */ public function getLists() { $data = $this->get('lists'); if (!$data || !isset($data['lists']) || count($data['lists']) == 0) { return; } $lists = []; foreach ($data['lists'] as $list) { $lists[] = [ 'id' => $list['id'], 'name' => $list['name'] ]; } return $lists; } /** * Get the last error returned by either the network transport, or by the API. * * API Reference: https://developers.activecampaign.com/v3/reference#errors * * @return string */ public function getLastError() { $error_code = $this->last_response->code; $error_message = 'Active Campaign Error'; switch ((int) $error_code) { case 403: $error_message = 'The request could not be authenticated or the authenticated user is not authorized to access the requested resource.'; break; case 404: $error_message = 'The requested resource does not exist.'; break; case 422: $error_message = 'The request could not be processed, usually due to a missing or invalid parameter.'; if (isset($this->last_response->body['errors']) && isset($this->last_response->body['errors'][0])) { $error_message = $this->last_response->body['errors'][0]['title']; } break; } return $error_message; } /** * Returns the Active Campaign Account's Custom Fields * * API Reference: https://developers.activecampaign.com/v3/reference#retrieve-fields-1 * * @return array */ public function getAllCustomFields() { $fields = $this->get('fields'); if (!$fields || !isset($fields['fields'])) { return; } // Make our life easier by creating a title-based assosiative array $f = []; foreach ($fields['fields'] as $key => $field) { if (!$field || !isset($field['title'])) { continue; } $key = strtolower(trim($field['title'])); $f[$key] = $field; } return $f; } /** * Make an HTTP GET request for retrieving data. * * ActiveCampaign has a limit of max 100 results per page. * https://developers.activecampaign.com/reference#pagination * * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * * @return array|false Assoc array of API response, decoded from JSON */ public function get($method, $args = array()) { $args['limit'] = isset($args['limit']) ? $args['limit'] : 100; $args['offset'] = isset($args['offset']) ? $args['offset'] : 0; $response = parent::get($method, $args); if ($args['offset'] < (int) $response['meta']['total']) { $args['offset'] += $args['limit']; $response_next = $this->get($method, $args); $response[$method] = array_merge($response[$method], $response_next[$method]); } return $response; } }PK!"!!9system/nrframework/NRFramework/Integrations/MailChimp.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class MailChimp extends Integration { /** * MailChimp Endpoint URL * * @var string */ protected $endpoint = 'https://.api.mailchimp.com/3.0'; /** * Create a new instance * * @param array $options The service's required options * @throws \Exception */ public function __construct($options) { parent::__construct(); $this->setKey($options); if (strpos($this->key, '-') === false) { return; } list(, $data_center) = explode('-', $this->key); $this->endpoint = str_replace('', $data_center, $this->endpoint); $this->options->set('headers.Authorization', 'apikey ' . $this->key); } /** * Subscribe user to MailChimp * * API References: * https://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/#edit-put_lists_list_id_members_subscriber_hash * https://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/#create-post_lists_list_id_members * * @param string $email User's email address * @param string $list The MailChimp list unique ID * @param Object $merge_fields Merge Fields * @param boolean $update_existing Update existing user * @param boolean $double_optin Send MailChimp confirmation email? * * @return void */ public function subscribe($email, $list, $merge_fields = array(), $update_existing = true, $double_optin = false) { $data = array( 'email_address' => $email, 'status' => $double_optin ? 'pending' : 'subscribed' ); // add support for tags if ($tags = $this->getTags($merge_fields)) { $data['tags'] = $tags; } if (is_array($merge_fields) && count($merge_fields)) { foreach ($merge_fields as $merge_field_key => $merge_field_value) { $value = is_array($merge_field_value) ? implode(',', $merge_field_value) : (string) $merge_field_value; $data['merge_fields'][$merge_field_key] = $value; } } $interests = $this->validateInterestCategories($list, $merge_fields); if (!empty($interests)) { $data = array_merge($data, array('interests' => $interests)); } if ($update_existing) { // Get subscriber information. $subscriberHash = md5(strtolower($email)); $subscriberInfo = $this->get('lists/' . $list . '/members/' . $subscriberHash); // Skip double opt-in if the subscriber exists and it's confirmed if (isset($subscriberInfo['status']) && $subscriberInfo['status'] == 'subscribed') { $data['status'] = $subscriberInfo['status']; } $this->put('lists/' . $list . '/members/' . $subscriberHash, $data); if ($tags) { $tags_ = []; foreach ($tags as $tag) { $tags_[] = [ 'name' => $tag, 'status' => 'active' ]; } $currentTags = $this->getMemberTags($list, $subscriberHash); if ($removeTags = array_diff($currentTags, $tags)) { foreach ($removeTags as $removeTag) { $tags_[] = [ 'name' => $removeTag, 'status' => 'inactive' ]; } } $this->post('lists/' . $list . '/members/' . $subscriberHash . '/tags', ['tags' => $tags_]); } } else { $this->post('lists/' . $list . '/members', $data); } return true; } private function getMemberTags($list, $subscriberHash) { $tags = $this->get('lists/' . $list . '/members/' . $subscriberHash . '/tags'); $return = []; if (isset($tags['tags'])) { foreach ($tags['tags'] as $tag) { $return[] = $tag['name']; } } return $return; } /** * Find and return all unique tags * * @param array $merge_fields * * @return array */ private function getTags($merge_fields) { $tags = []; // ensure tags are added in the form if (!isset($merge_fields['tags'])) { return $tags; } $mergeFieldsTags = $merge_fields['tags']; // make string array if (is_string($mergeFieldsTags)) { $tags = explode(',', $mergeFieldsTags); } // ensure we have array to manipulate if (is_array($mergeFieldsTags) || is_object($mergeFieldsTags)) { $tags = (array) $mergeFieldsTags; } // remove empty values, keep uniques and reset keys $tags = array_filter($tags); $tags = array_unique($tags); $tags = array_values($tags); $tags = array_map('trim', $tags); return $tags; } /** * Returns all available MailChimp lists * * https://developer.mailchimp.com/documentation/mailchimp/reference/lists/#read-get_lists * * @return array */ public function getLists() { $data = $this->get('/lists'); if (!$this->success()) { return; } if (!isset($data['lists']) || !is_array($data['lists'])) { return; } $lists = []; foreach ($data['lists'] as $key => $list) { $lists[] = array( 'id' => $list['id'], 'name' => $list['name'] ); } return $lists; } /** * Gets the Interest Categories from MailChimp * * @param string $listID The List ID * * @return array */ public function getInterestCategories($listID) { if (!$listID) { return; } $data = $this->get('/lists/' . $listID . '/interest-categories'); if (!$this->success()) { return; } if (isset($data['total_items']) && $data['total_items'] == 0) { return; } return $data['categories']; } /** * Gets the values accepted for the particular Interest Category * * @param string $listID The List ID * @param string $interestCategoryID The Interest Category ID * * @return array */ public function getInterestCategoryValues($listID, $interestCategoryID) { if (!$interestCategoryID || !$listID) { return array(); } $data = $this->get('/lists/' . $listID . '/interest-categories/' . $interestCategoryID . '/interests'); if (isset($data['total_items']) && $data['total_items'] == 0) { return array(); } return $data['interests']; } /** * Filters the interests categories through the form fields * and constructs the interests array for the subscribe method * * @param string $listID The List ID * @param array $params The Form fields * * @return array */ public function validateInterestCategories($listID, $params) { if (!$params || !$listID) { return array(); } $interestCategories = $this->getInterestCategories($listID); if (!$interestCategories) { return array(); } $categories = array(); foreach ($interestCategories as $category) { if (array_key_exists($category['title'], $params)) { $categories[] = array('id' => $category['id'], 'title' => $category['title']); } } if (empty($categories)) { return array(); } $interests = array(); foreach ($categories as $category) { $data = $this->getInterestCategoryValues($listID, $category['id']); if (isset($data['total_items']) && $data['total_items'] == 0) { continue; } foreach ($data as $interest) { if (in_array($interest['name'], (array) $params[$category['title']])) { $interests[$interest['id']] = true; } else { $interests[$interest['id']] = false; } } } return $interests; } /** * Get the last error returned by either the network transport, or by the API. * * @return string */ public function getLastError() { $body = $this->last_response->body; if (isset($body['errors'])) { $error = $body['errors'][0]; return $error['field'] . ': ' . $error['message']; } if (isset($body['detail'])) { return $body['detail']; } } /** * The get() method overridden so that it handles * the default item paging of MailChimp which is 10 * * @param string $method URL of the API request method * @param array $args Assoc array of arguments (usually your data) * @return array|false Assoc array of API response, decoded from JSON */ public function get($method, $args = array()) { $data = $this->makeRequest('get', $method, $args); if ($data && isset($data['total_items']) && (int) $data['total_items'] > 10) { $args['count'] = $data['total_items']; return $this->makeRequest('get', $method, $args); } return $data; } }PK!/4system/nrframework/NRFramework/Integrations/Zoho.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class Zoho extends Integration { /** * Create a new instance * * @param array $options The service's required options * @throws \Exception */ public function __construct($options) { parent::__construct(); $this->setKey($options['api']); $this->endpoint = 'https://campaigns.zoho.com/api'; } /** * Subscribe user to ZoHo * * https://www.zoho.com/campaigns/help/api/contact-subscribe.html * * @param string $email User's email address * @param string $list The ZoHo list unique ID * @param Object $customFields Collection of custom fields * * @return void */ public function subscribe($email, $list, $customFields = array()) { $contactinfo = json_encode(array_merge(array("Contact Email" => $email), $customFields)); $data = array( "authtoken" => $this->key, "scope" => "CampaignsAPI", "version" => "1", "resfmt" => "JSON", "listkey" => $list, "contactinfo" => $contactinfo ); $this->get('json/listsubscribe', $data); return true; } /** * Returns all available ZoHo lists * * https://www.zoho.com/campaigns/help/api/get-mailing-lists.html * * @return array */ public function getLists() { if (!$this->key) { return; } $data = array( 'authtoken' => $this->key, 'scope' => 'CampaignsAPI', 'sort' => 'asc', 'resfmt' => 'JSON', 'range' => '1000' //ambiguously large range of total results to overwrite the default range which is 20 ); $data = $this->get("getmailinglists", $data); if (!$this->success()) { return; } $lists = array(); if (!isset($data["list_of_details"]) || !is_array($data["list_of_details"])) { return $lists; } foreach ($data["list_of_details"] as $key => $list) { $lists[] = array( "id" => $list["listkey"], "name" => $list["listname"] ); } return $lists; } /** * Get the last error returned by either the network transport, or by the API. * * @return string */ public function getLastError() { $body = $this->last_response->body; if (isset($body['message'])) { return $body['message']; } return 'An unspecified error occured'; } /** * Check if the response was successful or a failure. If it failed, store the error. * * @return bool If the request was successful */ protected function determineSuccess() { $status = $this->findHTTPStatus(); // check if the status is equal to the arbitrary success codes of ZoHo if (in_array($status, array(0, 200, 6101, 6201))) { return ($this->request_successful = true); } return false; } /** * Find the HTTP status code from the headers or API response body * * @return int HTTP status code */ protected function findHTTPStatus() { $status = $this->last_response->code; $success = ($status >= 200 && $status <= 299) ? true : false; if (!$success) { return 418; } // ZoHo sometimes uses "Code" instead of "code" // also they don't use HTTP status codes // instead they store their own status code inside the response body $data = array_change_key_case($this->last_response->body); if (isset($data['code'])) { return (int) $data['code']; } return 418; } }PK!9% ;system/nrframework/NRFramework/Integrations/SendInBlue3.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2018 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class SendInBlue3 extends Integration { /** * Create a new instance * @param array $options The service's required options * @throws \Exception */ public function __construct($options) { parent::__construct(); $this->setKey($options['api']); $this->setEndpoint('https://api.sendinblue.com/v3'); $this->options->set('headers.api-key', $this->key); } /** * Subscribes a user to a SendinBlue Account * * API Reference v3: * https://developers.sendinblue.com/reference#createcontact * * @param string $email The user's email * @param array $params All the form fields * @param string $listid The List ID * @param boolean $update_existing Whether to update the existing contact (Only in v3) * * @return boolean */ public function subscribe($email, $params, $listid = false, $update_existing = true) { $data = [ 'email' => $email, 'attributes' => (object) $params, 'updateEnabled' => $update_existing ]; if ($listid) { $data['listIds'] = [(int) $listid]; } $this->post('contacts', $data); return true; } /** * Returns all Campaign lists * * API Reference v3: * https://developers.sendinblue.com/reference#getlists-1 * * @return array */ public function getLists() { $data = [ 'page' => 1, 'page_limit' => 50 ]; $lists = []; $data = $this->get('contacts/lists', $data); // sanity check if (!isset($data['lists']) || !is_array($data['lists']) || $data['count'] == 0) { return $lists; } foreach ($data['lists'] as $key => $list) { $lists[] = [ 'id' => $list['id'], 'name' => $list['name'] ]; } return $lists; } /** * Get the last error returned by either the network transport, or by the API. * * API Reference: * https://developers.sendinblue.com/docs/how-it-works#error-codes * * @return string */ public function getLastError() { $body = $this->last_response->body; $message = ''; if (!isset($body['code'])) { return $message; } return $body['message']; } }PK!7system/nrframework/NRFramework/Integrations/ZohoCRM.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class ZohoCRM extends Integration { /** * Response Type * * @var string */ protected $response_type = 'xml'; /** * Data Center API Endpoint * * @var string */ private $datacenter = 'crm.zoho.com'; /** * Create a new instance * * @param array $options The service's required options */ public function __construct($options) { parent::__construct(); $this->setKey($options['authenticationToken']); if (isset($options['datacenter']) && !is_null($options['datacenter']) && !empty($options['datacenter'])) { $this->datacenter = $options['datacenter']; } } /** * Subscribe user to ZohoCRM * * https://www.zoho.eu/crm/help/api/insertrecords.html#Insert_records_into_Zoho_CRM_from_third-party_applications * * @param string $email User's email address * @param array $fields Available form fields * @param string $module Zoho module to be used * @param boolean $update_existing Update existing users * @param string $workflow Trigger the workflow rule while inserting record * @param string $approve Approve records (Supports: Leads, Contacts, and Cases modules) * * @return void */ public function subscribe($email, $fields, $module = 'leads', $update_existing = true, $workflow = false, $approve = false) { $data = array( 'authtoken' => $this->key, 'scope' => 'crmapi', 'xmlData' => $this->buildModuleXML($email, $fields, $module), 'duplicateCheck' => $update_existing ? '2' : '1', 'wfTrigger' => $workflow ? 'true' : 'false', 'isApproval' => $approve ? 'true' : 'false', 'version' => '4' ); $this->endpoint = 'https://' . $this->datacenter . '/crm/private/xml/' . ucfirst($module) . '/insertRecords?' . http_build_query($data); $this->post(''); } /** * Build the XML for each module * * @param string $email User's email address * @param array $fields Form fields * @param string $module Module to be used * * @return string The XML */ private function buildModuleXML($email, $fields, $module) { $xml = new SimpleXMLElement('<' . ucfirst($module) . '/>'); $row = $xml->addChild('row'); $row->addAttribute('no', '1'); $xmlField = $row->addChild('FL', $email); $xmlField->addAttribute('val', 'Email'); if (is_array($fields) && count($fields)) { foreach ($fields as $field_key => $field_value) { $field_value = is_array($field_value) ? implode(',', $field_value) : $field_value; $xmlField = $row->addChild('FL', $field_value); $xmlField->addAttribute('val', $field_key); } } return $xml->asXML(); } /** * Get the last error returned by either the network transport, or by the API. * * @return string */ public function getLastError() { $body = $this->last_response->body; if (isset($body->error)) { return $body->error->message; } if (isset($body->result->row->error)) { return $body->result->row->error->details; } return 'Unknown error'; } /** * Check if the response was successful or a failure. If it failed, store the error. * * @return bool If the request was successful */ public function determineSuccess() { $status = $this->last_response->code; $success = ($status >= 200 && $status <= 299) ? true : false; if (!$success) { return false; } $body = $this->last_response->body; if (!isset($body->result->row->success)) { return false; } return ($this->request_successful = true); } }PK!I94system/nrframework/NRFramework/Integrations/Drip.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class Drip extends Integration { /** * Create a new instance * * @param string $key Your Drip API key * @param string $account_id Your Drip Account ID */ public function __construct($options) { parent::__construct(); if (!(isset($options['api']) && isset($options['account_id']))) { return; } $this->setKey($options['api']); $this->setEndpoint('http://api.getdrip.com/v2/' . $options['account_id']); $this->options->set('headers.Authorization', 'Basic ' . base64_encode($this->key)); } /** * Subscribe user to Drip * * API References: * https://developer.drip.com/#create-or-update-a-subscriber * * @param string $email User's email address * @param string $campaign_id The Campaign ID * @param string $name The name of the Contact (Name can be also declared in Custom Fields) * @param Object $custom_fields Custom Fields * @param mixed $tags Tags for this contact (comma-separated). Example: 'tag1, tag2, etc' * @param boolean $update_existing Update existing user * @param boolean $double_optin Send MailChimp confirmation email? * * @return void */ public function subscribe($email, $campaign_id, $name = null, $custom_fields = array(), $tags = '', $update_existing = true, $double_optin = false) { // Detect name $name = (is_null($name) || empty($name)) ? $this->getNameFromCustomFields($custom_fields) : explode(' ', $name, 2); // We use this boolean to see if the user has subscribed the campaign // This is used for the `update_existing` parameter $subscriber_exists = $this->subscriberIsInCampaign($email, $campaign_id); // Check if we need to update the user if ($update_existing == false && $subscriber_exists) { throw new \Exception(\JText::_('PLG_CONVERTFORMS_DRIP_SUBSCRIBER_ALREADY_EXISTS'), 1); } // Remove tags from custom fields $custom_fields_parse = $custom_fields; if (isset($custom_fields_parse['tags'])) { unset($custom_fields_parse['tags']); } // Create or Update a Subscriber $data = [ 'subscribers' => [ [ 'email' => $email, 'first_name' => isset($name[0]) ? $name[0] : '', 'last_name' => isset($name[1]) ? $name[1] : '', 'address1' => $this->getCustomFieldValue('address1', $custom_fields), 'address2' => $this->getCustomFieldValue('address2', $custom_fields), 'city' => $this->getCustomFieldValue('city', $custom_fields), 'state' => $this->getCustomFieldValue('state', $custom_fields), 'zip' => $this->getCustomFieldValue('zip', $custom_fields), 'country' => $this->getCustomFieldValue('country', $custom_fields), 'phone' => $this->getCustomFieldValue('phone', $custom_fields), 'custom_fields' => $custom_fields_parse, 'tags' => $this->getTags($tags) ] ] ]; $this->post('subscribers', $data); // If we are updating a user, dont try re-assigning him to a campaign // If we are updating a user but he just subscribed, then assign him to a campaign if ($update_existing == false || $subscriber_exists == false) { // Assign the newly created subscriber to the campaign $this->assignSubscriberToCampaign($email, $campaign_id, $double_optin); } return true; } /** * Assign a Subscriber to a Campaign * * https://developer.drip.com/?shell#subscribe-someone-to-a-campaign * * @return void */ private function assignSubscriberToCampaign($email, $campaign_id, $double_optin) { // Subscribe user to a campaign $campaignSubAPI = 'campaigns/' . $campaign_id . '/subscribers'; $data = [ 'subscribers' => [ [ 'email' => $email, 'double_optin' => (bool) $double_optin ] ] ]; $this->post($campaignSubAPI, $data); } /** * Returns an array of tags or an empty string if no tags provided * * @return mixed */ private function getTags($tags) { if (empty($tags)) { return; } if (is_string($tags)) { $tags = array_map('trim', explode(',', $tags)); } return $tags; } /** * Returns whether the subscriber is in a campaign * * https://developer.drip.com/?shell#list-all-of-a-subscriber-39-s-campaign-subscriptions * * @return bool */ private function subscriberIsInCampaign($email, $campaign_id) { $found_campaign = false; $subscriber_id = $this->getSubscriberIdFromEmail($email); // Use does not exist in Drip if (empty($subscriber_id)) { return false; } $subscriber_campaigns = $this->getSubscriberCampaigns($subscriber_id); foreach ($subscriber_campaigns as $c) { if ($c['campaign_id'] == $campaign_id) { $found_campaign = true; break; } } return $found_campaign; } /** * Returns the ID of the subscriber from email * * https://developer.drip.com/?shell#fetch-a-subscriber * * @return string */ private function getSubscriberIdFromEmail($email) { $data = $this->get('subscribers/' . $email); return isset($data['subscribers']) ? $data['subscribers'][0]['id'] : ''; } /** * Returns all subscriber's campaigns * * https://developer.drip.com/?javascript#list-all-of-a-subscriber-39-s-campaign-subscriptions * * @return array */ private function getSubscriberCampaigns($subscriberId) { $data = $this->get('subscribers/' . $subscriberId . '/campaign_subscriptions'); return isset($data['campaign_subscriptions']) ? $data['campaign_subscriptions'] : array(); } /** * Returns all available Drip campaigns * * https://developer.drip.com/?shell#list-all-campaigns * * @return array */ public function getLists() { $data = $this->get('campaigns'); if (!$this->success()) { return; } if (!isset($data['campaigns']) || !is_array($data['campaigns'])) { return; } $campaigns = []; foreach ($data['campaigns'] as $key => $campaign) { $campaigns[] = array( 'id' => $campaign['id'], 'name' => $campaign['name'] ); } return $campaigns; } /** * Search for First Name and Last Name in Custom Fields and return an array with both values. * * @param array $custom_fields The Custom Fields array passed by the user. * * @return array */ private function getNameFromCustomFields($custom_fields) { return [ (string) $this->getCustomFieldValue(['first_name', 'First Name'], $custom_fields), (string) $this->getCustomFieldValue(['last_name', 'Last Name'], $custom_fields) ]; } /** * Get the last error returned by either the network transport, or by the API. * * @return string */ public function getLastError() { $body = $this->last_response->body; $messages = ''; if (isset($body['errors'])) { foreach ($body['errors'] as $error) { $messages .= ' - ' . $error['message']; } } return $messages; } }PK!Q4kk;system/nrframework/NRFramework/Integrations/GetResponse.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class GetResponse extends Integration { /** * Create a new instance * * @param array $options The service's required options */ public function __construct($options) { parent::__construct(); $this->setKey($options); $this->endpoint = 'https://api.getresponse.com/v3'; $this->options->set('headers.X-Auth-Token', 'api-key ' . $this->key); $this->options->set('headers.Accept-Encoding', 'gzip,deflate'); } /** * Subscribe user to GetResponse Campaign * * https://apidocs.getresponse.com/v3/resources/contacts#contacts.create * * TODO: Update existing contact * * @param string $email Email of the Contact * @param string $name The name of the Contact * @param object $campaign Campaign ID * @param object $customFields Collection of custom fields * @param object $update_existing Update existing contact * * @return void */ public function subscribe($email, $name, $campaign, $customFields, $update_existing) { $data = array( 'email' => $email, 'name' => $name, 'dayOfCycle' => 0, 'campaign' => ['campaignId' => $campaign], 'customFieldValues' => $this->validateCustomFields($customFields), 'ipAddress' => \NRFramework\User::getIP() ); if (empty($name) || is_null($name)) { unset($data['name']); } if ($update_existing) { $contactId = $this->getContact($email); } if (!empty($contactId)) { return $this->post('contacts/' . $contactId, $data); } $this->post('contacts', $data); } /** * Returns a new array with valid only custom fields * * @param array $customFields Array of custom fields * * @return array Array of valid only custom fields */ public function validateCustomFields($customFields) { $fields = array(); if (!is_array($customFields)) { return $fields; } $accountCustomFields = $this->get('custom-fields'); if (!$this->request_successful) { return $fields; } foreach ($accountCustomFields as $key => $customField) { if (!isset($customFields[$customField['name']])) { continue; } $fields[] = array( 'customFieldId' => $customField['customFieldId'], 'value' => array($customFields[$customField['name']]) ); } return $fields; } /** * Get the last error returned by either the network transport, or by the API. * If something didn't work, this should contain the string describing the problem. * * @return string describing the error */ public function getLastError() { $body = $this->last_response->body; if (!isset($body['context']) || !isset($body['context'][0])) { return $body['codeDescription'] . ' - ' . $body['message']; } $error = $body['context'][0]; if (is_array($error) && isset($error['fieldName'])) { $errorFieldName = is_array($error['fieldName']) ? implode(' ', $error['fieldName']) : $error['fieldName']; return $errorFieldName . ': ' . $error['errorDescription']; } return (is_array($error)) ? implode(' ', $error) : $error; } /** * Returns all available GetResponse campaigns * * https://apidocs.getresponse.com/v3/resources/campaigns#campaigns.get.all * * @return array */ public function getLists() { $data = $this->get('campaigns'); if (!$this->success()) { return; } if (!is_array($data) || !count($data)) { return; } $lists = array(); foreach ($data as $key => $list) { $lists[] = array( 'id' => $list['campaignId'], 'name' => $list['name'] ); } return $lists; } /** * Get the Contact resource * * @param string $email The email of the contact which we want to retrieve * * @return string The Contact ID */ public function getContact($email) { if (!isset($email)) { return; } $data = $this->get('contacts', array('query[email]' => $email)); if (empty($data)) { return; } // the returned data is an array with only one contact $contactId = $data[0]['contactId']; return ($contactId) ? $contactId : null; } }PK!$ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class ElasticEmail extends Integration { protected $endpoint = 'https://api.elasticemail.com/v2'; /** * Create a new instance * * @param array $options The service's required options * @throws \Exception */ public function __construct($options) { parent::__construct(); $this->setKey($options); } /** * Subscribe user to ElasticEmail * * API References: * http://api.elasticemail.com/public/help#Contact_Add * http://api.elasticemail.com/public/help#Contact_Update * * @param string $email User's email address * @param string $list The ElasticEmail List unique ID * @param string $publicAccountID The ElasticEmail PublicAccountID * @param array $params The form's parameters * @param boolean $update_existing Update existing user * @param boolean $double_optin Send ElasticEmail confirmation email? * * @return void */ public function subscribe($email, $list, $publicAccountID, $params = array(), $update_existing = true, $double_optin = false) { $data = array( 'apikey' => $this->key, 'email' => $email, 'publicAccountID' => $publicAccountID, 'publicListID' => $list, 'sendActivation' => $double_optin ? 'true' : 'false', 'consentIP' => \NRFramework\User::getIP() ); if (is_array($params) && count($params)) { foreach ($params as $param_key => $param_value) { $data[$param_key] = (is_array($param_value)) ? implode(',', $param_value) : $param_value; } } if (!$update_existing) { return $this->get('/contact/add', $data); } if ($this->getContact($email)) { $data['clearRestOfFields'] = 'false'; $this->get('/contact/update', $data); } else { $this->get('/contact/add', $data); } return true; } /** * Returns all available ElasticEmail lists * * http://api.elasticemail.com/public/help#List_list * * @return array */ public function getLists() { $data = $this->get('/list/list', array('apikey' => $this->key)); if (!$this->success()) { return; } $lists = array(); if (!isset($data['data']) || !is_array($data['data'])) { return $lists; } foreach ($data['data'] as $key => $list) { $lists[] = array( 'id' => $list['publiclistid'], 'name' => $list['listname'] ); } return $lists; } /** * Check to see if a contact exists * * @param string $email The contact's email * * @return boolean */ public function getContact($email) { $contact = $this->get('/contact/loadcontact', array('apikey' => $this->key, 'email' => $email)); return (bool) $contact['success']; } /** * Get the Elastic Email Public Account ID * * @return string */ public function getPublicAccountID() { $data = $this->get('/account/load', array('apikey' => $this->key)); if (isset($data['data']['publicaccountid'])) { return $data['data']['publicaccountid']; } throw new \Exception(\JText::_('PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID'), 1); } /** * Get the last error returned by either the network transport, or by the API. * * @return string */ public function getLastError() { $body = $this->last_response->body; if (isset($body['error'])) { return $body['error']; } } /** * Check if the response was successful or a failure. If it failed, store the error. * * @return bool If the request was successful */ protected function determineSuccess() { $code = $this->last_response->code; $body = $this->last_response->body; if ($code >= 200 && $code <= 299 && !isset($body['error'])) { return ($this->request_successful = true); } $this->last_error = 'Unknown error, call getLastResponse() to find out what happened.'; return false; } }PK!C 7system/nrframework/NRFramework/Integrations/HubSpot.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class HubSpot extends Integration { /** * Create a new instance * * @param string $key Your HubSpot API key */ public function __construct($options) { parent::__construct(); $this->setKey(is_array($options) ? $options['api'] : $options); $this->setEndpoint('https://api.hubapi.com'); } /** * Subscribe user to HubSpot * * API References: * http://developers.hubspot.com/docs/methods/contacts/update_contact-by-email * * @param string $email User's email address * @param string $params The forms extra fields * * @return void */ public function subscribe($email, $params) { $fields = $this->validateCustomFields($params); $fields[] = array('property' => 'email', 'value' => $email); $data = array( 'properties' => $fields ); $this->post('contacts/v1/contact/createOrUpdate/email/' . $email . '/?hapikey=' . $this->key, $data); return true; } /** * Get the last error returned by either the network transport, or by the API. * * API References: * http://developers.hubspot.com/docs/faq/api-error-responses * * @return string */ public function getLastError() { $body = $this->last_response->body; $message = ''; if ((isset($body['status'])) && ($body['status'] == 'error')) { $message = $body['message']; } if (isset($body['validationResults']) && is_array($body['validationResults']) && count($body['validationResults'])) { foreach ($body['validationResults'] as $key => $validation) { if ($validation['isValid'] === false) { $message .= ' - ' . $validation['message']; } } } return $message; } /** * Returns a new array with valid only custom fields * * API References: * http://developers.hubspot.com/docs/methods/contacts/v2/get_contacts_properties * * @param array $formCustomFields Array of custom fields * * @return array Array of valid only custom fields */ public function validateCustomFields($formCustomFields) { $fields = array(); if (!is_array($formCustomFields)) { return $fields; } $accountFields = $this->get('properties/v1/contacts/properties?hapikey='.$this->key); if (!$this->request_successful) { return $fields; } $accountFieldsNames = array_map( function ($ar) { return $ar['name']; }, $accountFields ); $formCustomFieldsKeys = array_keys($formCustomFields); foreach ($accountFieldsNames as $accountFieldsName) { if (!in_array($accountFieldsName, $formCustomFieldsKeys)) { continue; } $fields[] = array( "property" => $accountFieldsName, "value" => $formCustomFields[$accountFieldsName], ); } return $fields; } }PK!:system/nrframework/NRFramework/Integrations/SendInBlue.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class SendInBlue extends Integration { /** * Create a new instance * @param array $options The service's required options * @throws \Exception */ public function __construct($options) { parent::__construct(); $this->setKey($options['api']); $this->setEndpoint('https://api.sendinblue.com/v2.0'); $this->options->set('headers.api-key', $this->key); } /** * Subscribes a user to a SendinBlue Account * * API Reference: * https://apidocs.sendinblue.com/user/#1 * * @param string $email The user's email * @param array $params All the form fields * @param string $listid The List ID * * @return boolean */ public function subscribe($email, $params, $listid = false) { $data = array( 'email' => $email, 'attributes' => $params, ); if ($listid) { $data['listid'] = array($listid); } $this->post('user/createdituser', $data); return true; } /** * Returns all Campaign lists * * https://apidocs.sendinblue.com/list/#1 * * @return array */ public function getLists() { $data = array( 'page' => 1, 'page_limit' => 50 ); $lists = array(); $data = $this->get('/list', $data); if (!isset($data['data']['lists']) || !is_array($data['data']['lists']) || $data['data']['total_list_records'] == 0) { return $lists; } foreach ($data['data']['lists'] as $key => $list) { $lists[] = array( 'id' => $list['id'], 'name' => $list['name'] ); } return $lists; } /** * Get the last error returned by either the network transport, or by the API. * * API Reference: * https://apidocs.sendinblue.com/response/ * * @return string */ public function getLastError() { $body = $this->last_response->body; $message = ''; if (isset($body['code']) && ($body['code'] == 'failure')) { $message = $body['message']; } return $message; } }PK!!X8system/nrframework/NRFramework/Integrations/IContact.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Integrations; // No direct access defined('_JEXEC') or die; class IContact extends Integration { public $accountID; public $clientFolderID; /** * Create a new instance * @param array $options The service's required options */ public function __construct($options) { parent::__construct(); $this->endpoint = 'https://app.icontact.com/icp/a'; $this->options->set('headers.API-Version', '2.2'); $this->options->set('headers.API-AppId', $options['appID']); $this->options->set('headers.API-Username', $options['username']); $this->options->set('headers.API-Password', $options['appPassword']); $this->setAccountID($options['accountID']); $this->setClientFolderID($options['clientFolderID']); } /** * Finds and sets the iContact AccountID * * @param mixed $accountID */ public function setAccountID($accountID = false) { if ($accountID) { $this->accountID = $accountID; } $accounts = $this->get(''); if (!$this->success()) { throw new \Exception($this->getLastError()); } // Make sure the account is active if (intval($accounts['accounts'][0]['enabled']) === 1) { $this->accountID = (integer) $accounts['accounts'][0]['accountId']; } else { throw new \Exception(\JText::_('NR_ICONTACT_ACCOUNTID_ERROR'), 1); } } /** * Finds and sets the iContact ClientFolderID * * @param mixed $clientFolderID */ public function setClientFolderID($clientFolderID = false) { if ($clientFolderID) { $this->clientFolderID = $clientFolderID; } // We need an existant accountID if (empty($this->accountID)) { try { $this->setAccountID(); } catch (Exception $e) { throw $e; } } if ($clientFolder = $this->get($this->accountID . '/c/')) { $this->clientFolderID = $clientFolder['clientfolders'][0]['clientFolderId']; } } /** * Subscribes a user to an iContact List * * API REFERENCE * https://www.icontact.com/developerportal/documentation/contacts * * @param string $email * @param object $params The extra form fields * @param mixed $list The iContact List ID * * @return boolean */ public function subscribe($email, $params, $list) { $data = array('contact' => array_merge(array('email' => $email, 'status' => 'normal'), (array) $params)); try { $contact = $this->post($this->accountID .'/c/' . $this->clientFolderID . '/contacts', $data); } catch (Exception $e) { throw $e; } if ((isset($contact['contacts'])) && (is_array($contact['contacts'])) && (count($contact['contacts']) > 0)) { $this->addToList($list, $contact['contacts'][0]['contactId']); } return true; } /** * Adds a contact to an iContact List * * API REFERENCE * https://www.icontact.com/developerportal/documentation/subscriptions * * @param string $listID * @param string $contactID */ public function addToList($listID, $contactID) { $data = array( array( 'contactId' => $contactID, 'listId' => $listID, 'status' => 'normal' ) ); $this->post($this->accountID .'/c/' . $this->clientFolderID . '/subscriptions',$data); } /** * Returns all Client lists * * API REFERENCE * https://www.icontact.com/developerportal/documentation/lists * * @return array */ public function getLists() { $data = $this->get($this->accountID .'/c/' . $this->clientFolderID . '/lists'); if (!$this->success()) { return; } $lists = array(); if (!isset($data["lists"]) || !is_array($data["lists"])) { return $lists; } foreach ($data["lists"] as $key => $list) { $lists[] = array( 'id' => $list['listId'], 'name' => $list['name'] ); } return $lists; } /** * Get the last error returned by either the network transport, or by the API. * If something didn't work, this should contain the string describing the problem. * * @return string describing the error */ public function getLastError() { $body = $this->last_response->body; $message = ''; if (isset($body['errors'])) { foreach ($body['errors'] as $error) { $message .= $error . ' '; } } return trim($message); } }PK!E1"(system/nrframework/NRFramework/Email.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined('_JEXEC') or die('Restricted access'); /** * Novarain Framework Emailer */ class Email { /** * Indicates the last error * * @var string */ public $error; /** * Email Object * * @var email data to be sent */ private $email; /** * Required elements for a valid email object * * @var array */ private $requiredKeys = array( 'from_email', 'from_name', 'recipient', 'subject', 'body' ); /** * Class constructor */ public function __construct($email) { $this->email = $email; } /** * Validates Email Object * * @param array $email The email object * * @return boolean Returns true if the email object is valid */ public function validate() { // Validate email object if (!$this->email || !is_array($this->email) || !count($this->email)) { $this->setError('Invalid email object.'); return; } // Check for missing properties foreach ($this->requiredKeys as $key) { if (!isset($this->email[$key]) || empty($this->email[$key])) { $this->setError("The $key field is either missing or invalid."); return; } } // Validate recipient email addresses. Pass multiple recipients separated by comma. $recipients = explode(',', $this->email['recipient']); // Remove spaces and duplicate email addresses to prevent issues with PHPMailer addRecipient() method. $recipients = array_unique(array_filter(array_map('trim', $recipients))); foreach ($recipients as $recipient) { if (!$this->validateEmailAddress($recipient)) { $this->setError("Invalid recipient email address: $recipient"); return; } } $this->email['recipient'] = $recipients; // Validate sender email address if (!$this->validateEmailAddress($this->email['from_email'])) { $this->setError('Invalid sender email address: ' . $this->email['from_email']); return; } // Convert special HTML entities back to characters on non text-only properties. // For instance, the subject line of an email is not parsed as HTML, it's just pure text. // Because of this an HTML entity like & it will be displayed as encoded. // To prevent this from happening we need decode the values. $this->email['subject'] = htmlspecialchars_decode($this->email['subject']); $this->email['from_name'] = htmlspecialchars_decode($this->email['from_name']); $this->email['reply_to_name'] = htmlspecialchars_decode($this->email['reply_to_name']); return true; } /** * Sending emails * * @param array $email The mail objecta * * @return mixed Returns true on success. Throws exeption on fail. */ public function send() { // Proceed only if Mail Sending is enabled. if (!\JFactory::getConfig()->get('mailonline')) { $this->error = \JText::_('NR_ERROR_EMAIL_IS_DISABLED'); return; } // Validate first the email object if (!$this->validate($this->email)) { return; } $email = $this->email; $mailer = \JFactory::getMailer(); $mailer->CharSet = 'UTF-8'; // Email Sender $mailer->setSender( array( $email['from_email'], $email['from_name'] ) ); // Reply-to if (isset($email['reply_to']) && !empty($email['reply_to'])) { $name = (isset($email['reply_to_name']) && !empty($email['reply_to_name'])) ? $email['reply_to_name'] : ''; $mailer->addReplyTo($email['reply_to'], $name); } // Convert all relative paths found in and elements to absolute URLs $email['body'] = \NRFramework\URLHelper::relativePathsToAbsoluteURLs($email['body']); $mailer ->addRecipient($email['recipient']) ->isHTML(true) ->setSubject($email['subject']) ->setBody($email['body']); $mailer->AltBody = strip_tags(str_ireplace(['
', '
', '
'], "\r\n", $email['body'])); // Attachments if (!empty($email['attachments'])) { if (!is_array($email['attachments'])) { $attachments = explode(',', $email['attachments']); } foreach ($attachments as $attachment) { $file_path = $this->toRelativePath($attachment); $mailer->addAttachment($file_path); } } // Send mail $send = $mailer->Send(); if ($send !== true) { $this->setError($send->__toString()); return; } return true; } /** * Set Class Error * * @param string $error The error message */ private function setError($error) { $this->error = 'Error sending email: ' . $error; Functions::log($error); } /** * Removes all illegal characters and validates an email address * * @param string $email Email address string * * @return bool */ private function validateEmailAddress($email) { // If the email address contains an ampersand, throw an error if (strpos($email, '&') !== false) { return false; } $email = filter_var($email, FILTER_SANITIZE_EMAIL); return filter_var($email, FILTER_VALIDATE_EMAIL); } /** * Attempts to transform an absolute URL to path relative to the site's root. * * @param string $url * * @return string */ private function toRelativePath($url) { $needles = [ \JURI::root(), JPATH_SITE, JPATH_ROOT ]; $path = str_replace($needles, '', $url); $path = \JPath::clean($path); return $path; } }PK!i-5-5'system/nrframework/NRFramework/HTML.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; // No direct access defined('_JEXEC') or die; use NRFramework\Cache; use NRFramework\Functions; use NRFramework\Extension; use Joomla\CMS\Language\Text; class HTML { /** * Display field help text as tooltip in Joomla 4 * * @return void */ public static function fixFieldTooltips() { // Run once static $run; if ($run) { return; } $run = true; \JHtml::_('bootstrap.popover'); $doc = \JFactory::getDocument(); $doc->addStyleDeclaration(' .form-text, .form-control-feedback { display:none; } .tooltip .arrow:before { border-top-color:#444; border-bottom-color:#444; } .tooltip-inner { text-align: left; background-color: #444; padding: 7px 9px; max-width:300px; } '); $doc->addScriptDeclaration(' document.addEventListener("DOMContentLoaded", function() { initPopover(); document.addEventListener("joomla:updated", initPopover); function initPopover(event) { var target = event && event.target ? event.target : document; var fields = target.querySelectorAll(".control-group"); fields.forEach(function(field) { var desc = field.querySelector(".form-text"); if (desc) { var label = field.querySelector("label"); if (label) { label.classList.add("tTooltip"); label.setAttribute("title", desc.innerHTML); } } }); jQuery(target).find(".tTooltip").tooltip({ placement: "top", html: true, delay: { show: 200 } }); } }); '); } public static function updateNotification($extension) { $version_installed = Extension::getVersion($extension); $version_latest = Extension::getLatestVersion($extension); if (!$needsUpdate = version_compare($version_latest, $version_installed, 'gt')) { return; } // Load extension's language file Functions::loadLanguage($extension); // Extension Title $title = Text::_($extension); $title = str_replace('System -', '', $title); // Remove plugin folder prefix from plugins // Render Layout $data = [ 'title' => $title, 'version_installed' => $version_installed, 'version_latest' => $version_latest, 'ispro' => Extension::isPro($extension), 'upgradeurl' => Extension::getTassosExtensionUpgradeURL($extension), 'product_url' => Extension::getProductURL($extension) ]; return \JLayoutHelper::render('updatechecker', $data, JPATH_PLUGINS . '/system/nrframework/layouts'); } /** * Displays a warning when an extension is outdated. * * @param string $extension * @param int $days_old * * @return mixed */ public static function checkForOutdatedExtension($extension, $days_old = 120) { if (!Extension::isOutdated($extension, $days_old)) { return; } // Load extension's language file Functions::loadLanguage($extension); $payload = [ 'extension' => \JText::_($extension), 'days_old' => $days_old ]; // load template return \JLayoutHelper::render('outdated_extension', $payload, dirname(__DIR__) . '/layouts'); } /** * Checks if the given extension has a newer version available through an AJAX request. * * @param string $element * * @return string */ public static function checkForUpdates($element) { \JHtml::script('plg_system_nrframework/updatechecker.js', ['relative' => true, 'version' => true]); \JHtml::stylesheet('plg_system_nrframework/updatechecker.css', ['relative' => true, 'version' => true]); return '
'; } /** * Renders the HTML layout * * @param string $layout The HTML class of the layout. * @param array $options A list of attributes passed to the layout * * @return string */ public static function render($layout, $options = []) { if (!$layout) { return; } $class = '\NRFramework\HTML\\' . $layout; // ensure class exists if (!class_exists($class)) { return; } return (new $class($options))->render(); } /** * Renders Pro Button * * @param string $feature_label The text that will be used as the modal popup feature * * @return void */ public static function renderProButton($feature_label = null) { include_once JPATH_PLUGINS . '/system/nrframework/fields/pro.php'; $field = new \JFormFieldNR_PRO; $element = new \SimpleXMLElement(' '); $field->setup($element, null); echo $field->__get('input'); } /** * Renders a modal that will be shown on Pro only features * * @return void */ public static function renderProOnlyModal() { $hash = 'proOnlyModal'; // Render modal once if (Cache::get($hash)) { return; } $options = [ 'extension_name' => Extension::getExtensionNameByRequest(true), 'upgrade_url' => Extension::getTassosExtensionUpgradeURL() ]; $html = \JLayoutHelper::render('proonlymodal', $options, dirname(__DIR__) . '/layouts'); echo \JHtml::_('bootstrap.renderModal', 'proOnlyModal', ['backdrop' => 'static'], $html); Cache::set($hash, true); } public static function smartTagsBox($options = array()) { \JHtml::_('jquery.framework'); include_once JPATH_PLUGINS . '/system/nrframework/fields/smarttagsbox.php'; $field = new \JFormFieldSmartTagsBox; $element = new \SimpleXMLElement(''); $field->setup($element, null); return $field->__get('input'); } /** * Construct the HTML for the input field in a tree * Logic from administrator\components\com_modules\views\module\tmpl\edit_assignment.php */ public static function treeselect(&$options, $name, $value, $id, $size = 300, $simple = 0, $class = '') { Functions::loadLanguage('com_menus', JPATH_ADMINISTRATOR); Functions::loadLanguage('com_modules', JPATH_ADMINISTRATOR); if (empty($options)) { return '
' . \JText::_('NR_NO_ITEMS_FOUND') . '
'; } if (!is_array($value)) { $value = explode(',', $value); } $count = 0; if ($options != -1) { foreach ($options as $option) { $count++; if (isset($option->links)) { $count += count($option->links); } } } if ($options == -1) { if (is_array($value)) { $value = implode(',', $value); } if (!$value) { $input = ''; } else { $input = ''; } return '
' . $input . '
'; } if ($simple) { $attr = 'style="width: ' . $size . 'px" multiple="multiple"'; if (!empty($class)) { $attr .= ' class="' . $class . '"'; } $html = \JHtml::_('select.genericlist', $options, $name, trim($attr), 'value', 'text', $value, $id); return $html; } \JHtml::script('plg_system_nrframework/treeselect.js', ['relative' => true, 'version' => true]); \JHtml::stylesheet('plg_system_nrframework/treeselect.css', ['relative' => true, 'version' => true]); $html = array(); $html[] = '
'; $html[] = ' '; $o = array(); foreach ($options as $option) { $option->level = isset($option->level) ? $option->level : 0; $o[] = $option; if (isset($option->links)) { foreach ($option->links as $link) { $link->level = $option->level + (isset($link->level) ? $link->level : 1); $o[] = $link; } } } $html[] = '
    '; $prevlevel = 0; foreach ($o as $i => $option) { if ($prevlevel < $option->level) { // correct wrong level indentations $option->level = $prevlevel + 1; $html[] = '
      '; } else if ($prevlevel > $option->level) { $html[] = str_repeat('
    ', $prevlevel - $option->level); } else if ($i) { $html[] = ''; } $labelclass = trim('pull-left ' . (isset($option->labelclass) ? $option->labelclass : '')); $html[] = '
  • '; $item = '
    '; if (isset($option->title)) { $labelclass .= ' nav-header'; } if (isset($option->title) && (!isset($option->value) || !$option->value)) { $item .= ''; } else { $selected = in_array($option->value, $value) ? ' checked="checked"' : ''; $disabled = (isset($option->disable) && $option->disable) ? ' readonly="readonly" style="visibility:hidden"' : ''; $item .= ' '; } $item .= '
    '; $html[] = $item; if (!isset($o[$i + 1]) && $option->level > 0) { $html[] = str_repeat('
', (int) $option->level); } $prevlevel = $option->level; } $html[] = ''; $html[] = ' '; $html[] = '
'; $html = implode('', $html); return $html; } public static function treeselectSimple(&$options, $name, $value, $id, $size = 300, $class = '') { return self::treeselect($options, $name, $value, $id, $size, 1, $class); } /** * Wrapper for the JHtml::script method to support old method signatures in Joomla < 3.7.0. * * @param string $path * * @deprecated Since we no longer support 3.7.0, use JHtml::script directly. * @return void */ public static function script($path) { if (version_compare(JVERSION, '3.7.0', 'lt')) { \JHtml::script($path, false, true); } else { \JHtml::script($path, ['relative' => true, 'version' => 'auto']); } } /** * Wrapper for the JHtml::stylesheet method to support old method signatures in Joomla < 3.7.0. * * @param string $path * * @return void * @deprecated Since we no longer support 3.7.0, use JHtml::script directly. */ public static function stylesheet($path) { if (version_compare(JVERSION, '3.7.0', 'lt')) { \JHtml::stylesheet($path, false, true); } else { \JHtml::stylesheet($path, ['relative' => true, 'version' => 'auto']); } } }PK!qb_KK.system/nrframework/NRFramework/Helpers/CSS.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2022 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Helpers; defined('_JEXEC') or die; class CSS { /** * Transforms an array of CSS variables (key, value) to * a CSS output. * * @param array $cssVars * @param string $namespace * * @return string */ public static function cssVarsToString($cssVars, $namespace) { $output = ''; foreach (array_filter($cssVars) as $key => $value) { $output .= '--' . $key . ': ' . $value . ';' . "\n"; } return $namespace . ' { ' . $output . ' } '; } }PK!%%Asystem/nrframework/NRFramework/Helpers/Widgets/GalleryManager.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Helpers\Widgets; defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.path'); use NRFramework\File; use NRFramework\Mimes; use NRFramework\Image; class GalleryManager { /** * Upload file * * @param array $file The request file as posted by form * @param string $upload_settings The upload settings * @param array $media_uploader_file_data Media uploader related file settings * @param array $resizeSettings The resize settings * * @return mixed String on success, Null on failure */ public static function upload($file, $upload_settings, $media_uploader_file_data, $resizeSettings) { $ds = DIRECTORY_SEPARATOR; // The source file name $source = ''; // Move the image to the tmp folder try { $source = File::upload($file, null, $upload_settings['allowed_types'], $upload_settings['allow_unsafe']); } catch (\Throwable $th) { return false; } // If the file came from the Media Manager file and we are copying it, fix its filename if ($media_uploader_file_data['is_media_uploader_file'] && isset($media_uploader_file_data['copied_from_media_uploader']) && !$media_uploader_file_data['copied_from_media_uploader']) { $media_uploader_file_data['media_uploader_filename'] = self::getFilePathFromMediaUploaderFile($media_uploader_file_data['media_uploader_filename']); } // The uploaded file name $filename = null; // Whether to copy the base image $copyBaseImage = true; // If we are copying the base image, copy it to the temp folder. if ($copyBaseImage && !$source = File::move($source, $source, true)) { return false; } // Check whether to copy and resize the original image if ($copyBaseImage && $resizeSettings['original_image_resize']) { $source = Image::resizeAndKeepAspectRatio($source, $resizeSettings['original_image_resize_width'], $resizeSettings['original_image_resize_quality']); } // Generate thumbnails if (!$thumb_data = self::generateThumbnail($source, $resizeSettings)) { return false; } return [ 'filename' => is_null($filename) ? $thumb_data['filename'] : $filename, 'thumbnail' => $thumb_data['resized_filename'] ]; } /** * Moves all given `tmp` items over to the destination folder. * * @param array $items * @param string $destination_folder * * @return mixed */ public static function moveTempItemsToDestination(&$items, $destination_folder) { if (!$destination_folder) { return; } // Create destination folder if missing if (!File::createDirs($destination_folder)) { return; } $temp_folder = File::getTempFolder(); // Move all files from `tmp` folder over to the `upload folder` foreach ($items as $key => &$item) { /** * Skip invalid files. * * These "fiels" can appear when we try to move files * over to the destination folder when the gallery manager * is still working to upload queueed files. */ if ($key === 'ITEM_ID') { continue; } $moved = false; // Ensure thumbnail in temp folder file exists if (file_exists($temp_folder . $item['thumbnail'])) { // Move thumbnails $thumb = File::move($temp_folder . $item['thumbnail'], $destination_folder . $item['thumbnail']); $thumb_filename = pathinfo($thumb, PATHINFO_BASENAME); // If the moved file has changed name, use the new file name if ($item['thumbnail'] !== $thumb_filename) { $item['thumbnail'] = $thumb_filename; } $moved = true; } // Check if we have uploaded the full image as well and set it if ((($item['media_upload_source'] === 'false' && $item['copied_from_media_uploader'] === 'false') || ($item['media_upload_source'] === 'true' && $item['copied_from_media_uploader'] === 'true')) && file_exists($temp_folder . $item['image'])) { $image = File::move($temp_folder . $item['image'], $destination_folder . $item['image']); $image_filename = pathinfo($image, PATHINFO_BASENAME); // If the moved file has changed name, use the new file name if ($item['image'] !== $image_filename) { $item['image'] = $image_filename; } $moved = true; } if ($moved) { // Update destination path self::updateDestinationPath($item, $destination_folder); } } } /** * Updates the destination path for the image and its thumbnail to the final destination folder. * * @param array $item * @param string $destination_folder * * @return mixed */ private static function updateDestinationPath(&$item, $destination_folder) { $ds = DIRECTORY_SEPARATOR; // Ensure destination folder is a relative path $destination_folder = ltrim(rtrim(str_replace(JPATH_ROOT, '', $destination_folder), $ds), $ds); $item['thumbnail'] = implode($ds, [$destination_folder, $item['thumbnail']]); $is_media_uploader_file = $item['media_upload_source'] === 'true'; $copied_from_media_uploader = $item['copied_from_media_uploader'] === 'true'; // Update the path of the original image only if copied from the Media Manager or uploaded manually if (!$is_media_uploader_file || ($is_media_uploader_file && $copied_from_media_uploader)) { $item['image'] = implode($ds, [$destination_folder, $item['image']]); } } /** * Media Uploader files look like: https://example.com/images/sampledata/parks/banner_cradle.png * We remove the first part (https://example.com/images/) and keep the other part (relative path to image). * * @param string $filename * * @return string */ private static function getFilePathFromMediaUploaderFile($filename) { $filenameArray = explode('images/', $filename, 2); unset($filenameArray[0]); $new_filepath = join($filenameArray); return 'images/' . $new_filepath; } /** * Generates thumbnail * * @param string $source Source image path. * @param array $resizeSettings Resize Settings. * @param string $destination_folder Destination folder. * @param boolean $unique_filename Whether the thumbnails will have a unique filename. * * @return array */ public static function generateThumbnail($source, $resizeSettings, $destination_folder = null, $unique_filename = true) { $parts = pathinfo($source); $destination_folder = !is_null($destination_folder) ? $destination_folder : $parts['dirname'] . DIRECTORY_SEPARATOR; $destination = $destination_folder . $parts['filename'] . '_thumb.' . $parts['extension']; /** * If height is zero, then we suppose we want to keep aspect ratio. * * Resize with width & height: If thumbnail height is not set * Resize and keep aspect ratio: If thumbnail height is set */ $resized_image = !is_null($resizeSettings['thumb_height']) && $resizeSettings['thumb_height'] !== '0' ? Image::resize($source, $resizeSettings['thumb_width'], $resizeSettings['thumb_height'], $resizeSettings['thumb_resize_quality'], $resizeSettings['thumb_resize_method'], $destination, $unique_filename) : Image::resizeAndKeepAspectRatio($source, $resizeSettings['thumb_width'], $resizeSettings['thumb_resize_quality'], $destination, $unique_filename); if (!$resized_image) { return; } return [ 'filename' => basename($source), 'resized_filename' => basename($resized_image) ]; } /** * Deletes an uploaded file (resized original image and thumbnail). * * @param string $filepath The filepath * @param string $thumbnail The thumbnail filepath * @param array $settings Other settings we need for the deletion * * @return bool */ public static function deleteFile($filepath, $thumbnail, $settings) { if (empty($filepath)) { return false; } $is_media_uploader_file = $settings['is_media_uploader_file']; $copied_from_media_uploader = $settings['copied_from_media_uploader']; $deleted_original_image = false; // Delete the main image if it was added by the Media Uploader and copied over to destination folder or uploaded manually if (!$is_media_uploader_file || ($is_media_uploader_file && $copied_from_media_uploader)) { $deleted_original_image = self::findAndDeleteFile($filepath); } // Check if we have a thumbnail and delete it $deleted_thumbnail = self::findAndDeleteFile($thumbnail); return [ 'deleted_original_image' => $deleted_original_image, 'deleted_thumbnail' => $deleted_thumbnail ]; } /** * Tries to delete the file either from within the upload folder * or within the tmp folder. * * @param string $filepath * * @return mixed */ private static function findAndDeleteFile($filepath) { $ds = DIRECTORY_SEPARATOR; $file = \JPath::clean(implode($ds, [JPATH_ROOT, $filepath])); $deleted_file = false; // Try to delete it from the upload folder if (\JFile::exists($file)) { $deleted_file = \JFile::delete($file); } // Otherwise, try to delete it from the tmp folder else { $file = implode($ds, [File::getTempFolder(), $filepath]); if (\JFile::exists($file)) { $deleted_file = \JFile::delete($file); } } return $deleted_file; } }PK!>o(/(/:system/nrframework/NRFramework/Helpers/Widgets/Gallery.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Helpers\Widgets; defined('_JEXEC') or die; use NRFramework\Mimes; class Gallery { /** * Stores all gallery parsed directories info txt file `*.gallery_info.txt` data in format: * GALLERY DIRECTORY => ARRAY OF `*.gallery_info.txt` file data * * @var array */ static $gallery_directories_info_file = []; /** * Stores all galleries info file names in format: * * GALLERY DIRECTORY => INFO FILE NAME * * @var array */ static $gallery_directories_info_file_names = []; /** * The directory information file holding all gallery item details. * * @var string */ const directory_gallery_info_file = 'gallery_info.txt'; /** * Parses the given gallery items. * * @param mixed $input A string to a directory/path/URL or an array of a URL item containing its information. * @param array $allowed_file_types The allowed file types. * * @return mixed */ public static function parseGalleryItems($input, $allowed_file_types = []) { if (is_string($input)) { $fullpath_input = JPATH_ROOT . DIRECTORY_SEPARATOR . ltrim($input, DIRECTORY_SEPARATOR); // Parse Directory if (is_dir($fullpath_input)) { return self::parseDirectory($fullpath_input, $allowed_file_types); } // Skip invalid URLs if ($url = self::parseURL($input)) { return [$url]; } // Parse Image if ($image_data = self::parseImage($fullpath_input, $allowed_file_types)) { return [$image_data]; } } return [self::parseURL($input)]; } /** * Parse the directory by finding all of its images and their information. * * @param string $dir * @param array $allowed_file_types * * @return mixed */ public static function parseDirectory($dir, $allowed_file_types = []) { if (!is_string($dir) || !is_dir($dir) || empty($allowed_file_types)) { return; } $items = []; // Get images $files = array_diff(scandir($dir), ['.', '..', '.DS_Store']); foreach ($files as $key => $filename) { // Skip directories if (is_dir($dir . DIRECTORY_SEPARATOR . $filename)) { continue; } $image_path = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename; if (!$image_data = self::parseImage($image_path, $allowed_file_types)) { continue; } $items[] = $image_data; } return $items; } /** * Parse the directory image and return its information. * * @param string $image_path * @param string $allowed_file_types * * @return mixed */ public static function parseImage($image_path, $allowed_file_types = null) { if (!is_string($image_path)) { return; } $data = [ 'path' => $image_path, 'url' => self::directoryImageToURL($image_path) ]; if (!is_file($image_path)) { return array_merge($data, [ 'invalid' => true ]); } // Skip not allowed file types if (!is_null($allowed_file_types) && !Mimes::check($allowed_file_types, Mimes::detectFileType($image_path))) { return; } // Check if there is a `*.gallery_info.txt` helper file and get any information about the image $gallery_info_file_data = self::getGalleryInfoFileData(dirname($image_path)); if (!$gallery_info_file_data) { return $data; } $image_filename = pathinfo($image_path, PATHINFO_BASENAME); // If no information from the text field about this image was found, stop if (!isset($gallery_info_file_data[$image_filename])) { return $data; } $image_data = $gallery_info_file_data[$image_filename]; return array_merge($data, [ 'caption' => isset($image_data['caption']) ? $image_data['caption'] : '' ]); } /** * Parses a single URL either as a String or as an Array. * * @param mixed $item * * @return mixed */ public static function parseURL($item) { // URL is a string if (is_string($item)) { if (!filter_var($item, FILTER_VALIDATE_URL)) { return; } return [ 'url' => $item ]; } // URL is an array if (!is_array($item) || !count($item)) { return; } // If a thumbnail URL is given but no URL, use it as the full image URL if (isset($item['thumbnail_url']) && !isset($item['url'])) { $item['url'] = $item['thumbnail_url']; } if (!isset($item['url'])) { return; } if (!filter_var($item['url'], FILTER_VALIDATE_URL)) { return; } return $item; } /** * Loads a module by its ID. * * @param string $id * * @return string */ public static function loadModule($id) { $module = \JModuleHelper::getModuleById($id); $params = ['style' => 'none']; return $module->id > 0 ? \JFactory::getDocument()->loadRenderer('module')->render($module, $params) : ''; } /** * Read the `*.gallery_info.txt` file for the given directory. * * @param string $dir * * @return mixed */ public static function getGalleryInfoFileData($dir) { if (isset(self::$gallery_directories_info_file[$dir]) && !empty(self::$gallery_directories_info_file[$dir])) { return self::$gallery_directories_info_file[$dir]; } if (!$file = self::findGalleryInfoFile($dir)) { return []; } // Read file if (!$handle = fopen($file, 'r')) { return []; } $data = []; $line_defaults = ['', '', '']; // Loop each line while (($line = fgets($handle)) !== false) { list($filename, $caption, $hash) = explode('|', $line) + $line_defaults; // If no filename is given, continue if (!$filename) { continue; } $data[$filename] = [ 'filename' => $filename, 'caption' => trim($caption), 'hash' => trim($hash) ]; } // Close file fclose($handle); self::$gallery_directories_info_file[$dir] = $data; return $data; } /** * Finds the source image and whether it has been edited. * * @param string $source * @param string $destination_folder * * @return mixed */ public static function findSourceImageDetails($source, $destination_folder) { $source_filename = pathinfo($source, PATHINFO_BASENAME); $data = self::getGalleryInfoFileData(dirname($source)); $image_data = isset($data[$source_filename]) ? $data[$source_filename] : false; if (!$image_data) { return false; } if (empty($image_data['hash'])) { return false; } $sourceHash = self::calculateFileHash($source); return [ 'path' => $destination_folder . $image_data['filename'], 'edited' => $image_data['hash'] !== $sourceHash ]; } /** * Updates or Inserts the given image information from the gallery info file. * * @param string $source * @param array $image_data * * @return mixed */ public static function updateImageDataInGalleryInfoFile($source, $image_data) { // Source directory $source_directory = dirname($source); // Check whether the gallery info file exists, if not, create it if (!$file = self::findGalleryInfoFile($source_directory)) { $file = self::createGalleryInfoFile($source_directory); } // Open files $reading = fopen($file, 'r'); $writing = fopen($file . '.tmp', 'w'); $replaced = false; while (!feof($reading)) { // Get each file line $line = fgets($reading); // Remove new line at the end $line = trim(preg_replace('/\s\s+/', ' ', $line)); // Skip empty lines if (empty($line)) { continue; } list($filename, $caption, $hash) = explode('|', $line) + ['', '', '']; // We need to manipulate current file if (strtolower($filename) !== strtolower(basename($image_data['path']))) { fputs($writing, $line . "\n"); continue; } $replaced = true; $line = $filename . '|' . $caption . '|' . self::calculateFileHash($source) . "\n";; // Write changed line fputs($writing, $line); } // Close files fclose($reading); fclose($writing); // If we replaced a line, update the text file if ($replaced) { rename($file . '.tmp', $file); } // No line was replaced, append image details else { unlink($file . '.tmp'); self::appendImageDataToGalleryInfoFile($file, $source, $image_data); } } /** * Removes the image from the gallery info file. * * @param string $source * * @return boolean */ public static function removeImageFromGalleryInfoFile($source) { // Get the gallery info file from destination folder if (!$file = self::findGalleryInfoFile(dirname($source))) { return false; } // Open files $reading = fopen($file, 'r'); $writing = fopen($file . '.tmp', 'w'); $found = false; while (!feof($reading)) { // Get each file line $line = fgets($reading); // Remove new line at the end $line = trim(preg_replace('/\s\s+/', ' ', $line)); // Skip empty lines if (empty($line)) { continue; } list($filename, $caption, $hash) = explode('|', $line) + ['', '', '']; // We need to manipulate current file if ($filename !== pathinfo($source, PATHINFO_BASENAME)) { $found = true; fputs($writing, $line . "\n"); continue; } } // Close files fclose($reading); fclose($writing); if (!$found) { return false; } // Save the changes rename($file . '.tmp', $file); return true; } /** * Appends the image data into the info file. * * @param string $dir * * @return void */ public static function createGalleryInfoFile($dir) { $file = self::getLanguageInfoFileName($dir); file_put_contents($file, ''); return $file; } /** * Appends the image data into the info file. * * @param string $file * @param string $source * @param object $image_data * * @return void */ public static function appendImageDataToGalleryInfoFile($file, $source, $image_data) { $caption = isset($image_data['caption']) ? $image_data['caption'] : ''; $hash = self::calculateFileHash($source); $line = pathinfo($source, PATHINFO_BASENAME) . '|' . $caption . '|' . $hash . "\n"; file_put_contents($file, $line, FILE_APPEND); } /** * Finds the `*.gallery_info.txt` file if it exists in the given directory. * * @param string $dir * * @return mixed */ public static function findGalleryInfoFile($dir) { if (isset(self::$gallery_directories_info_file_names[$dir])) { return self::$gallery_directories_info_file_names[$dir]; } // Method 1: With language prefix $file = self::getLanguageInfoFileName($dir); // Check if the file exists if (file_exists($file)) { self::$gallery_directories_info_file_names[$dir] = $file; return $file; } // Method 2: Without the language prefix $file = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . self::directory_gallery_info_file; // Check if the file exists if (file_exists($file)) { self::$gallery_directories_info_file_names[$dir] = $file; return $file; } return false; } /** * Returns the info file with the language prefix. * * @param string $dir * * @return string */ public static function getLanguageInfoFileName($dir) { return rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . \JFactory::getLanguage()->getTag() . '.' . self::directory_gallery_info_file; } /** * Calculates the file hash of a file. * * Hash = md5(file path + last modified date of file) * * @param string $file_path * * @return string */ public static function calculateFileHash($file_path) { return md5($file_path . filemtime($file_path)); } /** * Transforms an image path to a URL. * * @param string $image_path * * @return string */ public static function directoryImageToURL($image_path) { return rtrim(\JURI::root(), DIRECTORY_SEPARATOR) . mb_substr($image_path, strlen(JPATH_BASE), null);; } }PK! 6system/nrframework/NRFramework/Helpers/CustomField.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2022 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework\Helpers; defined('_JEXEC') or die; class CustomField { /** * Get a custom field's data. * * @param integer $id * * @return object */ public static function getData($id) { if (!$id) { return; } $db = \JFactory::getDbo(); $query = $db->getQuery(true); $query ->select($db->quoteName(['fieldparams'])) ->from($db->quoteName('#__fields')) ->where($db->quoteName('id') . ' = ' . $db->quote($id)) ->where($db->quoteName('state') . ' = 1'); $db->setQuery($query); if (!$result = $db->loadResult()) { return; } return new \Joomla\Registry\Registry($result); } }PK!\㎿,system/nrframework/NRFramework/URLHelper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; use NRFramework\URL; defined('_JEXEC') or die('Restricted access'); class URLHelper { /** * Searches the given HTML for all external links and appends the affiliate paramter aff=id to every link based on an affiliate list. * * @param string $text The html to search for external links * @param array $affiliates A key value array: domain name => affiliate parameter * * @return string */ public static function replaceAffiliateLinks($text, $affiliates, $factory = null) { if (!class_exists('DOMDocument') || empty($text)) { return $text; } $factory = $factory ? $factory : new \NRFramework\Factory(); libxml_use_internal_errors(true); $dom = new \DOMDocument; $dom->encoding = 'UTF-8'; $dom->loadHTML($text); $links = $dom->getElementsByTagName('a'); foreach ($links as $link) { $linkHref = $link->getAttribute('href'); if (empty($linkHref)) { continue; } $url = new URL($linkHref, $factory); if ($url->isInternal()) { continue; } $domain = $url->getDomainName(); if (!array_key_exists($domain, $affiliates)) { continue; } $urlInstance = $url->getInstance(); $urlQuery = $urlInstance->getQuery(); $affQuery = $affiliates[$domain]; // If both queries are the same, skip the link tag if ($urlQuery === $affQuery) { continue; } if (empty($urlQuery)) { $urlInstance->setQuery($affQuery); } else { parse_str($urlQuery, $params); parse_str($affQuery, $params_); $params_new = array_merge($params, $params_); $urlInstance->setQuery(http_build_query($params_new)); } $newURL = $urlInstance->toString(); if ($newURL === $linkHref) { continue; } $link->setAttribute('href', $newURL); } return $dom->saveHtml(); } /** * Convert all and tags with relative paths to absolute URLs * * @param string $text The text/HTML to search for relative paths * @param object $factory The framework's factory * @param object $fix_links Should we parse links? * @param object $fix_images Should we parse images? * * @return void The converted HTML string */ public static function relativePathsToAbsoluteURLs($text, $factory = null, $fix_links = true, $fix_images = true) { // Make sure DOMDocument is installed if (!class_exists('DOMDocument')) { return $text; } // Quick check the given text has some links or images $hasImages = $fix_images && strpos($text, 'encoding = 'UTF-8'; // Handle non-latin characters to UTF8 $text_ = mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'); // Load HTML without adding a doctype. // Do not ever try to remove tags with LIBXML_HTML_NOIMPLIED constant as it's rather unstable. // https://stackoverflow.com/questions/4879946/how-to-savehtml-of-domdocument-without-html-wrapper/44866403#44866403 // LIBXML_HTML_NODEFDTD requires Libxml >= 2.7.8 - https://www.php.net/manual/en/libxml.constants.php $dom->loadHTML($text_, LIBXML_HTML_NODEFDTD); // Replace links if ($fix_links) { $links = $dom->getElementsByTagName('a'); foreach ($links as $link) { $resource = $link->getAttribute('href'); if (empty($resource) || mb_substr($resource, 0, 1) == '#') { continue; } $url = new URL($resource, $factory); if (!$url->isInternal()) { continue; } $newURL = $url->toAbsolute(); $link->setAttribute('href', $newURL); $replacements++; } } // Replace images if ($fix_images) { $images = $dom->getElementsByTagName('img'); foreach ($images as $image) { $resource = $image->getAttribute('src'); if (empty($resource)) { continue; } $url = new URL($resource, $factory); if (!$url->isInternal()) { continue; } $newURL = $url->toAbsolute(); $image->setAttribute('src', $newURL); $replacements++; } } // If we don't have any replacements took place, proceed no further and return the original text. if ($replacements == 0) { return $text; } $html = trim($dom->saveHTML()); // Make sure no or tags are added in the text // In case the final string starts with , we assume the elements are added by DOMDocument incorectly and we remove them. // In case the final string starts with ..., we assume the elements are included in the original text and we must leave them. if (strpos($html, '') !== false) { $html = str_replace(['', ''], '', $html); } return $html; } catch (\Throwable $th) { return $text; } } }PK!;aBB,system/nrframework/NRFramework/Functions.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); use Joomla\Registry\Registry; use NRFramework\Cache; use Joomla\CMS\Factory; use Joomla\CMS\Date\Date; class Functions { /** * Add HTML before the closing tag. * * @param string $html The HTML to prepend to * @param boolean $once If true, the HTML will be added only once. * * @return void */ public static function appendToBody($html, $once = false) { if ($once) { $hash = md5($html); if (Cache::has($hash)) { return; } Cache::set($hash, true); } $app = \JFactory::getApplication(); $app->registerEvent('onAfterRender', function() use ($app, $html) { $buffer = $app->getBody(); $closingTag = ''; if (strpos($buffer, $closingTag)) { // If exists prepend the given HTML $buffer = str_replace($closingTag, $html . $closingTag, $buffer); } else { // If does not exist append to document's end $buffer .= $html; } $app->setBody($buffer); }); } /** * Attempt to convert a subject to array * * @param mixed $subject * * @return array */ public static function makeArray($subject) { if (empty($subject)) { return []; } if (is_object($subject)) { return (array) $subject; } if (!is_array($subject)) { // replace newlines with commas $subject = str_replace(PHP_EOL, ',', $subject); // split keywords on commas $subject = explode(',', $subject); } // Now that we have an array, run some housekeeping. $arr = $subject; // Trim entries $arr = array_map('trim', $subject); // Remove empty items. We use a custom callback here because the default behavior of array_filter removes 0 values as well. $arr = array_filter($arr, function($value) { return ($value !== null && $value !== false && $value !== ''); }); // Unique only items $arr = array_unique($arr); // Reset keys $arr = array_values($arr); return $arr; } /** * Return the real site base URL by ignoring the live_site configuration option. * * @param bool $ignore_admin If enabled and we are browsing administrator, we will get the front-end site root URL. * * @return string */ public static function getRootURL($ignore_admin = true) { $factory = \JFactory::getConfig(); // Store the original live_site value $live_site_original = $factory->get('live_site', ''); // If we live_site is not set, do not proceed further. Return the default website base URL. if (empty($live_site_original)) { return $ignore_admin ? \JURI::root() : \JURI::base(); } // Remove the live site $factory->set('live_site', ''); // Remove all cached JURI instances \JURI::reset(); // Get a new URL. The live_site option should be ignored. $base_url = $ignore_admin ? \JURI::root() : \JURI::base(); // Set back the original live_site $factory->set('live_site', $live_site_original); \JURI::reset(); return $base_url; } /** * Insert an associative array into a specific position in an array * * @param $original array The original array to add to * @param $new array The new array of values to insert into the original * @param $offset int The position in the array ( 0 index ) where the new array should go * * @return array The new combined array */ public static function array_splice_assoc($original,$new,$offset) { return array_slice($original, 0, $offset, true) + $new + array_slice($original, $offset, NULL, true); } public static function renderField($fieldname) { $fieldname = strtolower($fieldname); require_once JPATH_PLUGINS . '/system/nrframework/fields/' . $fieldname . '.php'; $classname = '\JFormField' . $fieldname; $field = new $classname(); $element = new \SimpleXMLElement(' '); $field->setup($element, null); return $field->__get('input'); } /** * Checks if an array of values (needle) exists in a text (haystack) * * @param array $needle The searched array of values. * @param string $haystack The text * @param bool $case_insensitive Indicates whether the letter case plays any role * * @return bool */ public static function strpos_arr($needles, $haystack, $case_insensitive = false) { $needles = !is_array($needles) ? (array) $needles : $needles; $haystack = $case_insensitive ? strtolower($haystack) : $haystack; foreach ($needles as $needle) { $needle = $case_insensitive ? strtolower($needle) : $needle; if (strpos($haystack, $needle) !== false) { // stop on first true result return true; } } return false; } /** * Log message to framework's log file * * @param mixed $data Log message * * @return void */ public static function log($data) { $data = (is_object($data) || is_array($data)) ? print_r($data, true) : $data; try { \JLog::add($data, \JLog::DEBUG, 'nrframework'); } catch (\Throwable $th) { } } /** * Return's a URL with the Google Analytics Campaign Parameters appended to the end * * @param string $url The URL * @param string $medium Campaign Medium * @param string $campaign Campaign Name * * @return string */ public static function getUTMURL($url, $medium = "upgradebutton", $campaign = "freeversion") { if (!$url) { return; } $utm = 'utm_source=Joomla&utm_medium=' . $medium . '&utm_campaign=' . $campaign; $char = strpos($url, "?") === false ? "?" : "&"; return $url . $char . $utm; } /** * Returns user's Download Key * * @return string */ public static function getDownloadKey() { $class = new Updatesites(); return $class->getDownloadKey(); } /** * Adds a script or a stylesheet to the document * * @param Mixed $files The files to be to added to the document * @param boolean $appendVersion Adds file versioning based on extension's version * * @return void */ public static function addMedia($files, $extension = "plg_system_nrframework", $appendVersion = true) { $doc = \JFactory::getDocument(); $version = self::getExtensionVersion($extension); $mediaPath = \JURI::root(true) . "/media/" . $extension; if (!is_array($files)) { $files = array($files); } foreach ($files as $key => $file) { $fileExt = \JFile::getExt($file); $filename = $mediaPath . "/" . $fileExt . "/" . $file; $filename = ($appendVersion) ? $filename . "?v=" . $version : $filename; if ($fileExt == "js") { $doc->addScript($filename); } if ($fileExt == "css") { $doc->addStylesheet($filename); } } } /** * Get the Framework version * * @return string The framework version */ public static function getVersion() { return self::getExtensionVersion("plg_system_nrframework"); } /** * Checks if document is a feed document (xml, rss, atom) * * @return boolean */ public static function isFeed() { return ( \JFactory::getDocument()->getType() == 'feed' || \JFactory::getDocument()->getType() == 'xml' || \JFactory::getApplication()->input->getWord('format') == 'feed' || \JFactory::getApplication()->input->getWord('type') == 'rss' || \JFactory::getApplication()->input->getWord('type') == 'atom' ); } public static function loadLanguage($extension = 'plg_system_nrframework', $basePath = '') { if ($basePath && \JFactory::getLanguage()->load($extension, $basePath)) { return true; } $basePath = self::getExtensionPath($extension, $basePath, 'language'); return \JFactory::getLanguage()->load($extension, $basePath); } /** * Returns extension ID * * @param string $extension Extension name * * @return integer * * @deprecated Use \NRFramework\Extension::getID instead */ public static function getExtensionID($extension, $folder = null) { $type = is_null($folder) ? 'component' : 'plugin'; return \NRFramework\Extension::getID($extension, $type, $folder); } /** * Checks if extension is installed * * @param string $extension The extension element name * @param string $type The extension's type * @param string $folder Plugin folder * * * @return boolean Returns true if extension is installed * * @deprecated Use \NRFramework\Extension::isInstalled instead */ public static function extensionInstalled($extension, $type = 'component', $folder = 'system') { return \NRFramework\Extension::isInstalled($extension, $type, $folder); } /** * Returns the version number from the extension's xml file * * @param string $extension The extension element name * * @return string Extension's version number */ public static function getExtensionVersion($extension, $type = false) { $hash = MD5($extension . "_" . ($type ? "1" : "0")); $cache = Cache::read($hash); if ($cache) { return $cache; } $xml = self::getExtensionXMLFile($extension); if (!$xml) { return false; } $xml = \JInstaller::parseXMLInstallFile($xml); if (!$xml || !isset($xml['version'])) { return ''; } $version = $xml['version']; if ($type) { $extType = Extension::isPro($extension) ? 'Pro' : 'Free'; $version = $xml["version"] . " " . $extType; } return Cache::set($hash, $version); } public static function getExtensionXMLFile($extension, $basePath = JPATH_ADMINISTRATOR) { $alias = explode("_", $extension); $alias = end($alias); $filename = (strpos($extension, 'mod_') === 0) ? "mod_" . $alias : $alias; $file = self::getExtensionPath($extension, $basePath) . "/" . $filename . ".xml"; if (\JFile::exists($file)) { return $file; } return false; } /** * @deprecated // Use Extension::isPro(); */ public static function extensionHasProInstalled($extension) { return Extension::isPro($extension); } public static function getExtensionPath($extension = 'plg_system_nrframework', $basePath = JPATH_ADMINISTRATOR, $check_folder = '') { switch (true) { case (strpos($extension, 'com_') === 0): $path = 'components/' . $extension; break; case (strpos($extension, 'mod_') === 0): $path = 'modules/' . $extension; break; case (strpos($extension, 'plg_system_') === 0): $path = 'plugins/system/' . substr($extension, strlen('plg_system_')); break; case (strpos($extension, 'plg_editors-xtd_') === 0): $path = 'plugins/editors-xtd/' . substr($extension, strlen('plg_editors-xtd_')); break; } $check_folder = $check_folder ? '/' . $check_folder : ''; $basePath = empty($basePath) ? JPATH_ADMINISTRATOR : $basePath; if (is_dir($basePath . '/' . $path . $check_folder)) { return $basePath . '/' . $path; } if (is_dir(JPATH_ADMINISTRATOR . '/' . $path . $check_folder)) { return JPATH_ADMINISTRATOR . '/' . $path; } if (is_dir(JPATH_SITE . '/' . $path . $check_folder)) { return JPATH_SITE . '/' . $path; } return $basePath; } public static function loadModule($id, $moduleStyle = null) { // Return if no module id passed if (!$id) { return; } // Fetch module from db $db = \JFactory::getDBO(); $query = $db->getQuery(true) ->select('*') ->from('#__modules') ->where('id='.$db->q($id)); $db->setQuery($query); // Return if no modules found if (!$module = $db->loadObject()) { return; } // Success! Return module's html return \JModuleHelper::renderModule($module, $moduleStyle); } public static function fixDate(&$date) { if (!$date) { $date = null; return; } $date = trim($date); // Check if date has correct syntax: 00-00-00 00:00:00 if (preg_match('#^[0-9]+-[0-9]+-[0-9]+( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])$#', $date)) { return; } // Check if date has syntax: 00-00-00 00:00 // If so, add :00 (seconds) if (preg_match('#^[0-9]+-[0-9]+-[0-9]+ [0-9][0-9]:[0-9][0-9]$#', $date)) { $date .= ':00'; return; } // Check if date has a prepending date syntax: 00-00-00 ... // If so, add 00:00:00 (hours:mins;secs) if (preg_match('#^([0-9]+-[0-9]+-[0-9]+)#', $date, $match)) { $date = $match[1] . ' 00:00:00'; return; } // Date format is not correct, so return null $date = null; } /** * Change date's timezone to UTC by modyfing the offset * * @param string $date The date in timezone other than UTC * * @return string The date in UTC */ public static function dateToUTC($date) { $date = is_string($date) ? trim($date) : $date; if (empty($date) || is_null($date) || $date == '0000-00-00 00:00:00') { return $date; } $timezone = Factory::getUser()->getParam('timezone', Factory::getConfig()->get('offset')); $date = new Date($date, $timezone); $date->setTimezone(new \DateTimeZone('UTC')); $dateUTC = $date->format('Y-m-d H:i:s', true, false); return $dateUTC; } /** * Change date's timezone to UTC by modyfing the offset * * @param string $date The date in timezone other than UTC * * @return string The date in UTC * * @deprecated Use dateToUTC() */ public static function fixDateOffset(&$date) { $date = self::dateToUTC($date); } // Text public static function clean($string) { $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens. return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars. } public static function dateTimeNow() { return \JFactory::getDate()->format("Y-m-d H:i:s"); } /** * Get framework plugin's parameters * * @return JRegistry The plugin parameters */ public static function params() { $hash = md5('frameworkParams'); if (Cache::has($hash)) { return Cache::read($hash); } $db = \JFactory::getDBO(); $result = $db->setQuery( $db->getQuery(true) ->select('params') ->from('#__extensions') ->where('element = ' . $db->quote('nrframework')) )->loadResult(); return Cache::set($hash, new Registry($result)); } }PK!ͷ(system/nrframework/NRFramework/Image.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ namespace NRFramework; // No direct access defined('_JEXEC') or die; use NRFramework\Mimes; use NRFramework\File; class Image { /** * Resize an image. * * @param string $source * @param string $width * @param string $height * @param integer $quality * @param string $mode * @param boolean $unique_filename * * @return mixed */ public static function resize($source, $width, $height, $quality = 80, $mode = 'crop', $destination = '', $unique_filename = false) { // Find thumbnail full file path $destination = empty($destination) ? $source : $destination; // size must be WIDTHxHEIGHT $size = $width . 'x' . $height; switch ($mode) { // Crop and Resize case 'crop': $mode = 5; break; // Scale Fill case 'stretch': $mode = 1; break; // Fit, will fill empty space with black case 'fit': $mode = 6; break; default: $mode = 5; break; } try { $image = new \JImage($source); // Determine the MIME of the original file to get the proper type $mime = Mimes::detectFileType($source); // PNG images should not have a quality value $options = $mime == 'image/png' ? [] : ['quality' => $quality]; // Get the image type $image_type = self::getImageType($mime); if ($unique_filename) { // Make destination file unique File::uniquefy($destination); } $destination = \JPath::clean($destination); // dont resize gif images if ($mime !== 'image/gif') { foreach ($image->generateThumbs($size, $mode) as $thumb) { $thumb->toFile($destination, $image_type, $options); } } // if we have uploaded a gif image, simply rename it else { $image->toFile($destination, $image_type, $options); } return $destination; } catch(\Exception $e) { return false; } } /** * Resizes an image by keeping the aspect ratio * * @param string $source * @param array $width * @param integer $quality * @param array $destination * @param boolean $unique_filename * * @return boolean */ public static function resizeAndKeepAspectRatio($source, $width, $quality = 80, $destination = '', $unique_filename = false) { // Ensure we have received valid image dimensions if (!count($image_dimensions = getimagesize($source))) { return false; } // Get the image width if (!$uploaded_image_width = (int) $image_dimensions[0]) { return false; } // Get the image height if (!$uploaded_image_height = (int) $image_dimensions[1]) { return false; } /** * If the image width is less than the given width, * set the image width we are resizing to the image's width. */ if ($uploaded_image_width < $width) { $width = $uploaded_image_width; } // Determine the MIME of the original file to get the proper type $mime = Mimes::detectFileType($source); // PNG images should not have a quality value $options = $mime == 'image/png' ? [] : ['quality' => $quality]; // Get the image type $type = self::getImageType($mime); try { // Get image object $image = new \JImage($source); // Calculate aspect ratio $ratio = $uploaded_image_width / $uploaded_image_height; // Get new height based on aspect ratio $targetHeight = $width / $ratio; // GIF images are not resized $resizedImage = $mime == 'image/gif' ? $image : $image->resize($width, $targetHeight, true); // Output file name $destination = empty($destination) ? $source : $destination; if ($unique_filename) { // Make destination file unique File::uniquefy($destination); } $destination = \JPath::clean($destination); // Store the resized image to a new file $resizedImage->toFile($destination, $type, $options); return $destination; } catch(\Exception $e) {} return false; } /** * Returns the image type based on its mime type * * @param string $mime * * @return int */ public static function getImageType($mime) { switch ($mime) { case 'image/png': return IMAGETYPE_PNG; break; case 'image/gif': return IMAGETYPE_GIF; break; case 'image/jpeg': default: return IMAGETYPE_JPEG; break; } } }PK!WHyy%system/nrframework/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/script.install.helper.php'; class PlgSystemNRFrameworkInstallerScript extends PlgSystemNRFrameworkInstallerScriptHelper { public $name = 'NOVARAIN_FRAMEWORK'; public $alias = 'nrframework'; public $extension_type = 'plugin'; public function onBeforeInstall() { if (!$this->isNewer()) { return false; } } } PK!K GGsystem/nrframework/autoload.phpnu[ or later */ defined( '_JEXEC' ) or die( 'Restricted access' ); // Registers framework's namespace JLoader::registerNamespace('NRFramework', __DIR__ . '/NRFramework/', false, false, 'psr4'); // Assignment related class aliases JLoader::registerAlias('NRFrameworkFunctions', '\\NRFramework\\Functions'); JLoader::registerAlias('NRAssignment', '\\NRFramework\\Conditions\Condition'); JLoader::registerAlias('nrFrameworkAssignmentsHelper', '\\NRFramework\\Assignments'); JLoader::registerAlias('nrFrameworkAssignmentsAcyMailing', '\\NRFramework\\Conditions\\AcyMailing'); JLoader::registerAlias('nrFrameworkAssignmentsAkeebaSubs', '\\NRFramework\\Conditions\\AkeebaSubs'); JLoader::registerAlias('nrFrameworkAssignmentsContent', '\\NRFramework\\Conditions\\Content'); JLoader::registerAlias('nrFrameworkAssignmentsConvertForms', '\\NRFramework\\Conditions\\ConvertForms'); JLoader::registerAlias('nrFrameworkAssignmentsDateTime', '\\NRFramework\\Conditions\\DateTime'); JLoader::registerAlias('nrFrameworkAssignmentsDevices', '\\NRFramework\\Conditions\\Devices'); JLoader::registerAlias('nrFrameworkAssignmentsGeoIP', '\\NRFramework\\Conditions\\GeoIP'); JLoader::registerAlias('nrFrameworkAssignmentsLanguages', '\\NRFramework\\Conditions\\Languages'); JLoader::registerAlias('nrFrameworkAssignmentsMenu', '\\NRFramework\\Conditions\\Menu'); JLoader::registerAlias('nrFrameworkAssignmentsPHP', '\\NRFramework\\Conditions\\PHP'); JLoader::registerAlias('nrFrameworkAssignmentsURLs', '\\NRFramework\\Conditions\\URLs'); JLoader::registerAlias('nrFrameworkAssignmentsUsers', '\\NRFramework\\Conditions\\Users'); JLoader::registerAlias('nrFrameworkAssignmentsOS', '\\NRFramework\\Conditions\\OS'); JLoader::registerAlias('nrFrameworkAssignmentsBrowsers', '\\NRFramework\\Conditions\\Browsers'); JLoader::registerAlias('NRCache', '\\NRFramework\\Cache'); JLoader::registerAlias('NRHTML', '\\NRFramework\\HTML'); JLoader::registerAlias('NRUpdateSites', '\\NRFramework\\Updatesites'); JLoader::registerAlias('NRSmartTags', '\\NRFramework\\SmartTags\\SmartTags'); JLoader::registerAlias('NRFramework\\SmartTags', '\\NRFramework\\SmartTags\\SmartTags'); JLoader::registerAlias('NREmail', '\\NRFramework\\Email'); JLoader::registerAlias('NRVisitor', '\\NRFramework\\VisitorToken'); JLoader::registerAlias('NRFonts', '\\NRFramework\\Fonts'); JLoader::registerAlias('NR_activecampaign', '\\NRFramework\\Integrations\\ActiveCampaign'); JLoader::registerAlias('NR_campaignmonitor', '\\NRFramework\\Integrations\\CampaignMonitor'); JLoader::registerAlias('NR_convertkit', '\\NRFramework\\Integrations\\ConvertKit'); JLoader::registerAlias('NR_drip', '\\NRFramework\\Integrations\\Drip'); JLoader::registerAlias('NR_elasticemail', '\\NRFramework\\Integrations\\ElasticEmail'); JLoader::registerAlias('NR_getresponse', '\\NRFramework\\Integrations\\GetResponse'); JLoader::registerAlias('NR_hubspot', '\\NRFramework\\Integrations\\HubSpot'); JLoader::registerAlias('NR_icontact', '\\NRFramework\\Integrations\\IContact'); JLoader::registerAlias('NR_mailchimp', '\\NRFramework\\Integrations\\MailChimp'); JLoader::registerAlias('NR_recaptcha', '\\NRFramework\\Integrations\\ReCaptcha'); JLoader::registerAlias('NR_salesforce', '\\NRFramework\\Integrations\\Salesforce'); JLoader::registerAlias('NR_sendinblue', '\\NRFramework\\Integrations\\SendInBlue'); JLoader::registerAlias('NR_zoho', '\\NRFramework\\Integrations\\Zoho'); JLoader::registerAlias('NR_zohocrm', '\\NRFramework\\Integrations\\ZohoCRM'); // Define a helper constant to indicate whether we are on a Joomla 4 installation if (version_compare(JVERSION, '4.0', 'ge') && !defined('nrJ4')) { define('nrJ4', true); }PK!:,"system/nrframework/nrframework.xmlnu[ plg_system_nrframework PLG_SYSTEM_NRFRAMEWORK_DESC 4.9.40 August 2016 Tassos Marinos Copyright © 2021 Tassos Marinos All Rights Reserved http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL info@tassos.gr http://www.tassos.gr script.install.php nrframework.php script.install.helper.php autoload.php fields helpers xml language layouts NRFramework
img css js svg
PK!R"system/nrframework/nrframework.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined( '_JEXEC' ) or die( 'Restricted access' ); jimport('joomla.filesystem.file'); use Joomla\String\StringHelper; use NRFramework\HTML; // Initialize Novarain Library require_once __DIR__ . '/autoload.php'; class plgSystemNRFramework extends JPlugin { /** * Auto load plugin language * * @var boolean */ protected $autoloadLanguage = true; /** * The Joomla Application object * * @var object */ protected $app; /** * Plugin constructor * * @param mixed &$subject * @param array $config */ public function __construct(&$subject, $config = array()) { // Declare extension logger JLog::addLogger( array('text_file' => 'plg_system_nrframework.php'), JLog::ALL, array('nrframework') ); // execute parent constructor parent::__construct($subject, $config); } /** * Update UpdateSites after the user has entered a Download Key * * @param string $context The component context * @param string $table * @param boolean $isNew * * @return void */ public function onExtensionAfterSave($context, $table, $isNew) { // Run only on Novarain Framework edit form if ( $this->app->isClient('site') || $context != 'com_plugins.plugin' || $table->element != 'nrframework' || !isset($table->params) ) { return; } // Set Download Key & fix Update Sites $upds = new NRFramework\Updatesites(); $upds->update(); } /** * Handling of PRO for extensions * Throws a notice message if the Download Key is missing before downloading the package * * @param string &$url Update Site URL * @param array &$headers */ public function onInstallerBeforePackageDownload(&$url, &$headers) { $uri = JUri::getInstance($url); $host = $uri->getHost(); // This is not a Tassos.gr extension if (strpos($host, 'tassos.gr') === false) { return true; } // If it's a Free version. No need to check for the Download Key. if (strpos($url, 'free') !== false) { return true; } // This is a Pro version. Let's validate the Download Key. $download_id = $this->params->get('key', ''); // Append it to the URL if (!empty($download_id)) { $uri->setVar('dlid', $download_id); $url = $uri->toString(); return true; } $this->app->enqueueMessage('To be able to update the Pro version of this extension via the Joomla updater, you will need enter your Download Key in the settings of the
Novarain Framework System Plugin'); return true; } /** * Listens to AJAX requests on ?option=com_ajax&format=raw&plugin=nrframework * * @return void */ public function onAjaxNrframework() { JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); // Only in backend if (!$this->app->isClient('administrator')) { return; } // Check if we have a valid task $task = $this->app->input->get('task', null); // Check if we have a valid method task $taskMethod = 'ajaxTask' . $task; if (!method_exists($this, $taskMethod)) { die('Task not found'); } $this->$taskMethod(); } /** * Handles the Widgets AJAX requests. * * @return void */ public function onAjaxWidgets() { JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); $widget = $this->app->input->get('widget', null); $class = '\NRFramework\Widgets\\' . $widget; if (!class_exists($class)) { return; } $task = $this->app->input->get('task'); (new $class)->onAjax($task); } private function ajaxTaskInclude() { $input = $this->app->input; $file = $input->get('file'); $path = JPATH_SITE . '/' . $input->get('path', '', 'RAW'); $class = $input->get('class'); $file_to_include = $path . $file . '.php'; if (!JFile::exists($file_to_include)) { die('FILE_ERROR'); } @include_once $file_to_include; if (!class_exists($class)) { die('CLASS_ERROR'); } if (!method_exists($class, 'onAJAX')) { die('METHOD_ERROR'); } (new $class())->onAJAX($input->getArray()); } /** * Conditional Builder AJAX requests. * * @return void */ private function ajaxTaskConditionBuilder() { $input = $this->app->input; $subtask = $input->get('subtask', null); switch ($subtask) { // Adding a condition item or group case 'add': $conditionItemGroup = $input->get('conditionItemGroup', null, 'RAW'); $groupKey = $input->getInt('groupKey'); $conditionKey = $input->getInt('conditionKey'); $include_rules = $input->get('include_rules', null, 'RAW'); $exclude_rules = $input->get('exclude_rules', null, 'RAW'); $conditionItem = NRFramework\Conditions\ConditionBuilder::add($conditionItemGroup, $groupKey, $conditionKey, null, $include_rules, $exclude_rules); // Adding a single condition item if ($input->get('addingNewGroup') === 'false') { echo $conditionItem; break; } $payload = [ 'name' => $conditionItemGroup, 'groupKey' => $groupKey, 'groupConditions' => ['enabled' => 1], 'include_rules' => $include_rules, 'exclude_rules' => $exclude_rules, 'condition_items_parsed' => [$conditionItem], ]; // Adding a condition group echo NRFramework\Conditions\ConditionBuilder::getLayout('conditionbuilder_group', $payload); break; case 'options': $conditionItemGroup = $input->get('conditionItemGroup', null, 'RAW'); $name = $input->get('name', null, 'RAW'); echo NRFramework\Conditions\ConditionBuilder::renderOptions($name, $conditionItemGroup); break; case 'init_load': $payload = [ 'data' => $input->get('data', [], 'RAW'), 'name' => $input->get('name', null, 'RAW'), 'include_rules' => $input->get('include_rules', null, 'RAW'), 'exclude_rules' => $input->get('exclude_rules', null, 'RAW') ]; echo NRFramework\Conditions\ConditionBuilder::initLoad($payload); break; } } /** * Check if the extension has an update and display a notification * * @return string */ private function ajaxTaskUpdateNotification() { echo HTML::updateNotification($this->app->input->get('element')); } }PK!Y,system/nrframework/xml/conditions/device.xmlnu[
PK!`/system/nrframework/xml/conditions/engagebox.xmlnu[
PK! fU0system/nrframework/xml/conditions/date/month.xmlnu[
PK!::.system/nrframework/xml/conditions/date/day.xmlnu[
PK!Ņ/system/nrframework/xml/conditions/date/date.xmlnu[
PK!L/system/nrframework/xml/conditions/date/time.xmlnu[
PK!;)system/nrframework/xml/conditions/php.xmlnu[
PK!t,ss>system/nrframework/xml/conditions/component/contentarticle.xmlnu[
PK!ovv:system/nrframework/xml/conditions/component/k2pagetype.xmlnu[
PK! ``;system/nrframework/xml/conditions/component/contentview.xmlnu[
PK!JǓ?system/nrframework/xml/conditions/component/contentcategory.xmlnu[
PK! ii5system/nrframework/xml/conditions/component/k2tag.xmlnu[
PK!JX**6system/nrframework/xml/conditions/component/k2item.xmlnu[
PK!:system/nrframework/xml/conditions/component/k2category.xmlnu[
PK!ǕjRR0system/nrframework/xml/conditions/timeonsite.xmlnu[
PK!V㥄JJ0system/nrframework/xml/conditions/akeebasubs.xmlnu[
PK!W.system/nrframework/xml/conditions/geo/city.xmlnu[
PK!ιYY0system/nrframework/xml/conditions/geo/region.xmlnu[
PK!l1system/nrframework/xml/conditions/geo/country.xmlnu[
PK!=;3system/nrframework/xml/conditions/geo/continent.xmlnu[
PK!&N-system/nrframework/xml/conditions/browser.xmlnu[
PK!k)system/nrframework/xml/conditions/url.xmlnu[
PK!=72system/nrframework/xml/conditions/convertforms.xmlnu[
PK!/>ކ6system/nrframework/xml/conditions/joomla/component.xmlnu[
PK!Pxll6system/nrframework/xml/conditions/joomla/usergroup.xmlnu[
PK!z&ĕ8system/nrframework/xml/conditions/joomla/accesslevel.xmlnu[
PK!\J 73system/nrframework/xml/conditions/joomla/userid.xmlnu[
PK!1system/nrframework/xml/conditions/joomla/menu.xmlnu[
PK!dii5system/nrframework/xml/conditions/joomla/language.xmlnu[
PK!ؤ../system/nrframework/xml/conditions/pageviews.xmlnu[
PK!P(system/nrframework/xml/conditions/ip.xmlnu[
PK!d-ʃ(system/nrframework/xml/conditions/os.xmlnu[
PK!ނ.system/nrframework/xml/conditions/referrer.xmlnu[
PK!**,system/nrframework/xml/conditions/cookie.xmlnu[
PK!'Dbb0system/nrframework/xml/conditions/acymailing.xmlnu[
PK!M0system/nrframework/xml/conditionbuilder/base.xmlnu[
PK!OFZZsystem/debug/debug.xmlnu[ plg_system_debug Joomla! Project 2006-12 (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_DEBUG_XML_DESCRIPTION Joomla\Plugin\System\Debug services src language/en-GB/plg_system_debug.ini language/en-GB/plg_system_debug.sys.ini
PK!"system/debug/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\Debug\Extension\Debug; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { return new Debug( $container->get(DispatcherInterface::class), (array) PluginHelper::getPlugin('system', 'debug'), Factory::getApplication(), $container->get(DatabaseInterface::class) ); } ); } }; PK!bY 3system/debug/src/DataCollector/SessionCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use Joomla\CMS\Factory; use Joomla\Plugin\System\Debug\AbstractDataCollector; use Joomla\Plugin\System\Debug\Extension\Debug; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * SessionDataCollector * * @since 4.0.0 */ class SessionCollector extends AbstractDataCollector { /** * Collector name. * * @var string * @since 4.0.0 */ private $name = 'session'; /** * Collected data. * * @var array * @since 4.4.0 */ protected $sessionData; /** * Constructor. * * @param Registry $params Parameters. * @param bool $collect Collect the session data. * * @since 4.4.0 */ public function __construct($params, $collect = false) { parent::__construct($params); if ($collect) { $this->collect(); } } /** * Called by the DebugBar when data needs to be collected * * @param bool $overwrite Overwrite the previously collected session data. * * @return array Collected data * * @since 4.0.0 */ public function collect($overwrite = false) { if ($this->sessionData === null || $overwrite) { $this->sessionData = []; $data = Factory::getApplication()->getSession()->all(); // redact value of potentially secret keys array_walk_recursive($data, static function (&$value, $key) { if (!preg_match(Debug::PROTECTED_COLLECTOR_KEYS, $key)) { return; } $value = '***redacted***'; }); foreach ($data as $key => $value) { $this->sessionData[$key] = $this->getDataFormatter()->formatVar($value); } } return ['data' => $this->sessionData]; } /** * Returns the unique name of the collector * * @since 4.0.0 * * @return string */ public function getName() { return $this->name; } /** * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * * @since 4.0.0 * * @return array */ public function getWidgets() { return [ 'session' => [ 'icon' => 'key', 'widget' => 'PhpDebugBar.Widgets.VariableListWidget', 'map' => $this->name . '.data', 'default' => '[]', ], ]; } } PK!Aum**;system/debug/src/DataCollector/LanguageStringsCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use DebugBar\DataCollector\AssetProvider; use Joomla\CMS\Factory; use Joomla\CMS\Language\Language; use Joomla\CMS\Uri\Uri; use Joomla\Plugin\System\Debug\AbstractDataCollector; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * LanguageStringsDataCollector * * @since 4.0.0 */ class LanguageStringsCollector extends AbstractDataCollector implements AssetProvider { /** * Collector name. * * @var string * @since 4.0.0 */ private $name = 'languageStrings'; /** * Called by the DebugBar when data needs to be collected * * @since 4.0.0 * * @return array Collected data */ public function collect(): array { return [ 'data' => $this->getData(), 'count' => $this->getCount(), ]; } /** * Returns the unique name of the collector * * @since 4.0.0 * * @return string */ public function getName(): string { return $this->name; } /** * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * * @since 4.0.0 * * @return array */ public function getWidgets(): array { return [ 'untranslated' => [ 'icon' => 'question-circle', 'widget' => 'PhpDebugBar.Widgets.languageStringsWidget', 'map' => $this->name . '.data', 'default' => '', ], 'untranslated:badge' => [ 'map' => $this->name . '.count', 'default' => 'null', ], ]; } /** * Returns an array with the following keys: * - base_path * - base_url * - css: an array of filenames * - js: an array of filenames * * @since 4.0.0 * @return array */ public function getAssets(): array { return [ 'js' => Uri::root(true) . '/media/plg_system_debug/widgets/languageStrings/widget.min.js', 'css' => Uri::root(true) . '/media/plg_system_debug/widgets/languageStrings/widget.min.css', ]; } /** * Collect data. * * @return array * * @since 4.0.0 */ private function getData(): array { $orphans = Factory::getLanguage()->getOrphans(); $data = []; foreach ($orphans as $orphan => $occurrences) { $data[$orphan] = []; foreach ($occurrences as $occurrence) { $item = []; $item['string'] = $occurrence['string'] ?? 'n/a'; $item['trace'] = []; $item['caller'] = ''; if (isset($occurrence['trace'])) { $cnt = 0; $trace = []; $callerLocation = ''; array_shift($occurrence['trace']); foreach ($occurrence['trace'] as $i => $stack) { $class = $stack['class'] ?? ''; $file = $stack['file'] ?? ''; $line = $stack['line'] ?? ''; $caller = $this->formatCallerInfo($stack); $location = $file && $line ? "$file:$line" : 'same'; $isCaller = 0; if (!$callerLocation && $class !== Language::class && !strpos($file, 'Text.php')) { $callerLocation = $location; $isCaller = 1; } $trace[] = [ \count($occurrence['trace']) - $cnt, $isCaller, $caller, $file, $line, ]; $cnt++; } $item['trace'] = $trace; $item['caller'] = $callerLocation; } $data[$orphan][] = $item; } } return [ 'orphans' => $data, 'jroot' => JPATH_ROOT, 'xdebugLink' => $this->getXdebugLinkTemplate(), ]; } /** * Get a count value. * * @return integer * * @since 4.0.0 */ private function getCount(): int { return \count(Factory::getLanguage()->getOrphans()); } } PK!ff5 2system/debug/src/DataCollector/MemoryCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use Joomla\Plugin\System\Debug\AbstractDataCollector; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Collects info about the request duration as well as providing * a way to log duration of any operations * * @since 4.4.0 */ class MemoryCollector extends AbstractDataCollector { /** * @var boolean * @since 4.4.0 */ protected $realUsage = false; /** * @var float * @since 4.4.0 */ protected $peakUsage = 0; /** * @param Registry $params Parameters. * @param float $peakUsage * @param boolean $realUsage * * @since 4.4.0 */ public function __construct(Registry $params, $peakUsage = null, $realUsage = null) { parent::__construct($params); if ($peakUsage !== null) { $this->peakUsage = $peakUsage; } if ($realUsage !== null) { $this->realUsage = $realUsage; } } /** * Returns whether total allocated memory page size is used instead of actual used memory size * by the application. See $real_usage parameter on memory_get_peak_usage for details. * * @return boolean * * @since 4.4.0 */ public function getRealUsage() { return $this->realUsage; } /** * Sets whether total allocated memory page size is used instead of actual used memory size * by the application. See $real_usage parameter on memory_get_peak_usage for details. * * @param boolean $realUsage * * @since 4.4.0 */ public function setRealUsage($realUsage) { $this->realUsage = $realUsage; } /** * Returns the peak memory usage * * @return integer * * @since 4.4.0 */ public function getPeakUsage() { return $this->peakUsage; } /** * Updates the peak memory usage value * * @since 4.4.0 */ public function updatePeakUsage() { if ($this->peakUsage === null) { $this->peakUsage = memory_get_peak_usage($this->realUsage); } } /** * @return array * * @since 4.4.0 */ public function collect() { $this->updatePeakUsage(); return [ 'peak_usage' => $this->peakUsage, 'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage, 3), ]; } /** * @return string * * @since 4.4.0 */ public function getName() { return 'memory'; } /** * @return array * * @since 4.4.0 */ public function getWidgets() { return [ 'memory' => [ 'icon' => 'cogs', 'tooltip' => 'Memory Usage', 'map' => 'memory.peak_usage_str', 'default' => "'0B'", ], ]; } } PK!g6 :system/debug/src/DataCollector/LanguageErrorsCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use DebugBar\DataCollector\AssetProvider; use Joomla\CMS\Factory; use Joomla\CMS\Uri\Uri; use Joomla\Plugin\System\Debug\AbstractDataCollector; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * LanguageErrorsDataCollector * * @since 4.0.0 */ class LanguageErrorsCollector extends AbstractDataCollector implements AssetProvider { /** * Collector name. * * @var string * @since 4.0.0 */ private $name = 'languageErrors'; /** * The count. * * @var integer * @since 4.0.0 */ private $count = 0; /** * Called by the DebugBar when data needs to be collected * * @since 4.0.0 * * @return array Collected data */ public function collect(): array { return [ 'data' => [ 'files' => $this->getData(), 'jroot' => JPATH_ROOT, 'xdebugLink' => $this->getXdebugLinkTemplate(), ], 'count' => $this->getCount(), ]; } /** * Returns the unique name of the collector * * @since 4.0.0 * * @return string */ public function getName(): string { return $this->name; } /** * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * * @since 4.0.0 * * @return array */ public function getWidgets(): array { return [ 'errors' => [ 'icon' => 'warning', 'widget' => 'PhpDebugBar.Widgets.languageErrorsWidget', 'map' => $this->name . '.data', 'default' => '', ], 'errors:badge' => [ 'map' => $this->name . '.count', 'default' => 'null', ], ]; } /** * Returns an array with the following keys: * - base_path * - base_url * - css: an array of filenames * - js: an array of filenames * * @since 4.0.0 * @return array */ public function getAssets() { return [ 'js' => Uri::root(true) . '/media/plg_system_debug/widgets/languageErrors/widget.min.js', 'css' => Uri::root(true) . '/media/plg_system_debug/widgets/languageErrors/widget.min.css', ]; } /** * Collect data. * * @return array * * @since 4.0.0 */ private function getData(): array { $errorFiles = Factory::getLanguage()->getErrorFiles(); $errors = []; if (\count($errorFiles)) { foreach ($errorFiles as $file => $lines) { foreach ($lines as $line) { $errors[] = [$file, $line]; $this->count++; } } } return $errors; } /** * Get a count value. * * @return int * * @since 4.0.0 */ private function getCount(): int { return $this->count; } } PK!FHu{{7system/debug/src/DataCollector/RequestDataCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use Joomla\Plugin\System\Debug\Extension\Debug; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Collects info about the request content while redacting potentially secret content * * @since 4.2.4 */ class RequestDataCollector extends \DebugBar\DataCollector\RequestDataCollector { /** * Called by the DebugBar when data needs to be collected * * @since 4.2.4 * * @return array */ public function collect() { $vars = ['_GET', '_POST', '_SESSION', '_COOKIE', '_SERVER']; $returnData = []; foreach ($vars as $var) { if (isset($GLOBALS[$var])) { $key = "$" . $var; $data = $GLOBALS[$var]; // Replace Joomla session data from session data, it will be collected by SessionCollector if ($var === '_SESSION' && !empty($data['joomla'])) { $data['joomla'] = '***redacted***'; } array_walk_recursive($data, static function (&$value, $key) { if (!preg_match(Debug::PROTECTED_COLLECTOR_KEYS, $key)) { return; } $value = '***redacted***'; }); if ($this->isHtmlVarDumperUsed()) { $returnData[$key] = $this->getVarDumper()->renderVar($data); } else { $returnData[$key] = $this->getDataFormatter()->formatVar($data); } } } return $returnData; } } PK!1||0system/debug/src/DataCollector/UserCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use DebugBar\DataCollector\DataCollectorInterface; use Joomla\CMS\Factory; use Joomla\CMS\User\UserFactoryInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * User collector that stores the user id of the person making the request allowing us to filter on it after storage * * @since 4.2.4 */ class UserCollector implements DataCollectorInterface { /** * Collector name. * * @var string * @since 4.2.4 */ private $name = 'juser'; /** * Called by the DebugBar when data needs to be collected * * @since 4.2.4 * * @return array Collected data */ public function collect() { $user = Factory::getApplication()->getIdentity() ?: Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById(0); return ['user_id' => $user->id]; } /** * Returns the unique name of the collector * * @since 4.2.4 * * @return string */ public function getName() { return $this->name; } } PK!oP  9system/debug/src/DataCollector/LanguageFilesCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use DebugBar\DataCollector\AssetProvider; use Joomla\CMS\Factory; use Joomla\CMS\Uri\Uri; use Joomla\Plugin\System\Debug\AbstractDataCollector; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * LanguageFilesDataCollector * * @since 4.0.0 */ class LanguageFilesCollector extends AbstractDataCollector implements AssetProvider { /** * Collector name. * * @var string * @since 4.0.0 */ private $name = 'languageFiles'; /** * The count. * * @var integer * @since 4.0.0 */ private $count = 0; /** * Called by the DebugBar when data needs to be collected * * @since 4.0.0 * * @return array Collected data */ public function collect(): array { $paths = Factory::getLanguage()->getPaths(); $loaded = []; foreach ($paths as $extension => $files) { $loaded[$extension] = []; foreach ($files as $file => $status) { $loaded[$extension][$file] = $status; if ($status) { $this->count++; } } } return [ 'loaded' => $loaded, 'xdebugLink' => $this->getXdebugLinkTemplate(), 'jroot' => JPATH_ROOT, 'count' => $this->count, ]; } /** * Returns the unique name of the collector * * @since 4.0.0 * * @return string */ public function getName(): string { return $this->name; } /** * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * * @since 4.0.0 * * @return array */ public function getWidgets(): array { return [ 'loaded' => [ 'icon' => 'language', 'widget' => 'PhpDebugBar.Widgets.languageFilesWidget', 'map' => $this->name, 'default' => '[]', ], 'loaded:badge' => [ 'map' => $this->name . '.count', 'default' => 'null', ], ]; } /** * Returns an array with the following keys: * - base_path * - base_url * - css: an array of filenames * - js: an array of filenames * * @since 4.0.0 * @return array */ public function getAssets(): array { return [ 'js' => Uri::root(true) . '/media/plg_system_debug/widgets/languageFiles/widget.min.js', 'css' => Uri::root(true) . '/media/plg_system_debug/widgets/languageFiles/widget.min.css', ]; } } PK!vSS1system/debug/src/DataCollector/QueryCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use DebugBar\DataCollector\AssetProvider; use Joomla\CMS\Uri\Uri; use Joomla\Database\Monitor\DebugMonitor; use Joomla\Plugin\System\Debug\AbstractDataCollector; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * QueryDataCollector * * @since 4.0.0 */ class QueryCollector extends AbstractDataCollector implements AssetProvider { /** * Collector name. * * @var string * @since 4.0.0 */ private $name = 'queries'; /** * The query monitor. * * @var DebugMonitor * @since 4.0.0 */ private $queryMonitor; /** * Profile data. * * @var array * @since 4.0.0 */ private $profiles; /** * Explain data. * * @var array * @since 4.0.0 */ private $explains; /** * Accumulated Duration. * * @var integer * @since 4.0.0 */ private $accumulatedDuration = 0; /** * Accumulated Memory. * * @var integer * @since 4.0.0 */ private $accumulatedMemory = 0; /** * Constructor. * * @param Registry $params Parameters. * @param DebugMonitor $queryMonitor Query monitor. * @param array $profiles Profile data. * @param array $explains Explain data * * @since 4.0.0 */ public function __construct(Registry $params, DebugMonitor $queryMonitor, array $profiles, array $explains) { $this->queryMonitor = $queryMonitor; parent::__construct($params); $this->profiles = $profiles; $this->explains = $explains; } /** * Called by the DebugBar when data needs to be collected * * @since 4.0.0 * * @return array Collected data */ public function collect(): array { $statements = $this->getStatements(); return [ 'data' => [ 'statements' => $statements, 'nb_statements' => \count($statements), 'accumulated_duration_str' => $this->getDataFormatter()->formatDuration($this->accumulatedDuration), 'memory_usage_str' => $this->getDataFormatter()->formatBytes($this->accumulatedMemory), 'xdebug_link' => $this->getXdebugLinkTemplate(), 'root_path' => JPATH_ROOT, ], 'count' => \count($this->queryMonitor->getLogs()), ]; } /** * Returns the unique name of the collector * * @since 4.0.0 * * @return string */ public function getName(): string { return $this->name; } /** * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * * @since 4.0.0 * * @return array */ public function getWidgets(): array { return [ 'queries' => [ 'icon' => 'database', 'widget' => 'PhpDebugBar.Widgets.SQLQueriesWidget', 'map' => $this->name . '.data', 'default' => '[]', ], 'queries:badge' => [ 'map' => $this->name . '.count', 'default' => 'null', ], ]; } /** * Assets for the collector. * * @since 4.0.0 * * @return array */ public function getAssets(): array { return [ 'css' => Uri::root(true) . '/media/plg_system_debug/widgets/sqlqueries/widget.min.css', 'js' => Uri::root(true) . '/media/plg_system_debug/widgets/sqlqueries/widget.min.js', ]; } /** * Prepare the executed statements data. * * @since 4.0.0 * * @return array */ private function getStatements(): array { $statements = []; $logs = $this->queryMonitor->getLogs(); $boundParams = $this->queryMonitor->getBoundParams(); $timings = $this->queryMonitor->getTimings(); $memoryLogs = $this->queryMonitor->getMemoryLogs(); $stacks = $this->queryMonitor->getCallStacks(); $collectStacks = $this->params->get('query_traces'); foreach ($logs as $id => $item) { $queryTime = 0; $queryMemory = 0; if ($timings && isset($timings[$id * 2 + 1])) { // Compute the query time. $queryTime = ($timings[$id * 2 + 1] - $timings[$id * 2]); $this->accumulatedDuration += $queryTime; } if ($memoryLogs && isset($memoryLogs[$id * 2 + 1])) { // Compute the query memory usage. $queryMemory = ($memoryLogs[$id * 2 + 1] - $memoryLogs[$id * 2]); $this->accumulatedMemory += $queryMemory; } $trace = []; $callerLocation = ''; if (isset($stacks[$id])) { $cnt = 0; foreach ($stacks[$id] as $i => $stack) { $class = $stack['class'] ?? ''; $file = $stack['file'] ?? ''; $line = $stack['line'] ?? ''; $caller = $this->formatCallerInfo($stack); $location = $file && $line ? "$file:$line" : 'same'; $isCaller = 0; if (\Joomla\Database\DatabaseDriver::class === $class && false === strpos($file, 'DatabaseDriver.php')) { $callerLocation = $location; $isCaller = 1; } if ($collectStacks) { $trace[] = [\count($stacks[$id]) - $cnt, $isCaller, $caller, $file, $line]; } $cnt++; } } $explain = $this->explains[$id] ?? []; $explainColumns = []; // Extract column labels for Explain table if ($explain) { $explainColumns = array_keys(reset($explain)); } $statements[] = [ 'sql' => $item, 'params' => $boundParams[$id] ?? [], 'duration_str' => $this->getDataFormatter()->formatDuration($queryTime), 'memory_str' => $this->getDataFormatter()->formatBytes($queryMemory), 'caller' => $callerLocation, 'callstack' => $trace, 'explain' => $explain, 'explain_col' => $explainColumns, 'profile' => $this->profiles[$id] ?? [], ]; } return $statements; } } PK!*^f`!`!3system/debug/src/DataCollector/ProfileCollector.phpnu[requestStartTime = $_SERVER['REQUEST_TIME_FLOAT']; } else { $this->requestStartTime = microtime(true); } parent::__construct($params); } /** * Starts a measure. * * @param string $name Internal name, used to stop the measure * @param string|null $label Public name * @param string|null $collector The source of the collector * * @return void * * @since 4.0.0 */ public function startMeasure($name, $label = null, $collector = null) { $start = microtime(true); $this->startedMeasures[$name] = [ 'label' => $label ?: $name, 'start' => $start, 'collector' => $collector, ]; } /** * Check a measure exists * * @param string $name Group name. * * @return bool * * @since 4.0.0 */ public function hasStartedMeasure($name): bool { return isset($this->startedMeasures[$name]); } /** * Stops a measure. * * @param string $name Measurement name. * @param array $params Parameters * * @return void * * @since 4.0.0 * * @throws DebugBarException */ public function stopMeasure($name, array $params = []) { $end = microtime(true); if (!$this->hasStartedMeasure($name)) { throw new DebugBarException("Failed stopping measure '$name' because it hasn't been started"); } $this->addMeasure($this->startedMeasures[$name]['label'], $this->startedMeasures[$name]['start'], $end, $params, $this->startedMeasures[$name]['collector']); unset($this->startedMeasures[$name]); } /** * Adds a measure * * @param string $label A label. * @param float $start Start of request. * @param float $end End of request. * @param array $params Parameters. * @param string|null $collector A collector. * * @return void * * @since 4.0.0 */ public function addMeasure($label, $start, $end, array $params = [], $collector = null) { $this->measures[] = [ 'label' => $label, 'start' => $start, 'relative_start' => $start - $this->requestStartTime, 'end' => $end, 'relative_end' => $end - $this->requestEndTime, 'duration' => $end - $start, 'duration_str' => $this->getDataFormatter()->formatDuration($end - $start), 'params' => $params, 'collector' => $collector, ]; } /** * Utility function to measure the execution of a Closure * * @param string $label A label. * @param \Closure $closure A closure. * @param string|null $collector A collector. * * @return void * * @since 4.0.0 */ public function measure($label, \Closure $closure, $collector = null) { $name = spl_object_hash($closure); $this->startMeasure($name, $label, $collector); $result = $closure(); $params = \is_array($result) ? $result : []; $this->stopMeasure($name, $params); } /** * Returns an array of all measures * * @return array * * @since 4.0.0 */ public function getMeasures(): array { return $this->measures; } /** * Returns the request start time * * @return float * * @since 4.0.0 */ public function getRequestStartTime(): float { return $this->requestStartTime; } /** * Returns the request end time * * @return float * * @since 4.0.0 */ public function getRequestEndTime(): float { return $this->requestEndTime; } /** * Returns the duration of a request * * @return float * * @since 4.0.0 */ public function getRequestDuration(): float { if ($this->requestEndTime !== null) { return $this->requestEndTime - $this->requestStartTime; } return microtime(true) - $this->requestStartTime; } /** * Sets request end time. * * @param float $time Request end time. * * @return $this * * @since 4.4.0 */ public function setRequestEndTime($time): self { $this->requestEndTime = $time; return $this; } /** * Called by the DebugBar when data needs to be collected * * @return array Collected data * * @since 4.0.0 */ public function collect(): array { $this->requestEndTime = $this->requestEndTime ?? microtime(true); $start = $this->requestStartTime; $marks = Profiler::getInstance('Application')->getMarks(); foreach ($marks as $mark) { $mem = $this->getDataFormatter()->formatBytes(abs($mark->memory) * 1048576); $label = $mark->label . " ($mem)"; $end = $start + $mark->time / 1000; $this->addMeasure($label, $start, $end); $start = $end; } foreach (array_keys($this->startedMeasures) as $name) { $this->stopMeasure($name); } usort( $this->measures, function ($a, $b) { if ($a['start'] === $b['start']) { return 0; } return $a['start'] < $b['start'] ? -1 : 1; } ); return [ 'start' => $this->requestStartTime, 'end' => $this->requestEndTime, 'duration' => $this->getRequestDuration(), 'duration_str' => $this->getDataFormatter()->formatDuration($this->getRequestDuration()), 'measures' => array_values($this->measures), 'rawMarks' => $marks, ]; } /** * Returns the unique name of the collector * * @return string * * @since 4.0.0 */ public function getName(): string { return 'profile'; } /** * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * * @return array * * @since 4.0.0 */ public function getWidgets(): array { return [ 'profileTime' => [ 'icon' => 'clock-o', 'tooltip' => 'Request Duration', 'map' => 'profile.duration_str', 'default' => "'0ms'", ], 'profile' => [ 'icon' => 'clock-o', 'widget' => 'PhpDebugBar.Widgets.TimelineWidget', 'map' => 'profile', 'default' => '{}', ], ]; } } PK!d0system/debug/src/DataCollector/InfoCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\DataCollector; use DebugBar\DataCollector\AssetProvider; use Joomla\CMS\Application\AdministratorApplication; use Joomla\CMS\Application\SiteApplication; use Joomla\CMS\Factory; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\User; use Joomla\Plugin\System\Debug\AbstractDataCollector; use Joomla\Registry\Registry; use Psr\Http\Message\ResponseInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * InfoDataCollector * * @since 4.0.0 */ class InfoCollector extends AbstractDataCollector implements AssetProvider { /** * Collector name. * * @var string * @since 4.0.0 */ private $name = 'info'; /** * Request ID. * * @var string * @since 4.0.0 */ private $requestId; /** * InfoDataCollector constructor. * * @param Registry $params Parameters * @param string $requestId Request ID * * @since 4.0.0 */ public function __construct(Registry $params, $requestId) { $this->requestId = $requestId; parent::__construct($params); } /** * Returns the unique name of the collector * * @since 4.0.0 * @return string */ public function getName(): string { return $this->name; } /** * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * * @since 4.0.0 * @return array */ public function getWidgets(): array { return [ 'info' => [ 'icon' => 'info-circle', 'title' => 'J! Info', 'widget' => 'PhpDebugBar.Widgets.InfoWidget', 'map' => $this->name, 'default' => '{}', ], ]; } /** * Returns an array with the following keys: * - base_path * - base_url * - css: an array of filenames * - js: an array of filenames * * @since 4.0.0 * @return array */ public function getAssets(): array { return [ 'js' => Uri::root(true) . '/media/plg_system_debug/widgets/info/widget.min.js', 'css' => Uri::root(true) . '/media/plg_system_debug/widgets/info/widget.min.css', ]; } /** * Called by the DebugBar when data needs to be collected * * @since 4.0.0 * * @return array Collected data */ public function collect(): array { /** @type SiteApplication|AdministratorApplication $application */ $application = Factory::getApplication(); $model = $application->bootComponent('com_admin') ->getMVCFactory()->createModel('Sysinfo', 'Administrator'); return [ 'phpVersion' => PHP_VERSION, 'joomlaVersion' => JVERSION, 'requestId' => $this->requestId, 'identity' => $this->getIdentityInfo($application->getIdentity()), 'response' => $this->getResponseInfo($application->getResponse()), 'template' => $this->getTemplateInfo($application->getTemplate(true)), 'database' => $this->getDatabaseInfo($model->getInfo()), ]; } /** * Get Identity info. * * @param User $identity The identity. * * @since 4.0.0 * * @return array */ private function getIdentityInfo(User $identity): array { if (!$identity->id) { return ['type' => 'guest']; } return [ 'type' => 'user', 'id' => $identity->id, 'name' => $identity->name, 'username' => $identity->username, ]; } /** * Get response info. * * @param ResponseInterface $response The response. * * @since 4.0.0 * * @return array */ private function getResponseInfo(ResponseInterface $response): array { return [ 'status_code' => $response->getStatusCode(), ]; } /** * Get template info. * * @param object $template The template. * * @since 4.0.0 * * @return array */ private function getTemplateInfo($template): array { return [ 'template' => $template->template ?? '', 'home' => $template->home ?? '', 'id' => $template->id ?? '', ]; } /** * Get database info. * * @param array $info General information. * * @since 4.0.0 * * @return array */ private function getDatabaseInfo(array $info): array { return [ 'dbserver' => $info['dbserver'] ?? '', 'dbversion' => $info['dbversion'] ?? '', 'dbcollation' => $info['dbcollation'] ?? '', 'dbconnectioncollation' => $info['dbconnectioncollation'] ?? '', 'dbconnectionencryption' => $info['dbconnectionencryption'] ?? '', 'dbconnencryptsupported' => $info['dbconnencryptsupported'] ?? '', ]; } } PK!øe: : "system/debug/src/DataFormatter.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug; use DebugBar\DataFormatter\DataFormatter as DebugBarDataFormatter; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * DataFormatter * * @since 4.0.0 */ class DataFormatter extends DebugBarDataFormatter { /** * Strip the root path. * * @param string $path The path. * @param string $replacement The replacement * * @return string * * @since 4.0.0 */ public function formatPath($path, $replacement = ''): string { return str_replace(JPATH_ROOT, $replacement, $path); } /** * Format a string from back trace. * * @param array $call The array to format * * @return string * * @since 4.0.0 */ public function formatCallerInfo(array $call): string { $string = ''; if (isset($call['class'])) { // If entry has Class/Method print it. $string .= htmlspecialchars($call['class'] . $call['type'] . $call['function']) . '()'; } elseif (isset($call['args'][0]) && \is_array($call['args'][0])) { $string .= htmlspecialchars($call['function']) . ' ('; foreach ($call['args'][0] as $arg) { // Check if the arguments can be used as string if (\is_object($arg) && !method_exists($arg, '__toString')) { $arg = \get_class($arg); } // Keep only the size of array if (\is_array($arg)) { $arg = 'Array(count=' . \count($arg) . ')'; } $string .= htmlspecialchars($arg) . ', '; } $string = rtrim($string, ', ') . ')'; } elseif (isset($call['args'][0])) { $string .= htmlspecialchars($call['function']) . '('; if (is_scalar($call['args'][0])) { $string .= $call['args'][0]; } elseif (\is_object($call['args'][0])) { $string .= \get_class($call['args'][0]); } else { $string .= gettype($call['args'][0]); } $string .= ')'; } else { // It's a function. $string .= htmlspecialchars($call['function']) . '()'; } return $string; } } PK! A6= = %system/debug/src/JoomlaHttpDriver.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug; use DebugBar\HttpDriverInterface; use Joomla\Application\WebApplicationInterface; use Joomla\CMS\Application\CMSApplicationInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla HTTP driver for DebugBar * * @since 4.1.5 */ final class JoomlaHttpDriver implements HttpDriverInterface { /** * @var CMSApplicationInterface * * @since 4.1.5 */ private $app; /** * @var array * * @since 4.1.5 */ private $dummySession = []; /** * Constructor. * * @param CMSApplicationInterface $app * * @since 4.1.5 */ public function __construct(CMSApplicationInterface $app) { $this->app = $app; } /** * Sets HTTP headers * * @param array $headers * * @since 4.1.5 */ public function setHeaders(array $headers) { if ($this->app instanceof WebApplicationInterface) { foreach ($headers as $name => $value) { $this->app->setHeader($name, $value, true); } } } /** * Checks if the session is started * * @return boolean * * @since 4.1.5 */ public function isSessionStarted() { return true; } /** * Sets a value in the session * * @param string $name * @param string $value * * @since 4.1.5 */ public function setSessionValue($name, $value) { $this->dummySession[$name] = $value; } /** * Checks if a value is in the session * * @param string $name * * @return boolean * * @since 4.1.5 */ public function hasSessionValue($name) { return array_key_exists($name, $this->dummySession); } /** * Returns a value from the session * * @param string $name * * @return mixed * * @since 4.1.5 */ public function getSessionValue($name) { return $this->dummySession[$name] ?? null; } /** * Deletes a value from the session * * @param string $name * * @since 4.1.5 */ public function deleteSessionValue($name) { unset($this->dummySession[$name]); } } PK!)iZ Z *system/debug/src/AbstractDataCollector.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug; use DebugBar\DataCollector\DataCollector; use DebugBar\DataCollector\Renderable; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * AbstractDataCollector * * @since 4.0.0 */ abstract class AbstractDataCollector extends DataCollector implements Renderable { /** * Parameters. * * @var Registry * @since 4.0.0 */ protected $params; /** * The default formatter. * * @var DataFormatter * @since 4.0.0 */ private static $defaultDataFormatter; /** * AbstractDataCollector constructor. * * @param Registry $params Parameters. * * @since 4.0.0 */ public function __construct(Registry $params) { $this->params = $params; } /** * Get a data formatter. * * @since 4.0.0 * @return DataFormatter */ public function getDataFormatter(): DataFormatter { if ($this->dataFormater === null) { $this->dataFormater = self::getDefaultDataFormatter(); } return $this->dataFormater; } /** * Returns the default data formatter * * @since 4.0.0 * @return DataFormatter */ public static function getDefaultDataFormatter(): DataFormatter { if (self::$defaultDataFormatter === null) { self::$defaultDataFormatter = new DataFormatter(); } return self::$defaultDataFormatter; } /** * Strip the Joomla! root path. * * @param string $path The path. * * @return string * * @since 4.0.0 */ public function formatPath($path): string { return $this->getDataFormatter()->formatPath($path); } /** * Format a string from back trace. * * @param array $call The array to format * * @return string * * @since 4.0.0 */ public function formatCallerInfo(array $call): string { return $this->getDataFormatter()->formatCallerInfo($call); } } PK!*\\$system/debug/src/Extension/Debug.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\Extension; use DebugBar\DataCollector\MessagesCollector; use DebugBar\DebugBar; use DebugBar\OpenHandler; use Joomla\Application\ApplicationEvents; use Joomla\CMS\Application\CMSApplicationInterface; use Joomla\CMS\Document\HtmlDocument; use Joomla\CMS\Log\Log; use Joomla\CMS\Log\LogEntry; use Joomla\CMS\Log\Logger\InMemoryLogger; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Profiler\Profiler; use Joomla\CMS\Session\Session; use Joomla\CMS\Uri\Uri; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\DatabaseInterface; use Joomla\Database\Event\ConnectionEvent; use Joomla\Event\DispatcherInterface; use Joomla\Event\Event; use Joomla\Event\Priority; use Joomla\Event\SubscriberInterface; use Joomla\Plugin\System\Debug\DataCollector\InfoCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageErrorsCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageFilesCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageStringsCollector; use Joomla\Plugin\System\Debug\DataCollector\MemoryCollector; use Joomla\Plugin\System\Debug\DataCollector\ProfileCollector; use Joomla\Plugin\System\Debug\DataCollector\QueryCollector; use Joomla\Plugin\System\Debug\DataCollector\RequestDataCollector; use Joomla\Plugin\System\Debug\DataCollector\SessionCollector; use Joomla\Plugin\System\Debug\DataCollector\UserCollector; use Joomla\Plugin\System\Debug\JavascriptRenderer; use Joomla\Plugin\System\Debug\JoomlaHttpDriver; use Joomla\Plugin\System\Debug\Storage\FileStorage; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! Debug plugin. * * @since 1.5 */ final class Debug extends CMSPlugin implements SubscriberInterface { use DatabaseAwareTrait; /** * List of protected keys that will be redacted in multiple data collected * * @since 4.2.4 */ public const PROTECTED_COLLECTOR_KEYS = "/password|passwd|pwd|secret|token|server_auth|_pass|smtppass|otpKey|otep/i"; /** * True if debug lang is on. * * @var boolean * @since 3.0 */ private $debugLang; /** * Holds log entries handled by the plugin. * * @var LogEntry[] * @since 3.1 */ private $logEntries = []; /** * Holds all SHOW PROFILE FOR QUERY n, indexed by n-1. * * @var array * @since 3.1.2 */ private $sqlShowProfileEach = []; /** * Holds all EXPLAIN EXTENDED for all queries. * * @var array * @since 3.1.2 */ private $explains = []; /** * @var DebugBar * @since 4.0.0 */ private $debugBar; /** * The query monitor. * * @var \Joomla\Database\Monitor\DebugMonitor * @since 4.0.0 */ private $queryMonitor; /** * AJAX marker * * @var bool * @since 4.0.0 */ protected $isAjax = false; /** * Whether displaying a logs is enabled * * @var bool * @since 4.0.0 */ protected $showLogs = false; /** * The time spent in onAfterDisconnect() * * @var float * @since 4.4.0 */ protected $timeInOnAfterDisconnect = 0; /** * @return array * * @since 4.1.3 */ public static function getSubscribedEvents(): array { return [ 'onBeforeCompileHead' => 'onBeforeCompileHead', 'onAjaxDebug' => 'onAjaxDebug', 'onBeforeRespond' => 'onBeforeRespond', 'onAfterRespond' => [ 'onAfterRespond', Priority::MIN, ], ApplicationEvents::AFTER_RESPOND => [ 'onAfterRespond', Priority::MIN, ], 'onAfterDisconnect' => 'onAfterDisconnect', ]; } /** * @param DispatcherInterface $dispatcher The object to observe -- event dispatcher. * @param array $config An optional associative array of configuration settings. * @param CMSApplicationInterface $app The app * @param DatabaseInterface $db The db * * @since 1.5 */ public function __construct(DispatcherInterface $dispatcher, $config, CMSApplicationInterface $app, DatabaseInterface $db) { parent::__construct($dispatcher, $config); $this->setApplication($app); $this->setDatabase($db); $this->debugLang = $this->getApplication()->get('debug_lang'); // Skip the plugin if debug is off if (!$this->debugLang && !$this->getApplication()->get('debug')) { return; } $this->getApplication()->set('gzip', false); ob_start(); ob_implicit_flush(false); /** @var \Joomla\Database\Monitor\DebugMonitor */ $this->queryMonitor = $this->getDatabase()->getMonitor(); if (!$this->params->get('queries', 1)) { // Remove the database driver monitor $this->getDatabase()->setMonitor(null); } $this->debugBar = new DebugBar(); // Check whether we want to track the request history for future use. if ($this->params->get('track_request_history', false)) { $storagePath = JPATH_CACHE . '/plg_system_debug_' . $this->getApplication()->getName(); $this->debugBar->setStorage(new FileStorage($storagePath)); } $this->debugBar->setHttpDriver(new JoomlaHttpDriver($this->getApplication())); $this->isAjax = $this->getApplication()->getInput()->get('option') === 'com_ajax' && $this->getApplication()->getInput()->get('plugin') === 'debug' && $this->getApplication()->getInput()->get('group') === 'system'; $this->showLogs = (bool) $this->params->get('logs', true); // Log deprecated class aliases if ($this->showLogs && $this->getApplication()->get('log_deprecated')) { foreach (\JLoader::getDeprecatedAliases() as $deprecation) { Log::add( sprintf( '%1$s has been aliased to %2$s and the former class name is deprecated. The alias will be removed in %3$s.', $deprecation['old'], $deprecation['new'], $deprecation['version'] ), Log::WARNING, 'deprecation-notes' ); } } } /** * Add an assets for debugger. * * @return void * * @since 4.0.0 */ public function onBeforeCompileHead() { // Only if debugging or language debug is enabled. if ((JDEBUG || $this->debugLang) && $this->isAuthorisedDisplayDebug() && $this->getApplication()->getDocument() instanceof HtmlDocument) { // Use our own jQuery and fontawesome instead of the debug bar shipped version $assetManager = $this->getApplication()->getDocument()->getWebAssetManager(); $assetManager->registerAndUseStyle( 'plg.system.debug', 'plg_system_debug/debug.css', [], [], ['fontawesome'] ); $assetManager->registerAndUseScript( 'plg.system.debug', 'plg_system_debug/debug.min.js', [], ['defer' => true], ['jquery'] ); } // Disable asset media version if needed. if (JDEBUG && (int) $this->params->get('refresh_assets', 1) === 0) { $this->getApplication()->getDocument()->setMediaVersion(''); } } /** * Show the debug info. * * @return void * * @since 1.6 */ public function onAfterRespond() { $endTime = microtime(true) - $this->timeInOnAfterDisconnect; $endMemory = memory_get_peak_usage(false); // Do not collect data if debugging or language debug is not enabled. if ((!JDEBUG && !$this->debugLang) || $this->isAjax) { return; } // User has to be authorised to see the debug information. if (!$this->isAuthorisedDisplayDebug()) { return; } // Load language. $this->loadLanguage(); $this->debugBar->addCollector(new InfoCollector($this->params, $this->debugBar->getCurrentRequestId())); $this->debugBar->addCollector(new UserCollector()); if (JDEBUG) { if ($this->params->get('memory', 1)) { $this->debugBar->addCollector(new MemoryCollector($this->params, $endMemory)); } if ($this->params->get('request', 1)) { $this->debugBar->addCollector(new RequestDataCollector()); } if ($this->params->get('session', 1)) { $this->debugBar->addCollector(new SessionCollector($this->params, true)); } if ($this->params->get('profile', 1)) { $this->debugBar->addCollector((new ProfileCollector($this->params))->setRequestEndTime($endTime)); } if ($this->params->get('queries', 1)) { // Remember session form token for possible future usage. $formToken = Session::getFormToken(); // Close session to collect possible session-related queries. $this->getApplication()->getSession()->close(); // Call $db->disconnect() here to trigger the onAfterDisconnect() method here in this class! $this->getDatabase()->disconnect(); $this->debugBar->addCollector(new QueryCollector($this->params, $this->queryMonitor, $this->sqlShowProfileEach, $this->explains)); } if ($this->showLogs) { $this->collectLogs(); } } if ($this->debugLang) { $this->debugBar->addCollector(new LanguageFilesCollector($this->params)); $this->debugBar->addCollector(new LanguageStringsCollector($this->params)); $this->debugBar->addCollector(new LanguageErrorsCollector($this->params)); } // Only render for HTML output. if (!($this->getApplication()->getDocument() instanceof HtmlDocument)) { $this->debugBar->stackData(); return; } $debugBarRenderer = new JavascriptRenderer($this->debugBar, Uri::root(true) . '/media/vendor/debugbar/'); $openHandlerUrl = Uri::base(true) . '/index.php?option=com_ajax&plugin=debug&group=system&format=raw&action=openhandler'; $openHandlerUrl .= '&' . ($formToken ?? Session::getFormToken()) . '=1'; $debugBarRenderer->setOpenHandlerUrl($openHandlerUrl); /** * @todo disable highlightjs from the DebugBar, import it through NPM * and deliver it through Joomla's API * Also every DebugBar script and stylesheet needs to use Joomla's API * $debugBarRenderer->disableVendor('highlightjs'); */ // Capture output. $contents = ob_get_contents(); if ($contents) { ob_end_clean(); } // No debug for Safari and Chrome redirection. if ( strpos($contents, 'loadResult(); if ($hasProfiling) { // Run a SHOW PROFILE query. $db->setQuery('SHOW PROFILES'); $sqlShowProfiles = $db->loadAssocList(); if ($sqlShowProfiles) { foreach ($sqlShowProfiles as $qn) { // Run SHOW PROFILE FOR QUERY for each query where a profile is available (max 100). $db->setQuery('SHOW PROFILE FOR QUERY ' . (int) $qn['Query_ID']); $this->sqlShowProfileEach[$qn['Query_ID'] - 1] = $db->loadAssocList(); } } } else { $this->sqlShowProfileEach[0] = [['Error' => 'MySql have_profiling = off']]; } } catch (\Exception $e) { $this->sqlShowProfileEach[0] = [['Error' => $e->getMessage()]]; } } if ($this->params->get('query_explains') && in_array($db->getServerType(), ['mysql', 'postgresql'], true)) { $logs = $this->queryMonitor->getLogs(); $boundParams = $this->queryMonitor->getBoundParams(); foreach ($logs as $k => $query) { $dbVersion56 = $db->getServerType() === 'mysql' && version_compare($db->getVersion(), '5.6', '>='); $dbVersion80 = $db->getServerType() === 'mysql' && version_compare($db->getVersion(), '8.0', '>='); if ($dbVersion80) { $dbVersion56 = false; } if ((stripos($query, 'select') === 0) || ($dbVersion56 && ((stripos($query, 'delete') === 0) || (stripos($query, 'update') === 0)))) { try { $queryInstance = $db->getQuery(true); $queryInstance->setQuery('EXPLAIN ' . ($dbVersion56 ? 'EXTENDED ' : '') . $query); if ($boundParams[$k]) { foreach ($boundParams[$k] as $key => $obj) { $queryInstance->bind($key, $obj->value, $obj->dataType, $obj->length, $obj->driverOptions); } } $this->explains[$k] = $db->setQuery($queryInstance)->loadAssocList(); } catch (\Exception $e) { $this->explains[$k] = [['error' => $e->getMessage()]]; } } } } $this->timeInOnAfterDisconnect = microtime(true) - $startTime; } /** * Store log messages so they can be displayed later. * This function is passed log entries by JLogLoggerCallback. * * @param LogEntry $entry A log entry. * * @return void * * @since 3.1 * * @deprecated 4.3 will be removed in 6.0 * Use \Joomla\CMS\Log\Log::add(LogEntry $entry) instead */ public function logger(LogEntry $entry) { if (!$this->showLogs) { return; } $this->logEntries[] = $entry; } /** * Collect log messages. * * @return void * * @since 4.0.0 */ private function collectLogs() { $loggerOptions = ['group' => 'default']; $logger = new InMemoryLogger($loggerOptions); $logEntries = $logger->getCollectedEntries(); if (!$this->logEntries && !$logEntries) { return; } if ($this->logEntries) { $logEntries = array_merge($logEntries, $this->logEntries); } $logDeprecated = $this->getApplication()->get('log_deprecated', 0); $logDeprecatedCore = $this->params->get('log-deprecated-core', 0); $this->debugBar->addCollector(new MessagesCollector('log')); if ($logDeprecated) { $this->debugBar->addCollector(new MessagesCollector('deprecated')); $this->debugBar->addCollector(new MessagesCollector('deprecation-notes')); } if ($logDeprecatedCore) { $this->debugBar->addCollector(new MessagesCollector('deprecated-core')); } foreach ($logEntries as $entry) { switch ($entry->category) { case 'deprecation-notes': if ($logDeprecated) { $this->debugBar[$entry->category]->addMessage($entry->message); } break; case 'deprecated': if (!$logDeprecated && !$logDeprecatedCore) { break; } $file = ''; $line = ''; // Find the caller, skip Log methods and trigger_error function foreach ($entry->callStack as $stackEntry) { if ( !empty($stackEntry['class']) && ($stackEntry['class'] === 'Joomla\CMS\Log\LogEntry' || $stackEntry['class'] === 'Joomla\CMS\Log\Log') ) { continue; } if ( empty($stackEntry['class']) && !empty($stackEntry['function']) && $stackEntry['function'] === 'trigger_error' ) { continue; } $file = $stackEntry['file'] ?? ''; $line = $stackEntry['line'] ?? ''; break; } $category = $entry->category; $relative = $file ? str_replace(JPATH_ROOT, '', $file) : ''; if ($relative && 0 === strpos($relative, '/libraries/src')) { if (!$logDeprecatedCore) { break; } $category .= '-core'; } elseif (!$logDeprecated) { break; } $message = [ 'message' => $entry->message, 'caller' => $file . ':' . $line, // @todo 'stack' => $entry->callStack; ]; $this->debugBar[$category]->addMessage($message, 'warning'); break; case 'databasequery': // Should be collected by its own collector break; default: switch ($entry->priority) { case Log::EMERGENCY: case Log::ALERT: case Log::CRITICAL: case Log::ERROR: $level = 'error'; break; case Log::WARNING: $level = 'warning'; break; default: $level = 'info'; } $this->debugBar['log']->addMessage($entry->category . ' - ' . $entry->message, $level); break; } } } /** * Add server timing headers when profile is activated. * * @return void * * @since 4.1.0 */ public function onBeforeRespond(): void { if (!JDEBUG || !$this->params->get('profile', 1)) { return; } $metrics = ''; $moduleTime = 0; $accessTime = 0; foreach (Profiler::getInstance('Application')->getMarks() as $index => $mark) { // Ignore the before mark as the after one contains the timing of the action if (stripos($mark->label, 'before') !== false) { continue; } // Collect the module render time if (strpos($mark->label, 'mod_') !== false) { $moduleTime += $mark->time; continue; } // Collect the access render time if (strpos($mark->label, 'Access:') !== false) { $accessTime += $mark->time; continue; } $desc = str_ireplace('after', '', $mark->label); $name = preg_replace('/[^\da-z]/i', '', $desc); $metrics .= sprintf('%s;dur=%f;desc="%s", ', $index . $name, $mark->time, $desc); // Do not create too large headers, some web servers don't love them if (strlen($metrics) > 3000) { $metrics .= 'System;dur=0;desc="Data truncated to 3000 characters", '; break; } } // Add the module entry $metrics .= 'Modules;dur=' . $moduleTime . ';desc="Modules", '; // Add the access entry $metrics .= 'Access;dur=' . $accessTime . ';desc="Access"'; $this->getApplication()->setHeader('Server-Timing', $metrics); } } PK!v(system/debug/src/Storage/FileStorage.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\Storage; use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\Folder; use Joomla\CMS\User\UserFactoryInterface; use Joomla\Filesystem\File; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Stores collected data into files * * @since 4.0.0 */ class FileStorage extends \DebugBar\Storage\FileStorage { /** * Saves collected data * * @param string $id The log id * @param string $data The log data * * @return void * * @since 4.0.0 */ public function save($id, $data) { if (!file_exists($this->dirname)) { Folder::create($this->dirname); } $dataStr = '#(^-^)#' . json_encode($data); File::write($this->makeFilename($id), $dataStr); } /** * Returns collected data with the specified id * * @param string $id The log id * * @return array * * @since 4.0.0 */ public function get($id) { $dataStr = file_get_contents($this->makeFilename($id)); $dataStr = str_replace('#(^-^)#', '', $dataStr); return json_decode($dataStr, true) ?: []; } /** * Returns a metadata about collected data * * @param array $filters Filtering options * @param integer $max The limit, items per page * @param integer $offset The offset * * @return array * * @since 4.0.0 */ public function find(array $filters = [], $max = 20, $offset = 0) { // Loop through all .php files and remember the modified time and id. $files = []; foreach (new \DirectoryIterator($this->dirname) as $file) { if ($file->getExtension() == 'php') { $files[] = [ 'time' => $file->getMTime(), 'id' => $file->getBasename('.php'), ]; } } // Sort the files, newest first usort( $files, function ($a, $b) { if ($a['time'] === $b['time']) { return 0; } return $a['time'] < $b['time'] ? 1 : -1; } ); // Load the metadata and filter the results. $results = []; $i = 0; foreach ($files as $file) { // When filter is empty, skip loading the offset if ($i++ < $offset && empty($filters)) { $results[] = null; continue; } $data = $this->get($file['id']); if (!$this->isSecureToReturnData($data)) { continue; } $meta = $data['__meta']; unset($data); if ($this->filter($meta, $filters)) { $results[] = $meta; } if (\count($results) >= ($max + $offset)) { break; } } return \array_slice($results, $offset, $max); } /** * Get a full path to the file * * @param string $id The log id * * @return string * * @since 4.0.0 */ public function makeFilename($id) { return $this->dirname . basename($id) . '.php'; } /** * Check if the user is allowed to view the request. Users can only see their own requests. * * @param array $data The data item to process * * @return boolean * * @since 4.2.4 */ private function isSecureToReturnData($data): bool { /** * We only started this collector in Joomla 4.2.4 - any older files we have to assume are insecure. */ if (!array_key_exists('juser', $data)) { return false; } $currentUser = Factory::getUser(); $currentUserId = $currentUser->id; $currentUserSuperAdmin = $currentUser->authorise('core.admin'); /** * Guests aren't allowed to look at other requests because there's no guarantee it's the same guest. Potentially * in the future this could be refined to check the session ID to show some requests. But it's unlikely we want * guests to be using the debug bar anyhow */ if ($currentUserId === 0) { return false; } /** @var \Joomla\CMS\User\User $user */ $user = Factory::getContainer()->get(UserFactoryInterface::class) ->loadUserById($data['juser']['user_id']); // Super users are allowed to look at other users requests. Otherwise users can only see their own requests. if ($currentUserSuperAdmin || $user->id === $currentUserId) { return true; } return false; } } PK!OQ'system/debug/src/JavascriptRenderer.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug; use DebugBar\DebugBar; use DebugBar\JavascriptRenderer as DebugBarJavascriptRenderer; use Joomla\CMS\Factory; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Custom JavascriptRenderer for DebugBar * * @since 4.0.0 */ class JavascriptRenderer extends DebugBarJavascriptRenderer { /** * Class constructor. * * @param \DebugBar\DebugBar $debugBar DebugBar instance * @param string $baseUrl The base URL from which assets will be served * @param string $basePath The path which assets are relative to * * @since 4.0.0 */ public function __construct(DebugBar $debugBar, $baseUrl = null, $basePath = null) { parent::__construct($debugBar, $baseUrl, $basePath); // Disable features that loaded by Joomla! API, or not in use $this->setEnableJqueryNoConflict(false); $this->disableVendor('jquery'); $this->disableVendor('fontawesome'); } /** * Renders the html to include needed assets * * Only useful if Assetic is not used * * @return string * * @since 4.0.0 */ public function renderHead() { list($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead) = $this->getAssets(null, self::RELATIVE_URL); $html = ''; $doc = Factory::getApplication()->getDocument(); foreach ($cssFiles as $file) { $html .= sprintf('' . "\n", $file); } foreach ($inlineCss as $content) { $html .= sprintf('' . "\n", $content); } foreach ($jsFiles as $file) { $html .= sprintf('' . "\n", $file); } $nonce = ''; if ($doc->cspNonce) { $nonce = ' nonce="' . $doc->cspNonce . '"'; } foreach ($inlineJs as $content) { $html .= sprintf('' . "\n", $nonce, $content); } foreach ($inlineHead as $content) { $html .= $content . "\n"; } return $html; } /** * Returns the code needed to display the debug bar * * AJAX request should not render the initialization code. * * @param boolean $initialize Whether or not to render the debug bar initialization code * @param boolean $renderStackedData Whether or not to render the stacked data * * @return string * * @since 4.0.0 */ public function render($initialize = true, $renderStackedData = true) { $js = ''; $doc = Factory::getApplication()->getDocument(); if ($initialize) { $js = $this->getJsInitializationCode(); } if ($renderStackedData && $this->debugBar->hasStackedData()) { foreach ($this->debugBar->getStackedData() as $id => $data) { $js .= $this->getAddDatasetCode($id, $data, '(stacked)'); } } $suffix = !$initialize ? '(ajax)' : null; $js .= $this->getAddDatasetCode($this->debugBar->getCurrentRequestId(), $this->debugBar->getData(), $suffix); $nonce = ''; if ($doc->cspNonce) { $nonce = ' nonce="' . $doc->cspNonce . '"'; } if ($this->useRequireJs) { return "\n"; } else { return "\n"; } } } PK!h/system/updatenotification/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\UpdateNotification\Extension\UpdateNotification; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new UpdateNotification( $dispatcher, (array) PluginHelper::getPlugin('system', 'updatenotification') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!C9system/updatenotification/postinstall/updatecachetime.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Table\Table; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Checks if the com_installer config for the cache Hours are eq 0 and the updatenotification Plugin is enabled * * @return boolean * * @since 3.6.3 */ function updatecachetime_postinstall_condition() { $cacheTimeout = (int) ComponentHelper::getComponent('com_installer')->params->get('cachetimeout', 6); // Check if cachetimeout is eq zero if ($cacheTimeout === 0 && PluginHelper::isEnabled('system', 'updatenotification')) { return true; } return false; } /** * Sets the cachetimeout back to the default (6 hours) * * @return void * * @since 3.6.3 */ function updatecachetime_postinstall_action() { $installer = ComponentHelper::getComponent('com_installer'); // Sets the cachetimeout back to the default (6 hours) $installer->params->set('cachetimeout', 6); // Save the new parameters back to com_installer $table = Table::getInstance('extension'); $table->load($installer->id); $table->bind(['params' => $installer->params->toString()]); // Store the changes if (!$table->store()) { // If there is an error show it to the admin Factory::getApplication()->enqueueMessage($table->getError(), 'error'); } } PK!Eo44>system/updatenotification/src/Extension/UpdateNotification.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\UpdateNotification\Extension; use Joomla\CMS\Access\Access; use Joomla\CMS\Cache\Cache; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Extension\ExtensionHelper; use Joomla\CMS\Log\Log; use Joomla\CMS\Mail\Exception\MailDisabledException; use Joomla\CMS\Mail\MailTemplate; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Table\Table; use Joomla\CMS\Updater\Updater; use Joomla\CMS\Uri\Uri; use Joomla\CMS\Version; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use PHPMailer\PHPMailer\Exception as phpMailerException; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects // Uncomment the following line to enable debug mode (update notification email sent every single time) // define('PLG_SYSTEM_UPDATENOTIFICATION_DEBUG', 1); /** * Joomla! Update Notification plugin * * Sends out an email to all Super Users or a predefined list of email addresses of Super Users when a new * Joomla! version is available. * * This plugin is a direct adaptation of the corresponding plugin in Akeeba Ltd's Admin Tools. The author has * consented to relicensing their plugin's code under GPLv2 or later (the original version was licensed under * GPLv3 or later) to allow its inclusion in the Joomla! CMS. * * @since 3.5 */ final class UpdateNotification extends CMSPlugin { use DatabaseAwareTrait; /** * Load plugin language files automatically * * @var boolean * @since 3.6.3 */ protected $autoloadLanguage = true; /** * The update check and notification email code is triggered after the page has fully rendered. * * @return void * * @since 3.5 */ public function onAfterRender() { // Get the timeout for Joomla! updates, as configured in com_installer's component parameters $component = ComponentHelper::getComponent('com_installer'); /** @var \Joomla\Registry\Registry $params */ $params = $component->getParams(); $cache_timeout = (int) $params->get('cachetimeout', 6); $cache_timeout = 3600 * $cache_timeout; // Do we need to run? Compare the last run timestamp stored in the plugin's options with the current // timestamp. If the difference is greater than the cache timeout we shall not execute again. $now = time(); $last = (int) $this->params->get('lastrun', 0); if (!defined('PLG_SYSTEM_UPDATENOTIFICATION_DEBUG') && (abs($now - $last) < $cache_timeout)) { return; } // Update last run status // If I have the time of the last run, I can update, otherwise insert $this->params->set('lastrun', $now); $db = $this->getDatabase(); $paramsJson = $this->params->toString('JSON'); $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) ->set($db->quoteName('params') . ' = :params') ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) ->where($db->quoteName('element') . ' = ' . $db->quote('updatenotification')) ->bind(':params', $paramsJson); try { // Lock the tables to prevent multiple plugin executions causing a race condition $db->lockTable('#__extensions'); } catch (\Exception $e) { // If we can't lock the tables it's too risky to continue execution return; } try { // Update the plugin parameters $result = $db->setQuery($query)->execute(); $this->clearCacheGroups(['com_plugins']); } catch (\Exception $exc) { // If we failed to execute $db->unlockTables(); $result = false; } try { // Unlock the tables after writing $db->unlockTables(); } catch (\Exception $e) { // If we can't lock the tables assume we have somehow failed $result = false; } // Stop on failure if (!$result) { return; } // This is the extension ID for Joomla! itself $eid = ExtensionHelper::getExtensionRecord('joomla', 'file')->extension_id; // Get any available updates $updater = Updater::getInstance(); $results = $updater->findUpdates([$eid], $cache_timeout); // If there are no updates our job is done. We need BOTH this check AND the one below. if (!$results) { return; } // Get the update model and retrieve the Joomla! core updates $model = $this->getApplication()->bootComponent('com_installer') ->getMVCFactory()->createModel('Update', 'Administrator', ['ignore_request' => true]); $model->setState('filter.extension_id', $eid); $updates = $model->getItems(); // If there are no updates we don't have to notify anyone about anything. This is NOT a duplicate check. if (empty($updates)) { return; } // Get the available update $update = array_pop($updates); // Check the available version. If it's the same or less than the installed version we have no updates to notify about. if (version_compare($update->version, JVERSION, 'le')) { return; } // If we're here, we have updates. First, get a link to the Joomla! Update component. $baseURL = Uri::base(); $baseURL = rtrim($baseURL, '/'); $baseURL .= (substr($baseURL, -13) !== 'administrator') ? '/administrator/' : '/'; $baseURL .= 'index.php?option=com_joomlaupdate'; $uri = new Uri($baseURL); /** * Some third party security solutions require a secret query parameter to allow log in to the administrator * backend of the site. The link generated above will be invalid and could probably block the user out of their * site, confusing them (they can't understand the third party security solution is not part of Joomla! proper). * So, we're calling the onBuildAdministratorLoginURL system plugin event to let these third party solutions * add any necessary secret query parameters to the URL. The plugins are supposed to have a method with the * signature: * * public function onBuildAdministratorLoginURL(Uri &$uri); * * The plugins should modify the $uri object directly and return null. */ $this->getApplication()->triggerEvent('onBuildAdministratorLoginURL', [&$uri]); // Let's find out the email addresses to notify $superUsers = []; $specificEmail = $this->params->get('email', ''); if (!empty($specificEmail)) { $superUsers = $this->getSuperUsers($specificEmail); } if (empty($superUsers)) { $superUsers = $this->getSuperUsers(); } if (empty($superUsers)) { return; } /* * Load the appropriate language. We try to load English (UK), the current user's language and the forced * language preference, in this order. This ensures that we'll never end up with untranslated strings in the * update email which would make Joomla! seem bad. So, please, if you don't fully understand what the * following code does DO NOT TOUCH IT. It makes the difference between a hobbyist CMS and a professional * solution! */ $jLanguage = $this->getApplication()->getLanguage(); $jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, 'en-GB', true, true); $jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, null, true, false); // Then try loading the preferred (forced) language $forcedLanguage = $this->params->get('language_override', ''); if (!empty($forcedLanguage)) { $jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, $forcedLanguage, true, false); } // Replace merge codes with their values $newVersion = $update->version; $jVersion = new Version(); $currentVersion = $jVersion->getShortVersion(); $sitename = $this->getApplication()->get('sitename'); $substitutions = [ 'newversion' => $newVersion, 'curversion' => $currentVersion, 'sitename' => $sitename, 'url' => Uri::base(), 'link' => $uri->toString(), 'releasenews' => 'https://www.joomla.org/announcements/release-news/', ]; // Send the emails to the Super Users foreach ($superUsers as $superUser) { try { $mailer = new MailTemplate('plg_system_updatenotification.mail', $jLanguage->getTag()); $mailer->addRecipient($superUser->email); $mailer->addTemplateData($substitutions); $mailer->send(); } catch (MailDisabledException | phpMailerException $exception) { try { Log::add($this->getApplication()->getLanguage()->_($exception->getMessage()), Log::WARNING, 'jerror'); } catch (\RuntimeException $exception) { $this->getApplication()->enqueueMessage($this->getApplication()->getLanguage()->_($exception->errorMessage()), 'warning'); } } } } /** * Returns the Super Users email information. If you provide a comma separated $email list * we will check that these emails do belong to Super Users and that they have not blocked * system emails. * * @param null|string $email A list of Super Users to email * * @return array The list of Super User emails * * @since 3.5 */ private function getSuperUsers($email = null) { $db = $this->getDatabase(); $emails = []; // Convert the email list to an array if (!empty($email)) { $temp = explode(',', $email); foreach ($temp as $entry) { $emails[] = trim($entry); } $emails = array_unique($emails); } // Get a list of groups which have Super User privileges $ret = []; try { $rootId = Table::getInstance('Asset')->getRootId(); $rules = Access::getAssetRules($rootId)->getData(); $rawGroups = $rules['core.admin']->getData(); $groups = []; if (empty($rawGroups)) { return $ret; } foreach ($rawGroups as $g => $enabled) { if ($enabled) { $groups[] = $g; } } if (empty($groups)) { return $ret; } } catch (\Exception $exc) { return $ret; } // Get the user IDs of users belonging to the SA groups try { $query = $db->getQuery(true) ->select($db->quoteName('user_id')) ->from($db->quoteName('#__user_usergroup_map')) ->whereIn($db->quoteName('group_id'), $groups); $db->setQuery($query); $userIDs = $db->loadColumn(0); if (empty($userIDs)) { return $ret; } } catch (\Exception $exc) { return $ret; } // Get the user information for the Super Administrator users try { $query = $db->getQuery(true) ->select($db->quoteName(['id', 'username', 'email'])) ->from($db->quoteName('#__users')) ->whereIn($db->quoteName('id'), $userIDs) ->where($db->quoteName('block') . ' = 0') ->where($db->quoteName('sendEmail') . ' = 1'); if (!empty($emails)) { $lowerCaseEmails = array_map('strtolower', $emails); $query->whereIn('LOWER(' . $db->quoteName('email') . ')', $lowerCaseEmails, ParameterType::STRING); } $db->setQuery($query); $ret = $db->loadObjectList(); } catch (\Exception $exc) { return $ret; } return $ret; } /** * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. * * @param array $clearGroups The cache groups to clean * * @return void * * @since 3.5 */ private function clearCacheGroups(array $clearGroups) { foreach ($clearGroups as $group) { try { $options = [ 'defaultgroup' => $group, 'cachebase' => $this->getApplication()->get('cache_path', JPATH_CACHE), ]; $cache = Cache::getInstance('callback', $options); $cache->clean(); } catch (\Exception $e) { // Ignore it } } } } PK!)0system/updatenotification/updatenotification.xmlnu[ plg_system_updatenotification Joomla! Project 2015-05 (C) 2015 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.5.0 PLG_SYSTEM_UPDATENOTIFICATION_XML_DESCRIPTION Joomla\Plugin\System\UpdateNotification postinstall services src language/en-GB/plg_system_updatenotification.ini language/en-GB/plg_system_updatenotification.sys.ini
PK!._"_" system/jchatlogin/jchatlogin.phpnu[appInstance->getDocument (); // Output JS APP nel Document if($doc->getType() !== 'html' || $this->appInstance->getInput()->getCmd ( 'tmpl' ) === 'component') { return false; } $user = $this->appInstance->getIdentity(); if(!$user->id && !$cParams->get('guestenabled', false)) { return false; } // Check access levels intersection to ensure that users has access usage permission for chat // Get users access levels based on user groups belonging $userAccessLevels = $user->getAuthorisedViewLevels(); // Get chat access level from configuration, if set AKA param != array(0) go on with intersection $chatAccessLevels = $cParams->get('chat_accesslevels', array(0)); if(is_array($chatAccessLevels) && !in_array(0, $chatAccessLevels, false)) { $intersectResult = array_intersect($userAccessLevels, $chatAccessLevels); $hasChatAccess = (bool)(count($intersectResult)); // Return if user has no access if(!$hasChatAccess) { return false; } } // Check for IP multiple ranges exclusions if($cParams->get ( 'ipbanning', false)) { $ipAddressRegex = '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/i'; $clientIP = $_SERVER ['REMOTE_ADDR']; $clientIpDec = ( float ) sprintf ( "%u", ip2long ( $clientIP ) ); $ipRanges = $cParams->get ( 'iprange_multiple', null); // Check if data are not null if($ipRanges) { // Try to load every range, one per row $explodeRows = explode(PHP_EOL, $ipRanges); if(!empty($explodeRows)) { foreach ($explodeRows as $singleRange) { // Try to detect single range $explodeRange = explode('-', $singleRange); if(!empty($explodeRange) && count($explodeRange) == 2) { $ipStart = trim($explodeRange[0]); $ipEnd = trim($explodeRange[1]); $validIpRangeStart = preg_match ( $ipAddressRegex, $ipStart ); $validIpRangeEnd = preg_match ( $ipAddressRegex, $ipEnd ); if ($validIpRangeStart && $validIpRangeEnd) { $lowerIpDec = ( float ) sprintf ( "%u", ip2long ( $ipStart ) ); $upperIpDec = ( float ) sprintf ( "%u", ip2long ( $ipEnd ) ); if (($clientIpDec >= $lowerIpDec) && ($clientIpDec <= $upperIpDec)) { return false; } } } } } } } // Check for hours activation $startHour = $cParams->get('start_at_hour', null); $stopHour = $cParams->get('stop_at_hour', null); if($startHour && $stopHour) { $jTimeZone = Factory::getApplication()->getConfig ()->get ( 'offset' ); $dateObject = Factory::getDate(); $dateObject->setTimezone(new \DateTimeZone($jTimeZone)); $currentHour = $dateObject->format('G', true); if($currentHour < $startHour || $currentHour >= $stopHour) { return false; } } // Check for day of the week activation $daysOfTheWeek = $cParams->get('days_of_the_week', null); if(is_array($daysOfTheWeek) && count($daysOfTheWeek) && !in_array('', $daysOfTheWeek, true)) { $jTimeZone = Factory::getApplication()->getConfig ()->get ( 'offset' ); $dateObject = Factory::getDate(); $dateObject->setTimezone(new \DateTimeZone($jTimeZone)); $currentDay = $dateObject->format('w', true); if(!in_array($currentDay, $daysOfTheWeek)) { return false; } } return true; } /** * onAfterDispatch handler * * @param Event $event * @access public * @return null */ public function chatSocialLoginConnector(Event $event) { if($this->appInstance->isClient ('site') && $this->checkIfValidExecution($this->cParams)) { // Load framework classes without autoloading require_once JPATH_ROOT . '/administrator/components/com_jchat/Framework/Helpers/Users.php'; // Manage partial language translations $jLang = $this->appInstance->getLanguage(); $jLang->load('com_jchat', JPATH_SITE . '/components/com_jchat', 'en-GB', true, true); if($jLang->getTag() != 'en-GB') { $jLang->load('com_jchat', JPATH_SITE, null, true, false); $jLang->load('com_jchat', JPATH_SITE . '/components/com_jchat', null, true, false); } // Check and include if Facebook social login is enabled if($this->cParams->get('fblogin_active', 0)) { // Inject the FB app id in the js domain $doc = $this->appInstance->getDocument(); $appId = $this->cParams->get('appId', ''); $locale = $this->appInstance->getLanguage ()->getTag(); $sdkLangTag = str_replace("-", "_", $locale); $sdkVersion = $this->cParams->get ( 'sdkversion', '6.0' ); $doc->getWebAssetManager()->addInlineScript ("var jchatAppId = '$appId';" . "var jchatSdkVersion = 'v$sdkVersion';" . "jQuery(function(){jQuery('
').appendTo('body')});" ); switch ((int)$this->cParams->get ( 'sdkloadmode', '2' )) { // Override load mode case 2 : $doc->getWebAssetManager()->addInlineScript ( "(function(d){var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];js = d.createElement('script');js.id = id;js.async = true;js.src = '//connect.facebook.net/$sdkLangTag/sdk.js#xfbml=1&version=v$sdkVersion&appId=$appId';ref.parentNode.insertBefore(js, ref);}(document));" ); break; // No override load mode case 1 : $doc->getWebAssetManager()->addInlineScript ( "(function(d) {var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];if (d.getElementById(id)){return;}js = d.createElement('script');js.id = id;js.async = true;js.src = '//connect.facebook.net/$sdkLangTag/sdk.js#xfbml=1&version=v$sdkVersion&appId=$appId';ref.parentNode.insertBefore(js, ref);}(document));" ); break; // Load nothing case 0 : break; } // Include the Facebook connector class require_once JPATH_ROOT . '/plugins/system/jchatlogin/connectors/connector.php'; require_once JPATH_ROOT . '/plugins/system/jchatlogin/connectors/facebook.php'; $fbConnector = new \JChatLoginConnectorFacebook($this->cParams); $fbConnector->execute(); } // Check and include if G+ social login is enabled if($this->cParams->get('gpluslogin_active', 0)) { // Include the Facebook connector class require_once JPATH_ROOT . '/plugins/system/jchatlogin/connectors/connector.php'; require_once JPATH_ROOT . '/plugins/system/jchatlogin/connectors/google.php'; $gplusConnector = new \JChatLoginConnectorGoogle($this->cParams); $gplusConnector->execute(); } // Check and include if Twitter social login is enabled // Check and include if G+ social login is enabled if($this->cParams->get('twitterlogin_active', 0)) { // Include the Facebook connector class require_once JPATH_ROOT . '/plugins/system/jchatlogin/connectors/connector.php'; require_once JPATH_ROOT . '/plugins/system/jchatlogin/connectors/twitter.php'; $twitterConnector = new \JChatLoginConnectorTwitter($this->cParams); $twitterConnector->execute(); } } } /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.0.0 */ public static function getSubscribedEvents(): array { return [ 'onAfterDispatch' => 'chatSocialLoginConnector' ]; } /** * Class Constructor * * @access protected * @param object $subject * object to observe * @param array $config * An array that holds the plugin configuration * @since 1.6 */ public function __construct(& $subject, $config = array()) { parent::__construct ( $subject, $config ); // Init application $this->appInstance = Factory::getApplication(); $this->cParams = ComponentHelper::getParams ( 'com_jchat' ); } } PK!|r;||*system/jchatlogin/social/twitter/login.phpnu[http_status; } function lastAPICall() { return $this->last_api_call; } /** * construct TwitterOAuth object */ function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) { $this->sha1_method = new OAuth\OAuthSignatureMethod_HMAC_SHA1(); $this->consumer = new OAuth\OAuthConsumer($consumer_key, $consumer_secret); if (!empty($oauth_token) && !empty($oauth_token_secret)) { $this->token = new OAuth\OAuthConsumer($oauth_token, $oauth_token_secret); } else { $this->token = NULL; } } /** * Get a request_token from Twitter * * @returns a key/value array containing oauth_token and oauth_token_secret */ function getRequestToken($oauth_callback = null) { $parameters = array(); $parameters['oauth_callback'] = $oauth_callback; $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters); $token = OAuth\OAuthUtil::parse_parameters($request); $this->token = @new OAuth\OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); return $token; } /** * Get the authorize URL * * @returns a string */ function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) { if (is_array($token)) { $token = $token['oauth_token']; } if (empty($sign_in_with_twitter)) { return $this->authorizeURL() . "?oauth_token={$token}"; } else { return $this->authenticateURL() . "?oauth_token={$token}"; } } /** * Exchange request token and secret for an access token and * secret, to sign API calls. * * @returns array("oauth_token" => "the-access-token", * "oauth_token_secret" => "the-access-secret", * "user_id" => "9436992", * "screen_name" => "abraham") */ function getAccessToken($oauth_verifier) { $parameters = array(); $parameters['oauth_verifier'] = $oauth_verifier; $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters); $token = OAuth\OAuthUtil::parse_parameters($request); if(isset($token['oauth_token'])) { $this->token = new OAuth\OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); } return $token; } /** * One time exchange of username and password for access token and secret. * * @returns array("oauth_token" => "the-access-token", * "oauth_token_secret" => "the-access-secret", * "user_id" => "9436992", * "screen_name" => "abraham", * "x_auth_expires" => "0") */ function getXAuthToken($username, $password) { $parameters = array(); $parameters['x_auth_username'] = $username; $parameters['x_auth_password'] = $password; $parameters['x_auth_mode'] = 'client_auth'; $request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters); $token = OAuth\OAuthUtil::parse_parameters($request); $this->token = new OAuth\OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); return $token; } /** * GET wrapper for oAuthRequest. */ function get($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'GET', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * POST wrapper for oAuthRequest. */ function post($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'POST', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * DELETE wrapper for oAuthReqeust. */ function delete($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'DELETE', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * Format and sign an OAuth / API request */ function oAuthRequest($url, $method, $parameters) { if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) { $url = "{$this->host}{$url}.{$this->format}"; } $request = OAuth\OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters); $request->sign_request($this->sha1_method, $this->consumer, $this->token); switch ($method) { case 'GET': return $this->http($request->to_url(), 'GET'); default: return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata()); } } /** * Make an HTTP request * * @return API results */ function http($url, $method, $postfields = NULL) { $this->http_info = array(); $ci = curl_init(); /* Curl settings */ curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader')); curl_setopt($ci, CURLOPT_HEADER, FALSE); switch ($method) { case 'POST': curl_setopt($ci, CURLOPT_POST, TRUE); if (!empty($postfields)) { curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); } break; case 'DELETE': curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); if (!empty($postfields)) { $url = "{$url}?{$postfields}"; } } curl_setopt($ci, CURLOPT_URL, $url); $response = curl_exec($ci); $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); $this->url = $url; curl_close ($ci); return $response; } /** * Get the header info to store. */ function getHeader($ch, $header) { $i = strpos($header, ':'); if (!empty($i)) { $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); $value = trim(substr($header, $i + 2)); $this->http_header[$key] = $value; } return strlen($header); } } PK!$>iiii*system/jchatlogin/social/twitter/OAuth.phpnu[key = $key; $this->secret = $secret; $this->callback_url = $callback_url; } function __toString() { return "OAuthConsumer[key=$this->key,secret=$this->secret]"; } } class OAuthToken { // access tokens and request tokens public $key; public $secret; /** * key = the token * secret = the token secret */ function __construct($key, $secret) { $this->key = $key; $this->secret = $secret; } /** * generates the basic string serialization of a token that a server * would respond to request_token and access_token calls with */ function to_string() { return "oauth_token=" . OAuthUtil::urlencode_rfc3986($this->key) . "&oauth_token_secret=" . OAuthUtil::urlencode_rfc3986($this->secret); } function __toString() { return $this->to_string(); } } /** * A class for implementing a Signature Method * See section 9 ("Signing Requests") in the spec */ abstract class OAuthSignatureMethod { /** * Needs to return the name of the Signature Method (ie HMAC-SHA1) * @return string */ abstract public function get_name(); /** * Build up the signature * NOTE: The output of this function MUST NOT be urlencoded. * the encoding is handled in OAuthRequest when the final * request is serialized * @param OAuthRequest $request * @param OAuthConsumer $consumer * @param OAuthToken $token * @return string */ abstract public function build_signature($request, $consumer, $token); /** * Verifies that a given signature is correct * @param OAuthRequest $request * @param OAuthConsumer $consumer * @param OAuthToken $token * @param string $signature * @return bool */ public function check_signature($request, $consumer, $token, $signature) { $built = $this->build_signature($request, $consumer, $token); return $built == $signature; } } /** * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] * where the Signature Base String is the text and the key is the concatenated values (each first * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&' * character (ASCII code 38) even if empty. * - Chapter 9.2 ("HMAC-SHA1") */ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod { function get_name() { return "HMAC-SHA1"; } public function build_signature($request, $consumer, $token) { $base_string = $request->get_signature_base_string(); $request->base_string = $base_string; $key_parts = array( $consumer->secret, ($token) ? $token->secret : "" ); $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); $key = implode('&', $key_parts); $bas64FunctionNameEncode = 'base'. 64 . '_encode'; return $bas64FunctionNameEncode(hash_hmac('sha1', $base_string, $key, true)); } } /** * The PLAINTEXT method does not provide any security protection and SHOULD only be used * over a secure channel such as HTTPS. It does not use the Signature Base String. * - Chapter 9.4 ("PLAINTEXT") */ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod { public function get_name() { return "PLAINTEXT"; } /** * oauth_signature is set to the concatenated encoded values of the Consumer Secret and * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is * empty. The result MUST be encoded again. * - Chapter 9.4.1 ("Generating Signatures") * * Please note that the second encoding MUST NOT happen in the SignatureMethod, as * OAuthRequest handles this! */ public function build_signature($request, $consumer, $token) { $key_parts = array( $consumer->secret, ($token) ? $token->secret : "" ); $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); $key = implode('&', $key_parts); $request->base_string = $key; return $key; } } /** * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a * verified way to the Service Provider, in a manner which is beyond the scope of this * specification. * - Chapter 9.3 ("RSA-SHA1") */ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod { public function get_name() { return "RSA-SHA1"; } // Up to the SP to implement this lookup of keys. Possible ideas are: // (1) do a lookup in a table of trusted certs keyed off of consumer // (2) fetch via http using a url provided by the requester // (3) some sort of specific discovery code based on request // // Either way should return a string representation of the certificate protected abstract function fetch_public_cert(&$request); // Up to the SP to implement this lookup of keys. Possible ideas are: // (1) do a lookup in a table of trusted certs keyed off of consumer // // Either way should return a string representation of the certificate protected abstract function fetch_private_cert(&$request); public function build_signature($request, $consumer, $token) { $base_string = $request->get_signature_base_string(); $request->base_string = $base_string; // Fetch the private key cert based on the request $cert = $this->fetch_private_cert($request); // Pull the private key ID from the certificate $privatekeyid = openssl_get_privatekey($cert); // Sign using the key $ok = openssl_sign($base_string, $signature, $privatekeyid); // Release the key resource openssl_free_key($privatekeyid); $bas64FunctionNameEncode = 'base'. 64 . '_encode'; return $bas64FunctionNameEncode($signature); } public function check_signature($request, $consumer, $token, $signature) { $bas64FunctionNameDecode = 'base'. 64 . '_decode'; $decoded_sig = $bas64FunctionNameDecode($signature); $base_string = $request->get_signature_base_string(); // Fetch the public key cert based on the request $cert = $this->fetch_public_cert($request); // Pull the public key ID from the certificate $publickeyid = openssl_get_publickey($cert); // Check the computed signature against the one passed in the query $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); // Release the key resource openssl_free_key($publickeyid); return $ok == 1; } } class OAuthRequest { private $parameters; private $http_method; private $http_url; // for debug purposes public $base_string; public static $version = '1.0'; public static $POST_INPUT = 'php://input'; function __construct($http_method, $http_url, $parameters=NULL) { @$parameters or $parameters = array(); $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); $this->parameters = $parameters; $this->http_method = $http_method; $this->http_url = $http_url; } /** * attempt to build up a request from what was passed to the server */ public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) { $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https'; @$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI']; @$http_method or $http_method = $_SERVER['REQUEST_METHOD']; // We weren't handed any parameters, so let's find the ones relevant to // this request. // If you run XML-RPC or similar you should use this to provide your own // parsed parameter-list if (!$parameters) { // Find request headers $request_headers = OAuthUtil::get_headers(); // Parse the query-string to find GET parameters $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); // It's a POST request of the proper content-type, so parse POST // parameters and add those overriding any duplicates from GET if ($http_method == "POST" && @strstr($request_headers["Content-Type"], "application/x-www-form-urlencoded") ) { $post_data = OAuthUtil::parse_parameters( file_get_contents(self::$POST_INPUT) ); $parameters = array_merge($parameters, $post_data); } // We have a Authorization-header with OAuth data. Parse the header // and add those overriding any duplicates from GET or POST if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") { $header_parameters = OAuthUtil::split_header( $request_headers['Authorization'] ); $parameters = array_merge($parameters, $header_parameters); } } return new OAuthRequest($http_method, $http_url, $parameters); } /** * pretty much a helper function to set up the request */ public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) { @$parameters or $parameters = array(); $defaults = array("oauth_version" => OAuthRequest::$version, "oauth_nonce" => OAuthRequest::generate_nonce(), "oauth_timestamp" => OAuthRequest::generate_timestamp(), "oauth_consumer_key" => $consumer->key); if ($token) $defaults['oauth_token'] = $token->key; $parameters = array_merge($defaults, $parameters); return new OAuthRequest($http_method, $http_url, $parameters); } public function set_parameter($name, $value, $allow_duplicates = true) { if ($allow_duplicates && isset($this->parameters[$name])) { // We have already added parameter(s) with this name, so add to the list if (is_scalar($this->parameters[$name])) { // This is the first duplicate, so transform scalar (string) // into an array so we can add the duplicates $this->parameters[$name] = array($this->parameters[$name]); } $this->parameters[$name][] = $value; } else { $this->parameters[$name] = $value; } } public function get_parameter($name) { return isset($this->parameters[$name]) ? $this->parameters[$name] : null; } public function get_parameters() { return $this->parameters; } public function unset_parameter($name) { unset($this->parameters[$name]); } /** * The request parameters, sorted and concatenated into a normalized string. * @return string */ public function get_signable_parameters() { // Grab all parameters $params = $this->parameters; // Remove oauth_signature if present // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") if (isset($params['oauth_signature'])) { unset($params['oauth_signature']); } return OAuthUtil::build_http_query($params); } /** * Returns the base string of this request * * The base string defined as the method, the url * and the parameters (normalized), each urlencoded * and the concated with &. */ public function get_signature_base_string() { $parts = array( $this->get_normalized_http_method(), $this->get_normalized_http_url(), $this->get_signable_parameters() ); $parts = OAuthUtil::urlencode_rfc3986($parts); return implode('&', $parts); } /** * just uppercases the http method */ public function get_normalized_http_method() { return strtoupper($this->http_method); } /** * parses the url and rebuilds it to be * scheme://host/path */ public function get_normalized_http_url() { $parts = parse_url($this->http_url); $port = @$parts['port']; $scheme = $parts['scheme']; $host = $parts['host']; $path = @$parts['path']; $port or $port = ($scheme == 'https') ? '443' : '80'; if (($scheme == 'https' && $port != '443') || ($scheme == 'http' && $port != '80')) { $host = "$host:$port"; } return "$scheme://$host$path"; } /** * builds a url usable for a GET request */ public function to_url() { $post_data = $this->to_postdata(); $out = $this->get_normalized_http_url(); if ($post_data) { $out .= '?'.$post_data; } return $out; } /** * builds the data one would send in a POST request */ public function to_postdata() { return OAuthUtil::build_http_query($this->parameters); } /** * builds the Authorization: header */ public function to_header($realm=null) { $first = true; if($realm) { $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"'; $first = false; } else $out = 'Authorization: OAuth'; $total = array(); foreach ($this->parameters as $k => $v) { if (substr($k, 0, 5) != "oauth") continue; if (is_array($v)) { throw new OAuthException('Arrays not supported in headers'); } $out .= ($first) ? ' ' : ','; $out .= OAuthUtil::urlencode_rfc3986($k) . '="' . OAuthUtil::urlencode_rfc3986($v) . '"'; $first = false; } return $out; } public function __toString() { return $this->to_url(); } public function sign_request($signature_method, $consumer, $token) { $this->set_parameter( "oauth_signature_method", $signature_method->get_name(), false ); $signature = $this->build_signature($signature_method, $consumer, $token); $this->set_parameter("oauth_signature", $signature, false); } public function build_signature($signature_method, $consumer, $token) { $signature = $signature_method->build_signature($this, $consumer, $token); return $signature; } /** * util function: current timestamp */ private static function generate_timestamp() { return time(); } /** * util function: current nonce */ private static function generate_nonce() { $mt = microtime(); $rand = mt_rand(); return md5($mt . $rand); // md5s look nicer than numbers } } class OAuthServer { protected $timestamp_threshold = 300; // in seconds, five minutes protected $version = '1.0'; // hi blaine protected $signature_methods = array(); protected $data_store; function __construct($data_store) { $this->data_store = $data_store; } public function add_signature_method($signature_method) { $this->signature_methods[$signature_method->get_name()] = $signature_method; } // high level functions /** * process a request_token request * returns the request token on success */ public function fetch_request_token(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); // no token required for the initial token request $token = NULL; $this->check_signature($request, $consumer, $token); // Rev A change $callback = $request->get_parameter('oauth_callback'); $new_token = $this->data_store->new_request_token($consumer, $callback); return $new_token; } /** * process an access_token request * returns the access token on success */ public function fetch_access_token(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); // requires authorized request token $token = $this->get_token($request, $consumer, "request"); $this->check_signature($request, $consumer, $token); // Rev A change $verifier = $request->get_parameter('oauth_verifier'); $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); return $new_token; } /** * verify an api call, checks all the parameters */ public function verify_request(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); $token = $this->get_token($request, $consumer, "access"); $this->check_signature($request, $consumer, $token); return array($consumer, $token); } // Internals from here /** * version 1 */ private function get_version(&$request) { $version = $request->get_parameter("oauth_version"); if (!$version) { // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. // Chapter 7.0 ("Accessing Protected Ressources") $version = '1.0'; } if ($version !== $this->version) { throw new OAuthException("OAuth version '$version' not supported"); } return $version; } /** * figure out the signature with some defaults */ private function get_signature_method(&$request) { $signature_method = @$request->get_parameter("oauth_signature_method"); if (!$signature_method) { // According to chapter 7 ("Accessing Protected Ressources") the signature-method // parameter is required, and we can't just fallback to PLAINTEXT throw new OAuthException('No signature method parameter. This parameter is required'); } if (!in_array($signature_method, array_keys($this->signature_methods))) { throw new OAuthException( "Signature method '$signature_method' not supported " . "try one of the following: " . implode(", ", array_keys($this->signature_methods)) ); } return $this->signature_methods[$signature_method]; } /** * try to find the consumer for the provided request's consumer key */ private function get_consumer(&$request) { $consumer_key = @$request->get_parameter("oauth_consumer_key"); if (!$consumer_key) { throw new OAuthException("Invalid consumer key"); } $consumer = $this->data_store->lookup_consumer($consumer_key); if (!$consumer) { throw new OAuthException("Invalid consumer"); } return $consumer; } /** * try to find the token for the provided request's token key */ private function get_token(&$request, $consumer, $token_type="access") { $token_field = @$request->get_parameter('oauth_token'); $token = $this->data_store->lookup_token( $consumer, $token_type, $token_field ); if (!$token) { throw new OAuthException("Invalid $token_type token: $token_field"); } return $token; } /** * all-in-one function to check the signature on a request * should guess the signature method appropriately */ private function check_signature(&$request, $consumer, $token) { // this should probably be in a different method $timestamp = @$request->get_parameter('oauth_timestamp'); $nonce = @$request->get_parameter('oauth_nonce'); $this->check_timestamp($timestamp); $this->check_nonce($consumer, $token, $nonce, $timestamp); $signature_method = $this->get_signature_method($request); $signature = $request->get_parameter('oauth_signature'); $valid_sig = $signature_method->check_signature( $request, $consumer, $token, $signature ); if (!$valid_sig) { throw new OAuthException("Invalid signature"); } } /** * check that the timestamp is new enough */ private function check_timestamp($timestamp) { if( ! $timestamp ) throw new OAuthException( 'Missing timestamp parameter. The parameter is required' ); // verify that timestamp is recentish $now = time(); if (abs($now - $timestamp) > $this->timestamp_threshold) { throw new OAuthException( "Expired timestamp, yours $timestamp, ours $now" ); } } /** * check that the nonce is not repeated */ private function check_nonce($consumer, $token, $nonce, $timestamp) { if( ! $nonce ) throw new OAuthException( 'Missing nonce parameter. The parameter is required' ); // verify that the nonce is uniqueish $found = $this->data_store->lookup_nonce( $consumer, $token, $nonce, $timestamp ); if ($found) { throw new OAuthException("Nonce already used: $nonce"); } } } class OAuthDataStore { function lookup_consumer($consumer_key) { // implement me } function lookup_token($consumer, $token_type, $token) { // implement me } function lookup_nonce($consumer, $token, $nonce, $timestamp) { // implement me } function new_request_token($consumer, $callback = null) { // return a new token attached to this consumer } function new_access_token($token, $consumer, $verifier = null) { // return a new access token attached to this consumer // for the user associated with this token if the request token // is authorized // should also invalidate the request token } } class OAuthUtil { public static function urlencode_rfc3986($input) { if (is_array($input)) { return array_map(array('JChat\Twitter\OAuth\OAuthUtil', 'urlencode_rfc3986'), $input); } else if (is_scalar($input)) { return str_replace( '+', ' ', str_replace('%7E', '~', rawurlencode($input)) ); } else { return ''; } } // This decode function isn't taking into consideration the above // modifications to the encoding process. However, this method doesn't // seem to be used anywhere so leaving it as is. public static function urldecode_rfc3986($string) { return urldecode($string); } // Utility function for turning the Authorization: header into // parameters, has to do some unescaping // Can filter out any non-oauth parameters if needed (default behaviour) public static function split_header($header, $only_allow_oauth_parameters = true) { $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/'; $offset = 0; $params = array(); while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) { $match = $matches[0]; $header_name = $matches[2][0]; $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0]; if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) { $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content); } $offset = $match[1] + strlen($match[0]); } if (isset($params['realm'])) { unset($params['realm']); } return $params; } // helper to try to sort out headers for people who aren't running apache public static function get_headers() { if (function_exists('apache_request_headers')) { // we need this to get the actual Authorization: header // because apache tends to tell us it doesn't exist $headers = apache_request_headers(); // sanitize the output of apache_request_headers because // we always want the keys to be Cased-Like-This and arh() // returns the headers in the same case as they are in the // request $out = array(); foreach( $headers AS $key => $value ) { $key = str_replace( " ", "-", ucwords(strtolower(str_replace("-", " ", $key))) ); $out[$key] = $value; } } else { // otherwise we don't have apache and are just going to have to hope // that $_SERVER actually contains what we need $out = array(); if( isset($_SERVER['CONTENT_TYPE']) ) $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; if( isset($_ENV['CONTENT_TYPE']) ) $out['Content-Type'] = $_ENV['CONTENT_TYPE']; foreach ($_SERVER as $key => $value) { if (substr($key, 0, 5) == "HTTP_") { // this is chaos, basically it is just there to capitalize the first // letter of every word that is not an initial HTTP and strip HTTP // code from przemek $key = str_replace( " ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) ); $out[$key] = $value; } } } return $out; } // This function takes a input like a=b&a=c&d=e and returns the parsed // parameters like this // array('a' => array('b','c'), 'd' => 'e') public static function parse_parameters( $input ) { if (!isset($input) || !$input) return array(); $pairs = explode('&', $input); $parsed_parameters = array(); foreach ($pairs as $pair) { $split = explode('=', $pair, 2); $parameter = OAuthUtil::urldecode_rfc3986($split[0]); $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; if (isset($parsed_parameters[$parameter])) { // We have already recieved parameter(s) with this name, so add to the list // of parameters with this name if (is_scalar($parsed_parameters[$parameter])) { // This is the first duplicate, so transform scalar (string) into an array // so we can add the duplicates $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]); } $parsed_parameters[$parameter][] = $value; } else { $parsed_parameters[$parameter] = $value; } } return $parsed_parameters; } public static function build_http_query($params) { if (!$params) return ''; // Urlencode both keys and values $keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); $values = OAuthUtil::urlencode_rfc3986(array_values($params)); $params = array_combine($keys, $values); // Parameters are sorted by name, using lexicographical byte value ordering. // Ref: Spec: 9.1.1 (1) uksort($params, 'strcmp'); $pairs = array(); foreach ($params as $parameter => $value) { if (is_array($value)) { // If two or more parameters share the same name, they are sorted by their value // Ref: Spec: 9.1.1 (1) natsort($value); foreach ($value as $duplicate_value) { $pairs[] = $parameter . '=' . $duplicate_value; } } else { $pairs[] = $parameter . '=' . $value; } } // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) // Each name-value pair is separated by an '&' character (ASCII code 38) return implode('&', $pairs); } } PK!V+system/jchatlogin/social/twitter/index.htmlnu[ PK! 8system/jchatlogin/social/facebook/fb_ca_chain_bundle.crtnu[## ## Bundle of CA Root Certificates ## ## Certificate data from Mozilla as of: Tue Jan 22 14:14:40 2019 GMT ## ## 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: ## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt ## ## It contains the certificates in PEM format and therefore ## can be directly used with curl / libcurl / php_curl, or with ## an Apache+mod_ssl webserver for SSL client authentication. ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.27. ## SHA256: 18372117493b5b7ec006c31d966143fc95a9464a2b5f8d5188e23c5557b2292d ## 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----- PK! E88*system/jchatlogin/social/facebook/base.phpnu[ 10, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60, CURLOPT_USERAGENT => 'facebook-php-3.1' ); /** * List of query parameters that get automatically dropped when rebuilding * the current URL. */ protected static $DROP_QUERY_PARAMS = array ( 'code', 'state', 'signed_request' ); /** * Maps aliases to Facebook domains. */ public static $DOMAIN_MAP = array ( 'api' => 'https://api.facebook.com/', 'api_video' => 'https://api-video.facebook.com/', 'api_read' => 'https://api-read.facebook.com/', 'graph' => 'https://graph.facebook.com/', 'graph_video' => 'https://graph-video.facebook.com/', 'www' => 'https://www.facebook.com/' ); /** * The Application ID. * * @var string */ protected $appId; /** * The Application App Secret. * * @var string */ protected $appSecret; /** * The ID of the Facebook user, or 0 if the user is logged out. * * @var integer */ protected $user; /** * The data from the signed_request token. */ protected $signedRequest; /** * A CSRF state variable to assist in the defense against CSRF attacks. */ protected $state; /** * The OAuth access token received in exchange for a valid authorization * code. * null means the access token has yet to be determined. * * @var string */ protected $accessToken = null; /** * Indicates if the CURL based @ syntax for file uploads is enabled. * * @var boolean */ protected $fileUploadSupport = false; /** * Initialize a Facebook Application. * * The configuration: * - appId: the application ID * - secret: the application secret * - fileUpload: (optional) boolean indicating if file uploads are enabled * * @param array $config * The application configuration */ public function __construct($config) { $this->setAppId ( $config ['appId'] ); $this->setAppSecret ( $config ['secret'] ); if (isset ( $config ['fileUpload'] )) { $this->setFileUploadSupport ( $config ['fileUpload'] ); } $state = $this->getPersistentData ( 'state' ); if (! empty ( $state )) { $this->state = $this->getPersistentData ( 'state' ); } } /** * Set the Application ID. * * @param string $appId * The Application ID * @return BaseFacebook */ public function setAppId($appId) { $this->appId = $appId; return $this; } /** * Get the Application ID. * * @return string the Application ID */ public function getAppId() { return $this->appId; } /** * Set the App Secret. * * @param string $apiSecret * The App Secret * @return BaseFacebook * @deprecated * */ public function setApiSecret($apiSecret) { $this->setAppSecret ( $apiSecret ); return $this; } /** * Set the App Secret. * * @param string $appSecret * The App Secret * @return BaseFacebook */ public function setAppSecret($appSecret) { $this->appSecret = $appSecret; return $this; } /** * Get the App Secret. * * @return string the App Secret * @deprecated * */ public function getApiSecret() { return $this->getAppSecret (); } /** * Get the App Secret. * * @return string the App Secret */ public function getAppSecret() { return $this->appSecret; } /** * Set the file upload support status. * * @param boolean $fileUploadSupport * The file upload support status. * @return BaseFacebook */ public function setFileUploadSupport($fileUploadSupport) { $this->fileUploadSupport = $fileUploadSupport; return $this; } /** * Get the file upload support status. * * @return boolean true if and only if the server supports file upload. */ public function getFileUploadSupport() { return $this->fileUploadSupport; } /** * DEPRECATED! Please use getFileUploadSupport instead. * * Get the file upload support status. * * @return boolean true if and only if the server supports file upload. */ public function useFileUploadSupport() { return $this->getFileUploadSupport (); } /** * Sets the access token for api calls. * Use this if you get * your access token by other means and just want the SDK * to use it. * * @param string $access_token * an access token. * @return BaseFacebook */ public function setAccessToken($access_token) { $this->accessToken = $access_token; return $this; } /** * Determines the access token that should be used for API calls. * The first time this is called, $this->accessToken is set equal * to either a valid user access token, or it's set to the application * access token if a valid user access token wasn't available. Subsequent * calls return whatever the first call returned. * * @return string The access token */ public function getAccessToken() { if ($this->accessToken !== null) { // we've done this already and cached it. Just return. return $this->accessToken; } // first establish access token to be the application // access token, in case we navigate to the /oauth/access_token // endpoint, where SOME access token is required. $this->setAccessToken ( $this->getApplicationAccessToken () ); $user_access_token = $this->getUserAccessToken (); if ($user_access_token) { $this->setAccessToken ( $user_access_token ); } return $this->accessToken; } /** * Determines and returns the user access token, first using * the signed request if present, and then falling back on * the authorization code if present. * The intent is to * return a valid user access token, or false if one is determined * to not be available. * * @return string A valid user access token, or false if one * could not be determined. */ protected function getUserAccessToken() { // first, consider a signed request if it's supplied. // if there is a signed request, then it alone determines // the access token. $signed_request = $this->getSignedRequest (); if ($signed_request) { // apps.facebook.com hands the access_token in the signed_request if (array_key_exists ( 'oauth_token', $signed_request )) { $access_token = $signed_request ['oauth_token']; $this->setPersistentData ( 'access_token', $access_token ); return $access_token; } // the JS SDK puts a code in with the redirect_uri of '' if (array_key_exists ( 'code', $signed_request )) { $code = $signed_request ['code']; $access_token = $this->getAccessTokenFromCode ( $code, '' ); if ($access_token) { $this->setPersistentData ( 'code', $code ); $this->setPersistentData ( 'access_token', $access_token ); return $access_token; } } // signed request states there's no access token, so anything // stored should be cleared. $this->clearAllPersistentData (); return false; // respect the signed request's data, even // if there's an authorization code or something else } else { if (isset ($_REQUEST['accessToken'])) { $access_token = $_REQUEST['accessToken']; if ($access_token) { $this->setPersistentData ( 'code', $code ); $this->setPersistentData ( 'access_token', $access_token ); return $access_token; } } } $code = $this->getCode (); if ($code && $code != $this->getPersistentData ( 'code' )) { $access_token = $this->getAccessTokenFromCode ( $code ); if ($access_token) { $this->setPersistentData ( 'code', $code ); $this->setPersistentData ( 'access_token', $access_token ); return $access_token; } // code was bogus, so everything based on it should be invalidated. $this->clearAllPersistentData (); return false; } // as a fallback, just return whatever is in the persistent // store, knowing nothing explicit (signed request, authorization // code, etc.) was present to shadow it (or we saw a code in $_REQUEST, // but it's the same as what's in the persistent store) return $this->getPersistentData ( 'access_token' ); } /** * Retrieve the signed request, either from a request parameter or, * if not present, from a cookie. * * @return string the signed request, if available, or null otherwise. */ public function getSignedRequest() { if (! $this->signedRequest) { if (isset ( $_REQUEST ['signedRequest'] )) { $this->signedRequest = $this->parseSignedRequest ( $_REQUEST ['signedRequest'] ); } else if (isset ( $_REQUEST ['signed_request'] )) { $this->signedRequest = $this->parseSignedRequest ( $_REQUEST ['signed_request'] ); } else if (isset ( $_COOKIE [$this->getSignedRequestCookieName ()] )) { $this->signedRequest = $this->parseSignedRequest ( $_COOKIE [$this->getSignedRequestCookieName ()] ); } } return $this->signedRequest; } /** * Get the UID of the connected user, or 0 * if the Facebook user is not connected. * * @return string the UID if available. */ public function getUser() { if ($this->user !== null) { // we've already determined this and cached the value. return $this->user; } return $this->user = $this->getUserFromAvailableData (); } /** * Determines the connected user by first examining any signed * requests, then considering an authorization code, and then * falling back to any persistent store storing the user. * * @return integer The id of the connected Facebook user, * or 0 if no such user exists. */ protected function getUserFromAvailableData() { // if a signed request is supplied, then it solely determines // who the user is. $signed_request = $this->getSignedRequest (); if ($signed_request) { if (array_key_exists ( 'user_id', $signed_request )) { $user = $signed_request ['user_id']; $this->setPersistentData ( 'user_id', $signed_request ['user_id'] ); return $user; } // if the signed request didn't present a user id, then invalidate // all entries in any persistent store. $this->clearAllPersistentData (); return 0; } $user = $this->getPersistentData ( 'user_id', $default = 0 ); $persisted_access_token = $this->getPersistentData ( 'access_token' ); // use access_token to fetch user id if we have a user access_token, or if // the cached access token has changed. $access_token = $this->getAccessToken (); if ($access_token && $access_token != $this->getApplicationAccessToken () && ! ($user && $persisted_access_token == $access_token)) { $user = $this->getUserFromAccessToken (); if ($user) { $this->setPersistentData ( 'user_id', $user ); } else { $this->clearAllPersistentData (); } } return $user; } /** * Get a Login URL for use with redirects. * By default, full page redirect is * assumed. If you are using the generated URL with a window.open() call in * JavaScript, you can pass in display=popup as part of the $params. * * The parameters: * - redirect_uri: the url to go to after a successful login * - scope: comma separated list of requested extended perms * * @param array $params * Provide custom parameters * @return string The URL for the login flow */ public function getLoginUrl($params = array()) { $this->establishCSRFTokenState (); $currentUrl = $this->getCurrentUrl (); // if 'scope' is passed as an array, convert to comma separated list $scopeParams = isset ( $params ['scope'] ) ? $params ['scope'] : null; if ($scopeParams && is_array ( $scopeParams )) { $params ['scope'] = implode ( ',', $scopeParams ); } return $this->getUrl ( 'www', 'dialog/oauth', array_merge ( array ( 'client_id' => $this->getAppId (), 'redirect_uri' => $currentUrl, // possibly overwritten 'state' => $this->state ), $params ) ); } /** * Get a Logout URL suitable for use with redirects. * * The parameters: * - next: the url to go to after a successful logout * * @param array $params * Provide custom parameters * @return string The URL for the logout flow */ public function getLogoutUrl($params = array()) { return $this->getUrl ( 'www', 'logout.php', array_merge ( array ( 'next' => $this->getCurrentUrl (), 'access_token' => $this->getAccessToken () ), $params ) ); } /** * Get a login status URL to fetch the status from Facebook. * * The parameters: * - ok_session: the URL to go to if a session is found * - no_session: the URL to go to if the user is not connected * - no_user: the URL to go to if the user is not signed into facebook * * @param array $params * Provide custom parameters * @return string The URL for the logout flow */ public function getLoginStatusUrl($params = array()) { return $this->getUrl ( 'www', 'extern/login_status.php', array_merge ( array ( 'api_key' => $this->getAppId (), 'no_session' => $this->getCurrentUrl (), 'no_user' => $this->getCurrentUrl (), 'ok_session' => $this->getCurrentUrl (), 'session_version' => 3 ), $params ) ); } /** * Make an API call. * * @return mixed The decoded response */ public function api(/* polymorphic */) { $args = func_get_args (); if (is_array ( $args [0] )) { return $this->_restserver ( $args [0] ); } else { return call_user_func_array ( array ( $this, '_graph' ), $args ); } } /** * Constructs and returns the name of the cookie that * potentially houses the signed request for the app user. * The cookie is not set by the BaseFacebook class, but * it may be set by the JavaScript SDK. * * @return string the name of the cookie that would house * the signed request value. */ protected function getSignedRequestCookieName() { return 'fbsr_' . $this->getAppId (); } /** * Constructs and returns the name of the coookie that potentially contain * metadata. * The cookie is not set by the BaseFacebook class, but it may be * set by the JavaScript SDK. * * @return string the name of the cookie that would house metadata. */ protected function getMetadataCookieName() { return 'fbm_' . $this->getAppId (); } /** * Get the authorization code from the query parameters, if it exists, * and otherwise return false to signal no authorization code was * discoverable. * * @return mixed The authorization code, or false if the authorization * code could not be determined. */ protected function getCode() { if (isset ( $_REQUEST ['code'] )) { if ($this->state !== null && isset ( $_REQUEST ['state'] ) && $this->state === $_REQUEST ['state']) { // CSRF state has done its job, so clear it $this->state = null; $this->clearPersistentData ( 'state' ); return $_REQUEST ['code']; } else { self::errorLog ( 'CSRF state token does not match one provided.' ); return false; } } if (isset ($_REQUEST['accessToken'])) { return $_REQUEST ['accessToken']; } return false; } /** * Retrieves the UID with the understanding that * $this->accessToken has already been set and is * seemingly legitimate. * It relies on Facebook's Graph API * to retrieve user information and then extract * the user ID. * * @return integer Returns the UID of the Facebook user, or 0 * if the Facebook user could not be determined. */ protected function getUserFromAccessToken() { try { $user_info = $this->api ( '/me' ); return $user_info ['id']; } catch ( JChatFacebookException $e ) { return 0; } } /** * Returns the access token that should be used for logged out * users when no authorization code is available. * * @return string The application access token, useful for gathering * public information about users and applications. */ protected function getApplicationAccessToken() { return $this->appId . '|' . $this->appSecret; } /** * Lays down a CSRF state token for this process. * * @return void */ protected function establishCSRFTokenState() { if ($this->state === null) { $this->state = md5 ( uniqid ( mt_rand (), true ) ); $this->setPersistentData ( 'state', $this->state ); } } /** * Retrieves an access token for the given authorization code * (previously generated from www.facebook.com on behalf of * a specific user). * The authorization code is sent to graph.facebook.com * and a legitimate access token is generated provided the access token * and the user for which it was generated all match, and the user is * either logged in to Facebook or has granted an offline access permission. * * @param string $code * An authorization code. * @return mixed An access token exchanged for the authorization code, or * false if an access token could not be generated. */ protected function getAccessTokenFromCode($code, $redirect_uri = null) { if (empty ( $code )) { return false; } if ($redirect_uri === null) { $redirect_uri = $this->getCurrentUrl (); } try { // need to circumvent json_decode by calling _oauthRequest // directly, since response isn't JSON format. $access_token_response = $this->_oauthRequest ( $this->getUrl ( 'graph', '/oauth/access_token' ), $params = array ( 'client_id' => $this->getAppId (), 'client_secret' => $this->getAppSecret (), 'redirect_uri' => $redirect_uri, 'code' => $code ) ); } catch ( JChatFacebookException $e ) { // most likely that user very recently revoked authorization. // In any event, we don't have an access token, so say so. return false; } if (empty ( $access_token_response )) { return false; } $response_params = array (); $response_params = (array)json_decode($access_token_response); if (! isset ( $response_params ['access_token'] )) { return false; } return $response_params ['access_token']; } /** * Invoke the old restserver.php endpoint. * * @param array $params * Method call object * * @return mixed The decoded response object * @throws JChatFacebookException */ protected function _restserver($params) { // generic application level parameters $params ['api_key'] = $this->getAppId (); $params ['format'] = 'json-strings'; $result = json_decode ( $this->_oauthRequest ( $this->getApiUrl ( $params ['method'] ), $params ), true ); // results are returned, errors are thrown if (is_array ( $result ) && isset ( $result ['error_code'] )) { $this->throwAPIException ( $result ); } if ($params ['method'] === 'auth.expireSession' || $params ['method'] === 'auth.revokeAuthorization') { $this->destroySession (); } return $result; } /** * Return true if this is video post. * * @param string $path * The path * @param string $method * The http method (default 'GET') * * @return boolean true if this is video post */ protected function isVideoPost($path, $method = 'GET') { if ($method == 'POST' && preg_match ( "/^(\/)(.+)(\/)(videos)$/", $path )) { return true; } return false; } /** * Invoke the Graph API. * * @param string $path * The path (required) * @param string $method * The http method (default 'GET') * @param array $params * The query/post data * * @return mixed The decoded response object * @throws JChatFacebookException */ protected function _graph($path, $method = 'GET', $params = array()) { if (is_array ( $method ) && empty ( $params )) { $params = $method; $method = 'GET'; } $params ['method'] = $method; // method override as we always do a POST if ($this->isVideoPost ( $path, $method )) { $domainKey = 'graph_video'; } else { $domainKey = 'graph'; } $result = json_decode ( $this->_oauthRequest ( $this->getUrl ( $domainKey, $path ), $params ), true ); // results are returned, errors are thrown if (is_array ( $result ) && isset ( $result ['error'] )) { $this->throwAPIException ( $result ); } return $result; } /** * Make a OAuth Request. * * @param string $url * The path (required) * @param array $params * The query/post data * * @return string The decoded response object * @throws JChatFacebookException */ protected function _oauthRequest($url, $params) { if (! isset ( $params ['access_token'] )) { $params ['access_token'] = $this->getAccessToken (); } // json_encode all params values that are not strings foreach ( $params as $key => $value ) { if (! is_string ( $value )) { $params [$key] = json_encode ( $value ); } } return $this->makeRequest ( $url, $params ); } /** * Makes an HTTP request. * This method can be overridden by subclasses if * developers want to do fancier things or use something other than curl to * make the request. * * @param string $url * The URL to make the request to * @param array $params * The parameters to use for the POST body * @param CurlHandler $ch * Initialized curl handle * * @return string The response text */ protected function makeRequest($url, $params, $ch = null) { if (! $ch) { $ch = curl_init (); } $opts = self::$CURL_OPTS; if ($this->getFileUploadSupport ()) { $opts [CURLOPT_POSTFIELDS] = $params; } else { $opts [CURLOPT_POSTFIELDS] = http_build_query ( $params, '', '&' ); } $opts [CURLOPT_URL] = $url; // disable the 'Expect: 100-continue' behaviour. This causes CURL to wait // for 2 seconds if the server does not support this header. if (isset ( $opts [CURLOPT_HTTPHEADER] )) { $existing_headers = $opts [CURLOPT_HTTPHEADER]; $existing_headers [] = 'Expect:'; $opts [CURLOPT_HTTPHEADER] = $existing_headers; } else { $opts [CURLOPT_HTTPHEADER] = array ( 'Expect:' ); } curl_setopt_array ( $ch, $opts ); $result = curl_exec ( $ch ); if (curl_errno ( $ch ) == 60) { // CURLE_SSL_CACERT self::errorLog ( 'Invalid or no certificate authority found, ' . 'using bundled information' ); curl_setopt ( $ch, CURLOPT_CAINFO, dirname ( __FILE__ ) . '/fb_ca_chain_bundle.crt' ); $result = curl_exec ( $ch ); } if ($result === false) { $e = new \JChatFacebookException ( array ( 'error_code' => curl_errno ( $ch ), 'error' => array ( 'message' => curl_error ( $ch ), 'type' => 'CurlException' ) ) ); curl_close ( $ch ); throw $e; } curl_close ( $ch ); return $result; } /** * Parses a signed_request and validates the signature. * * @param string $signed_request * A signed token * @return array The payload inside it or null if the sig is wrong */ protected function parseSignedRequest($signed_request) { list ( $encoded_sig, $payload ) = explode ( '.', $signed_request, 2 ); // decode the data $sig = self::bas64UrlDecode ( $encoded_sig ); $data = json_decode ( self::bas64UrlDecode ( $payload ), true ); if (strtoupper ( $data ['algorithm'] ) !== 'HMAC-SHA256') { self::errorLog ( 'Unknown algorithm. Expected HMAC-SHA256' ); return null; } // check sig $expected_sig = hash_hmac ( 'sha256', $payload, $this->getAppSecret (), $raw = true ); if ($sig !== $expected_sig) { self::errorLog ( 'Bad Signed JSON signature!' ); return null; } return $data; } /** * Build the URL for api given parameters. * * @param $method String * the method name. * @return string The URL for the given parameters */ protected function getApiUrl($method) { static $READ_ONLY_CALLS = array ( 'admin.getallocation' => 1, 'admin.getappproperties' => 1, 'admin.getbannedusers' => 1, 'admin.getlivestreamvialink' => 1, 'admin.getmetrics' => 1, 'admin.getrestrictioninfo' => 1, 'application.getpublicinfo' => 1, 'auth.getapppublickey' => 1, 'auth.getsession' => 1, 'auth.getsignedpublicsessiondata' => 1, 'comments.get' => 1, 'connect.getunconnectedfriendscount' => 1, 'dashboard.getactivity' => 1, 'dashboard.getcount' => 1, 'dashboard.getglobalnews' => 1, 'dashboard.getnews' => 1, 'dashboard.multigetcount' => 1, 'dashboard.multigetnews' => 1, 'data.getcookies' => 1, 'events.get' => 1, 'events.getmembers' => 1, 'fbml.getcustomtags' => 1, 'feed.getappfriendstories' => 1, 'feed.getregisteredtemplatebundlebyid' => 1, 'feed.getregisteredtemplatebundles' => 1, 'fql.multiquery' => 1, 'fql.query' => 1, 'friends.arefriends' => 1, 'friends.get' => 1, 'friends.getappusers' => 1, 'friends.getlists' => 1, 'friends.getmutualfriends' => 1, 'gifts.get' => 1, 'groups.get' => 1, 'groups.getmembers' => 1, 'intl.gettranslations' => 1, 'links.get' => 1, 'notes.get' => 1, 'notifications.get' => 1, 'pages.getinfo' => 1, 'pages.isadmin' => 1, 'pages.isappadded' => 1, 'pages.isfan' => 1, 'permissions.checkavailableapiaccess' => 1, 'permissions.checkgrantedapiaccess' => 1, 'photos.get' => 1, 'photos.getalbums' => 1, 'photos.gettags' => 1, 'profile.getinfo' => 1, 'profile.getinfooptions' => 1, 'stream.get' => 1, 'stream.getcomments' => 1, 'stream.getfilters' => 1, 'users.getinfo' => 1, 'users.getloggedinuser' => 1, 'users.getstandardinfo' => 1, 'users.hasapppermission' => 1, 'users.isappuser' => 1, 'users.isverified' => 1, 'video.getuploadlimits' => 1 ); $name = 'api'; if (isset ( $READ_ONLY_CALLS [strtolower ( $method )] )) { $name = 'api_read'; } else if (strtolower ( $method ) == 'video.upload') { $name = 'api_video'; } return self::getUrl ( $name, 'restserver.php' ); } /** * Build the URL for given domain alias, path and parameters. * * @param $name string * The name of the domain * @param $path string * Optional path (without a leading slash) * @param $params array * Optional query parameters * * @return string The URL for the given parameters */ protected function getUrl($name, $path = '', $params = array()) { $url = self::$DOMAIN_MAP [$name]; if ($path) { if ($path [0] === '/') { $path = substr ( $path, 1 ); } $url .= $path; } if ($params) { $url .= '?' . http_build_query ( $params, '', '&' ); } return $url; } /** * Returns the Current URL, stripping it of known FB parameters that should * not persist. * * @return string The current URL */ protected function getCurrentUrl() { if (isset ( $_SERVER ['HTTPS'] ) && ($_SERVER ['HTTPS'] == 'on' || $_SERVER ['HTTPS'] == 1) || isset ( $_SERVER ['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER ['HTTP_X_FORWARDED_PROTO'] == 'https') { $protocol = 'https://'; } else { $protocol = 'http://'; } $currentUrl = $protocol . $_SERVER ['HTTP_HOST'] . $_SERVER ['REQUEST_URI']; $parts = parse_url ( $currentUrl ); $query = ''; if (! empty ( $parts ['query'] )) { // drop known fb params $params = explode ( '&', $parts ['query'] ); $retained_params = array (); foreach ( $params as $param ) { if ($this->shouldRetainParam ( $param )) { $retained_params [] = $param; } } if (! empty ( $retained_params )) { $query = '?' . implode ( '&', $retained_params ); } } // use port if non default $port = isset ( $parts ['port'] ) && (($protocol === 'http://' && $parts ['port'] !== 80) || ($protocol === 'https://' && $parts ['port'] !== 443)) ? ':' . $parts ['port'] : ''; // rebuild return $protocol . $parts ['host'] . $port . $parts ['path'] . $query; } /** * Returns true if and only if the key or key/value pair should * be retained as part of the query string. * This amounts to * a brute-force search of the very small list of Facebook-specific * params that should be stripped out. * * @param string $param * A key or key/value pair within a URL's query (e.g. * 'foo=a', 'foo=', or 'foo'. * * @return boolean */ protected function shouldRetainParam($param) { foreach ( self::$DROP_QUERY_PARAMS as $drop_query_param ) { if (strpos ( $param, $drop_query_param . '=' ) === 0) { return false; } } return true; } /** * Analyzes the supplied result to see if it was thrown * because the access token is no longer valid. * If that is * the case, then we destroy the session. * * @param $result array * A record storing the error message returned * by a failed API call. */ protected function throwAPIException($result) { $e = new \JChatFacebookException ( $result ); switch ($e->getType ()) { // OAuth 2.0 Draft 00 style case 'OAuthException' : // OAuth 2.0 Draft 10 style case 'invalid_token' : // REST server errors are just Exceptions case 'Exception' : $message = $e->getMessage (); if ((strpos ( $message, 'Error validating access token' ) !== false) || (strpos ( $message, 'Invalid OAuth access token' ) !== false) || (strpos ( $message, 'An active access token must be used' ) !== false)) { $this->destroySession (); } break; } throw $e; } /** * Prints to the error log if you aren't in command line mode. * * @param string $msg * Log message */ protected static function errorLog($msg) { } /** * Bas64 encoding that doesn't need to be urlencode()ed. * Exactly the same as bas64 encode except it uses * - instead of + * _ instead of / * * @param string $input * bas64UrlEncoded string * @return string */ protected static function bas64UrlDecode($input) { $bas64FunctionNameEncode = 'base'. 64 . '_encode'; $bas64FunctionNameDecode = 'base'. 64 . '_decode'; return $bas64FunctionNameDecode ( strtr ( $input, '-_', '+/' ) ); } /** * Destroy the current session */ public function destroySession() { $this->accessToken = null; $this->signedRequest = null; $this->user = null; $this->clearAllPersistentData (); // Javascript sets a cookie that will be used in getSignedRequest that we // need to clear if we can $cookie_name = $this->getSignedRequestCookieName (); if (array_key_exists ( $cookie_name, $_COOKIE )) { unset ( $_COOKIE [$cookie_name] ); if (! headers_sent ()) { // The base domain is stored in the metadata cookie if not we fallback // to the current hostname $base_domain = '.' . $_SERVER ['HTTP_HOST']; $metadata = $this->getMetadataCookie (); if (array_key_exists ( 'base_domain', $metadata ) && ! empty ( $metadata ['base_domain'] )) { $base_domain = $metadata ['base_domain']; } setcookie ( $cookie_name, '', 0, '/', $base_domain ); } else { self::errorLog ( 'There exists a cookie that we wanted to clear that we couldn\'t ' . 'clear because headers was already sent. Make sure to do the first ' . 'API call before outputing anything' ); } } } /** * Parses the metadata cookie that our Javascript API set * * @return an array mapping key to value */ protected function getMetadataCookie() { $cookie_name = $this->getMetadataCookieName (); if (! array_key_exists ( $cookie_name, $_COOKIE )) { return array (); } // The cookie value can be wrapped in "-characters so remove them $cookie_value = trim ( $_COOKIE [$cookie_name], '"' ); if (empty ( $cookie_value )) { return array (); } $parts = explode ( '&', $cookie_value ); $metadata = array (); foreach ( $parts as $part ) { $pair = explode ( '=', $part, 2 ); if (! empty ( $pair [0] )) { $metadata [urldecode ( $pair [0] )] = (count ( $pair ) > 1) ? urldecode ( $pair [1] ) : ''; } } return $metadata; } /** * Each of the following four methods should be overridden in * a concrete subclass, as they are in the provided Facebook class. * The Facebook class uses PHP sessions to provide a primitive * persistent store, but another subclass--one that you implement-- * might use a database, memcache, or an in-memory cache. * * @see Facebook */ /** * Stores the given ($key, $value) pair, so that future calls to * getPersistentData($key) return $value. * This call may be in another request. * * @param string $key * @param array $value * * @return void */ abstract protected function setPersistentData($key, $value); /** * Get the data for $key, persisted by BaseFacebook::setPersistentData() * * @param string $key * The key of the data to retrieve * @param boolean $default * The default value to return if $key is not found * * @return mixed */ abstract protected function getPersistentData($key, $default = false); /** * Clear the data with $key from the persistent storage * * @param string $key * @return void */ abstract protected function clearPersistentData($key); /** * Clear all data from the persistent storage * * @return void */ abstract protected function clearAllPersistentData(); }PK!jR R /system/jchatlogin/social/facebook/exception.phpnu[result = $result; $code = isset ( $result ['error_code'] ) ? $result ['error_code'] : 0; if (isset ( $result ['error_description'] )) { // OAuth 2.0 Draft 10 style $msg = $result ['error_description']; } else if (isset ( $result ['error'] ) && is_array ( $result ['error'] )) { // OAuth 2.0 Draft 00 style $msg = $result ['error'] ['message']; } else if (isset ( $result ['error_msg'] )) { // Rest server style $msg = $result ['error_msg']; } else { $msg = 'Unknown Error. Check getResult()'; } parent::__construct ( $msg, $code ); } /** * Return the associated result object returned by the API server. * * @return array The result from the API server */ public function getResult() { return $this->result; } /** * Returns the associated type for the error. * This will default to * 'Exception' when a type is not available. * * @return string */ public function getType() { if (isset ( $this->result ['error'] )) { $error = $this->result ['error']; if (is_string ( $error )) { // OAuth 2.0 Draft 10 style return $error; } else if (is_array ( $error )) { // OAuth 2.0 Draft 00 style if (isset ( $error ['type'] )) { return $error ['type']; } } } return 'Exception'; } /** * To make debugging easier. * * @return string The string representation of the error */ public function __toString() { $str = $this->getType () . ': '; if ($this->code != 0) { $str .= $this->code . ': '; } return $str . $this->message; } } PK!T) ) .system/jchatlogin/social/facebook/facebook.phpnu[constructSessionVariableName ( $key ); $_SESSION [$session_var_name] = $value; } protected function getPersistentData($key, $default = false) { if (! in_array ( $key, self::$kSupportedKeys )) { self::errorLog ( 'Unsupported key passed to getPersistentData.' ); return $default; } $session_var_name = $this->constructSessionVariableName ( $key ); return isset ( $_SESSION [$session_var_name] ) ? $_SESSION [$session_var_name] : $default; } protected function clearPersistentData($key) { if (! in_array ( $key, self::$kSupportedKeys )) { self::errorLog ( 'Unsupported key passed to clearPersistentData.' ); return; } $session_var_name = $this->constructSessionVariableName ( $key ); unset ( $_SESSION [$session_var_name] ); } protected function clearAllPersistentData() { foreach ( self::$kSupportedKeys as $key ) { $this->clearPersistentData ( $key ); } } protected function constructSessionVariableName($key) { return implode ( '_', array ( 'fb', $this->getAppId (), $key ) ); } } PK!k!!,system/jchatlogin/social/facebook/index.htmlnu[ PK! 97 )system/jchatlogin/social/google/login.phpnu[clientId = $clientId; $this->key = $key; $this->callbackUrl = $callbackUrl; } /** * Initializes our service */ public function init() { $storage = new Session (); $serviceFactory = new ServiceFactory (); $credentials = new Credentials ( $this->clientId, $this->key, $this->callbackUrl ); $this->service = $serviceFactory->createService ( 'google', $credentials, $storage, array ( 'userinfo_email', 'userinfo_profile' ) ); return $this; } /** * Returns the login url for the social network * * @return string */ public function getLoginUrl() { return $this->service->getAuthorizationUri (); } /** * Handles the login callback from the social network * * @param string $accessCode * * @return SocialUserInterface */ public function loginCallback($accessCode) { $this->service->requestAccessToken ( $accessCode ); $userData = json_decode ( $this->service->request ( 'https://www.googleapis.com/oauth2/v1/userinfo' ), true ); $googleUser = new \JChatGoogleUser ( $userData ); return $googleUser; } } PK!V*system/jchatlogin/social/google/index.htmlnu[ PK!b(system/jchatlogin/social/google/user.phpnu[userData = $userData; } /** * Get the provider name * * @return string */ public function getProvider() { return "google"; } /** * Get the UID of the user * * @return string */ public function getUid() { if (array_key_exists ( 'id', $this->userData )) { return $this->userData ['id']; } return null; } /** * Get the first name of the user * * @return string */ public function getFirstname() { if (array_key_exists ( 'given_name', $this->userData )) { return $this->userData ['given_name']; } return null; } /** * Get the last name of the user * * @return string */ public function getLastname() { if (array_key_exists ( 'family_name', $this->userData )) { return $this->userData ['family_name']; } return null; } /** * Get the username * * @return string */ public function getUsername() { return strtolower($this->getFirstname() . '_' . $this->getLastname()); } /** * Get the emailaddress * * @return string */ public function getEmailAddress() { if (array_key_exists ( 'email', $this->userData )) { return $this->userData ['email']; } return null; } /** * Get the city * * @return string */ public function getCity() { return null; } /** * Get the birthdate * * @return string */ public function getBirthDate() { return null; } /** * Get the gender * * @return string */ public function getGender() { if (array_key_exists ( 'gender', $this->userData )) { return $this->userData ['gender']; } return null; } /** * Get the geolocale * * @return string */ public function getLocale() { if (array_key_exists ( 'locale', $this->userData )) { return $this->userData ['locale']; } return null; } /** * Get the Google picture avatar * * @return string */ public function getPicture() { if (array_key_exists ( 'picture', $this->userData )) { return $this->userData ['picture']; } return null; } } PK!#o,,#system/jchatlogin/social/index.htmlnu[PK!J7(system/jchatlogin/connectors/twitter.phpnu[joomlaUserObject->guest && ( bool ) !$this->app->getInput()->get->getString ( 'oauth_token', false ) && !( bool ) $this->app->getInput()->getString ( 'code', false )) { $connection = new \JChatTwitterLogin($this->appId, $this->secret); $request_token = $connection->getRequestToken (); // get Request Token if ($request_token && isset($request_token ['oauth_token'])) { $token = $request_token ['oauth_token']; $_SESSION ['jchat_request_token'] = $token; $_SESSION ['jchat_request_token_secret'] = $request_token ['oauth_token_secret']; switch ($connection->http_code) { case 200 : $twitterLoginURL = $connection->getAuthorizeURL ( $token ); $_SESSION ['jchat_login_url'] = $twitterLoginURL; $this->app->set('jchat_login_url', $twitterLoginURL); $doc = $this->app->getDocument(); $doc->getWebAssetManager()->addInlineScript ( "var jchatTwitterLoginURL = '$twitterLoginURL';" ); break; } } } else { $twitterLoginURL = @$_SESSION ['jchat_login_url']; $this->app->set('jchat_login_url', $twitterLoginURL); } } catch ( \Exception $e ) { $this->app->enqueueMessage(Text::sprintf('COM_JCHAT_ERROR_TWITTER_LOGIN', $e->getMessage ()), 'warning'); } // Twitter Login - Execute only after link click to perform Twitter login, after Twitter redirects back if ($this->joomlaUserObject->guest && ( bool ) $this->app->getInput()->get->getString ( 'oauth_token', false ) && ( bool ) $this->app->getInput()->get->getString ( 'oauth_verifier', false )) { try { $connection = new \JChatTwitterLogin($this->appId, $this->secret, $_SESSION['jchat_request_token'], $_SESSION['jchat_request_token_secret']); $access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']); if(isset($access_token['oauth_token'])) { $connection = new \JChatTwitterLogin($this->appId, $this->secret, $access_token['oauth_token'], $access_token['oauth_token_secret']); $twitterParams =array(); $twitterParams['include_entities']='false'; $twitterUserObject = $connection->get('account/verify_credentials', $twitterParams); } else { return; } // Check if users exists already in the Joomla database using email address as primary key, retrieve user id if exists $authType = 'id'; $joomlaIdentifier = 'tw' . $twitterUserObject->id_str; $alreadyCreatedJoomlaUserID = JChatHelpersUsers::getJoomlaId ( $joomlaIdentifier, $authType ); if (! $alreadyCreatedJoomlaUserID) { // Collect user info $name = $twitterUserObject->name; $username = InputFilter::getInstance()->clean($twitterUserObject->screen_name, 'username'); $password = UserHelper::genRandomPassword ( 5 ); $email = $twitterUserObject->email = $joomlaIdentifier . '@twitter.com'; // Normalize info array $fbUserProfileArray ['id'] = $joomlaIdentifier; $fbUserProfileArray ['email'] = $twitterUserObject->email; $fbUserProfileArray ['picture'] = $twitterUserObject->profile_image_url_https; $fbUserProfileArray ['first_name'] = $twitterUserObject->name; $fbUserProfileArray ['last_name'] = $twitterUserObject->screen_name; $fbUserProfileArray ['name'] = $twitterUserObject->name; // Trigger to create a new Joomla user aggregating data from Facebook user profile, pre-populate bind $this->joomlaUserObject $this->onNewUser( $this->joomlaUserObject, $name, $username, $password, $email, $fbUserProfileArray, $this->cParams ); // Do instant Joomla login authentication with new user, aggregated data and random generated password only for login purpouse $this->onLogin( $this->joomlaUserObject, $this->cParams ); } else { // get already populated $this->joomlaUserObject $this->joomlaUserObject = Factory::getContainer()->get(\Joomla\CMS\User\UserFactoryInterface::class)->loadUserById ( $alreadyCreatedJoomlaUserID ); // Do instant Joomla login authentication with new user, aggregated data and random generated password only for login purpouse $this->onLogin( $this->joomlaUserObject, $this->cParams ); } } catch ( \Exception $e ) { $this->app->enqueueMessage(Text::sprintf('COM_JCHAT_ERROR_TWITTER_LOGIN', $e->getMessage ()), 'warning'); } } } /** * Class Constructor * @param Object $cParams * * @access public */ public function __construct($cParams) { parent::__construct($cParams); $this->appId = $this->cParams->get('twitterKey', null); $this->secret = $this->cParams->get('twitterSecret', null); // Load framework classes without autoloading require_once JPATH_ROOT . '/plugins/system/jchatlogin/social/twitter/login.php'; require_once JPATH_ROOT . '/plugins/system/jchatlogin/social/twitter/OAuth.php'; } }PK!jaP'system/jchatlogin/connectors/google.phpnu[joomlaUserObject->guest && ( bool ) !$this->app->getInput()->get->getString ( 'code', false )) { $googleAPI = new \JChatGoogleLogin($this->appId, $this->secret, Uri::base(), true); $gplusLoginURL = $googleAPI->init()->getLoginUrl(); $doc = $this->app->getDocument(); $doc->getWebAssetManager()->addInlineScript ( "var jchatGPlusLoginURL = '$gplusLoginURL';" ); } } catch ( \Exception $e ) { $this->app->enqueueMessage(Text::sprintf('COM_JCHAT_ERROR_GPLUS_LOGIN', $e->getMessage ()), 'warning'); } // Google Plus Login - Execute only after link click to perform Google login, after Google redirects back if ($this->joomlaUserObject->guest && ( bool ) $this->app->getInput()->get->getString ( 'code', false )) { try { $googleAPI = new \JChatGoogleLogin($this->appId, $this->secret, Uri::base(), true); $googleUserObject = $googleAPI->init()->loginCallback($this->app->getInput()->get->getString ( 'code' )); // Check if users exists already in the Joomla database using email address as primary key, retrieve user id if exists $authType = $this->cParams->get('auth_type', 'id'); $joomlaIdentifier = $authType == 'id' ? $googleUserObject->getUid() : $googleUserObject->getEmailAddress(); $alreadyCreatedJoomlaUserID = JChatHelpersUsers::getJoomlaId ( $joomlaIdentifier, $authType ); if (! $alreadyCreatedJoomlaUserID) { // Collect user info $name = $googleUserObject->getFirstname() . ' ' . $googleUserObject->getlastname(); $username = InputFilter::getInstance()->clean($googleUserObject->getUsername(), 'username'); $password = UserHelper::genRandomPassword ( 5 ); $email = $googleUserObject->getEmailAddress(); // Normalize info array $fbUserProfileArray ['id'] = $googleUserObject->getUid(); $fbUserProfileArray ['email'] = $email; $fbUserProfileArray ['picture'] = $googleUserObject->getPicture(); $fbUserProfileArray ['first_name'] = $googleUserObject->getFirstname(); $fbUserProfileArray ['last_name'] = $googleUserObject->getLastname(); $fbUserProfileArray ['name'] = $name; // Trigger to create a new Joomla user aggregating data from Facebook user profile, pre-populate bind $this->joomlaUserObject $this->onNewUser( $this->joomlaUserObject, $name, $username, $password, $email, $fbUserProfileArray, $this->cParams ); // Do instant Joomla login authentication with new user, aggregated data and random generated password only for login purpouse $this->onLogin( $this->joomlaUserObject, $this->cParams ); } else { // get already populated $this->joomlaUserObject $this->joomlaUserObject = Factory::getContainer()->get(\Joomla\CMS\User\UserFactoryInterface::class)->loadUserById ( $alreadyCreatedJoomlaUserID ); // Do instant Joomla login authentication with new user, aggregated data and random generated password only for login purpouse $this->onLogin( $this->joomlaUserObject, $this->cParams ); } } catch ( \Exception $e ) { $this->app->enqueueMessage(Text::sprintf('COM_JCHAT_ERROR_GPLUS_LOGIN', $e->getMessage ()), 'warning'); } } } /** * Class Constructor * @param Object $cParams * * @access public */ public function __construct($cParams) { parent::__construct($cParams); $this->appId = $this->cParams->get('gplusClientID', null); $this->secret = $this->cParams->get('gplusKey', null); // Load framework classes without autoloading require_once JPATH_ROOT . '/plugins/system/jchatlogin/social/google/login.php'; require_once JPATH_ROOT . '/plugins/system/jchatlogin/social/google/user.php'; } }PK!25++*system/jchatlogin/connectors/connector.phpnu[db); $tableInstance->userid = $joomlaUserObject->id; $tableInstance->alias = $joomlaUserObject->id . ':' . $joomlaUserObject->username; try { $tableInstance->store(); } catch (\Exception $e) { } break; case 'easysocial': $tableInstance = new CustomTable('#__social_users', 'id', $this->db); $tableInstance->user_id = $joomlaUserObject->id; $tableInstance->state = 1; $tableInstance->type = 'joomla'; try { $tableInstance->store(); } catch (\Exception $e) { } $tableInstance = new CustomTable('#__social_profiles_maps', 'id', $this->db); $tableInstance->profile_id = 1; $tableInstance->user_id = $joomlaUserObject->id; $tableInstance->state = 1; $tableInstance->created = $fbUsersTable->registered_on; try { $tableInstance->store(); } catch (\Exception $e) { } break; case 'cbuilder': $tableInstance = new CustomTable('#__comprofiler', 'userid', $this->db); $tableInstance->id = $tableInstance->user_id = $joomlaUserObject->id; $tableInstance->firstname = $fbUsersTable->first_name; $tableInstance->lastname = $fbUsersTable->last_name; $tableInstance->approved = 1; $tableInstance->confirmed = 1; try { $tableInstance->store(); } catch (\Exception $e) { } break; } } /** * Get always the redirected 301 URL to the avatar image for Facebook * * @access protected * @param string $url * @return string The redirected URL */ protected function getFacebookRedirectPage( $url ) { // Format the request header array $header = array ( 'User-Agent: Google-Bot', 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' ); $ch = curl_init ( $url ); curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); curl_setopt ( $ch, CURLOPT_HEADER, true); curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 0 ); curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header ); curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 30 ); $result = curl_exec ( $ch ); $info = curl_getinfo ( $ch ); $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close ( $ch ); // If it's a redirection (3XX) follow the redirect if ($httpStatus >= 300 && $httpStatus < 400) { $redirectionLink = null; $headers = explode("\n", $result); // loop through the headers and check for a Location: str $j = count($headers); for($i = 0; $i < $j; $i++){ // if we find the Location header strip it and fill the redir var if(stripos($headers[$i],"location:") !== false){ $redirectionLink = trim(str_ireplace("location:","",$headers[$i])); break; } } return $redirectionLink; } return $url; } /** * Manage the 3PD components integration * * @access protected * @param string $remoteAvatar * @return void */ protected function importAvatar($remoteAvatar) { // Manage redirected avatars from Facebook if(strpos($remoteAvatar, 'facebook')) { $remoteAvatar = $this->getFacebookRedirectPage($remoteAvatar); } // Setup avatar paths $tempAvatarName = JPATH_ROOT . '/components/com_jchat/images/avatars/tempavatar' . $this->joomlaUserObject->id; $finalAvatarName = JPATH_ROOT . '/components/com_jchat/images/avatars/uidavatar_' . $this->joomlaUserObject->id . '.png'; // Import copy the remote avatar $stream = new Stream(); $stream->copy($remoteAvatar, $tempAvatarName); // Resize and convert avatar to png try { $imageHandler = new Image($tempAvatarName); $resizedImage = $imageHandler->resize(32, 32); $resizedImage->toFile($finalAvatarName, IMAGETYPE_PNG); } catch (\Exception $e) { } // Finally remove the temp image $stream->delete($tempAvatarName); } /** * onNewUser handler * * @access protected * @param Object $this->joomlaUserObject * @param string $name * @param string $username * @param string $password * @param string $email * @param array $fbUserProfileArray * @param Object $cParams * @return null */ protected function onNewUser($joomlaUserObject, $name, $username, $password, $email, $fbUserProfileArray, $cParams) { // Execute only on site application if ($this->app->isClient ('site')) { $config = ComponentHelper::getParams ( 'com_users' ); // Default to Registered. $defaultUserGroup = $config->get ( 'new_usertype', 2 ); $data = array ( "name" => $name, "username" => $username, "groups" => array ( $defaultUserGroup ), "email" => $email ); // Write to database $this->joomlaUserObject->bind ( $data ); if (! $this->joomlaUserObject->save ()) { // Try to load data of existing user using the email address as p.key $query = "SELECT *" . "\n FROM #__users" . "\n WHERE " . $this->db->quoteName('email') . " = " . $this->db->quote($email); $existingData = $this->db->setQuery($query)->loadAssoc(); $existingData['params'] = json_decode($existingData['params'], true); $this->joomlaUserObject->bind($existingData); } // Track auto created users from Facebook connect login into component db table $fbUsersTable = $this->app->bootComponent('com_jchat')->getMVCFactory()->createTable('Login', 'Administrator'); $fbUsersTable->j_uid = $this->joomlaUserObject->id; $fbUsersTable->fb_uid = $fbUserProfileArray['id']; $fbUsersTable->email = $email; $fbUsersTable->picture = $fbUserProfileArray['picture']; $fbUsersTable->first_name = isset($fbUserProfileArray['first_name']) ? $fbUserProfileArray['first_name'] : $name; $fbUsersTable->last_name = isset($fbUserProfileArray['last_name']) ? $fbUserProfileArray['last_name'] : $name; $fbUsersTable->name = isset($fbUserProfileArray['name']) ? $fbUserProfileArray['name'] : $name; $fbUsersTable->store(); // Call 3PD user integration function if($tpdIntegration = $cParams->get('3pdintegration', null)) { $this->userIntegration ( $tpdIntegration, $fbUsersTable, $this->joomlaUserObject ); } // Manage avatar import for the newly created user if($fbUsersTable->picture) { $this->importAvatar ( $fbUsersTable->picture ); } } } /** * onLogin handler * * @access protected * @param Object $this->joomlaUserObject * @param Object $cParams * @return null */ protected function onLogin($joomlaUserObject, $cParams) { $credentials = array (); $credentials ['username'] = $this->joomlaUserObject->username; // Check if existing user and overwrite mode, save the existing password $query = "SELECT " . $this->db->quoteName('password') . "\n FROM #__users" . "\n WHERE " . $this->db->quoteName('id') . " = " . (int)$joomlaUserObject->id; $this->db->setQuery ( $query ); $storedPassword = $this->db->loadResult (); // Reset a new user registration case $joomlaUserObject->password_clear = false; // If newly created user, we have a password clear already generated if($joomlaUserObject->password_clear) { $credentials ['password'] = $joomlaUserObject->password_clear; } else { // Generate and use a temp random password just to login on the fly $password = UserHelper::genRandomPassword(); $credentials ['password'] = $password; // Go on to generate a random password for this on the fly login $hashedPassword = UserHelper::hashPassword($password); $query = "UPDATE #__users" . "\n SET " . $this->db->quoteName('password') . " = " . $this->db->quote($hashedPassword) . "\n WHERE " . $this->db->quoteName('id') . " = " . (int)$joomlaUserObject->id; $this->db->setQuery ( $query ); $this->db->execute (); } $options = array (); $options ['remember'] = true; $options ['silent'] = true; // Disable the multilanguage plugin associations redirection and automatic_change $menu = $this->app->getMenu(); $activeMenu = $menu->getActive(); $activeMenu->getParams()->set('login_redirect_url', true); $loggedIn = $this->app->login ( $credentials, $options ); // Check if existing user and overwrite mode, restore the original password $query = "UPDATE #__users" . "\n SET " . $this->db->quoteName('password') . " = " . $this->db->quote($storedPassword) . "\n WHERE " . $this->db->quoteName('id') . " = " . (int)$joomlaUserObject->id; $this->db->setQuery ( $query ); $this->db->execute (); $redirectArray = $loggedIn ? array('msg'=>'', 'status'=>'') : array('msg'=>'COM_JCHAT_ERROR' . '_LOGIN', 'status'=>'error'); if(!$loggedIn) { $this->app->enqueueMessage(Text::_($redirectArray['msg']), $redirectArray['status']); } $this->app->redirect ( Uri::current(), 301); } /** * Main connector function * * @abstract * @access public * @return Void */ abstract public function execute(); /** * Class Constructor * @param Object $cParams * * @access public */ public function __construct($cParams) { $this->cParams = $cParams; $this->app = Factory::getApplication(); $this->joomlaUserObject = $this->app->getIdentity(); $this->db = Factory::getContainer()->get('DatabaseDriver'); } }PK!BvSS)system/jchatlogin/connectors/facebook.phpnu[joomlaUserObject->guest && ( bool ) $this->app->getInput()->getInt ( 'fblogin', false )) { try { $filter = InputFilter::getInstance (); // Instantiate main Facebook API library class object, pass in Application ID and secret doce $facebookAPI = new \JChatFacebook ( array ( 'appId' => $this->appId, 'secret' => $this->secret ) ); // Check if SSL peer verification is enabled if(!$this->cParams->get('curl_ssl_verifypeer', true)) { JChatFacebookBase::$CURL_OPTS[CURLOPT_SSL_VERIFYPEER] = false; } // Retrieve info about current Facebook user using API to get user integer identifier $fbUserID = $facebookAPI->getUser (); if(!$fbUserID) { throw new \Exception(Text::_('COM_JCHAT_FBUSERID_NOTFOUND')); } // Retrieve full Facebook user profile informations using Facebook API $fbUserProfileArray = $facebookAPI->api ( '/me?fields=id,email,name,first_name,last_name,picture' ); // Check if users exists already in the Joomla database using email address as primary key, retrieve user id if exists $authType = $this->cParams->get('auth_type', 'id'); $alreadyCreatedJoomlaUserID = JChatHelpersUsers::getJoomlaId ( $fbUserProfileArray [$authType], $authType ); if (! $alreadyCreatedJoomlaUserID) { $name = @$fbUserProfileArray ['name']; $username = strtolower ( $filter->clean ( @$fbUserProfileArray ['name'], 'cmd' ) ); // This Facebook account as no username, for example a Facebook page if (! $username) { $name = $fbUserProfileArray ['email']; $username = $fbUserProfileArray ['email']; } $password = UserHelper::genRandomPassword ( 5 ); $email = $fbUserProfileArray ['email'] ? $fbUserProfileArray ['email'] : $fbUserProfileArray ['id'] . '@facebook.com'; $fbUserProfileArray ['picture'] = 'https://graph.facebook.com/' .$fbUserProfileArray['id']. '/picture?type=normal'; // Trigger to create a new Joomla user aggregating data from Facebook user profile, pre-populate bind $this->joomlaUserObject $this->onNewUser( $this->joomlaUserObject, $name, $username, $password, $email, $fbUserProfileArray, $this->cParams ); // Do instant Joomla login authentication with new user, aggregated data and random generated password only for login purpouse $this->onLogin( $this->joomlaUserObject, $this->cParams ); } else { // get already populated $this->joomlaUserObject $this->joomlaUserObject = Factory::getContainer()->get(\Joomla\CMS\User\UserFactoryInterface::class)->loadUserById ( $alreadyCreatedJoomlaUserID ); // Do instant Joomla login authentication with new user, aggregated data and random generated password only for login purpouse $this->onLogin( $this->joomlaUserObject, $this->cParams ); } } catch ( \Exception $e ) { $this->app->enqueueMessage(Text::sprintf('COM_JCHAT_ERROR_FACEBOOK_LOGIN', $e->getMessage ()), 'warning'); } } } /** * Class Constructor * @param Object $cParams * * @access public */ public function __construct($cParams) { parent::__construct($cParams); $this->appId = $this->cParams->get('appId', null); $this->secret = $this->cParams->get('secret', null); // Load framework classes without autoloading require_once JPATH_ROOT . '/plugins/system/jchatlogin/social/facebook/base.php'; require_once JPATH_ROOT . '/plugins/system/jchatlogin/social/facebook/facebook.php'; require_once JPATH_ROOT . '/plugins/system/jchatlogin/social/facebook/exception.php'; } }PK!k!!'system/jchatlogin/connectors/index.htmlnu[ PK!#o,,system/jchatlogin/index.htmlnu[PK!Al7!! system/jchatlogin/jchatlogin.xmlnu[ System - JChatSocial login Joomla! Extensions Store 2022-08-16 Copyright (C) 2015 - Joomla! Extensions Store. All Rights Reserved. http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL info@storejextensions.org http://storejextensions.org 2.49 JChatSocial login jchatlogin.php connectors social index.html PK!Q))&system/sppagebuilder/sppagebuilder.phpnu[isClient('administrator')) { $integration = self::getIntegration(); if (!$integration) { return; } $input = $app->input; $option = $input->get('option', '', 'STRING'); $view = $input->get('view', '', 'STRING'); $id = $input->get($integration['id_alias'], 0, 'INT'); $layout = $input->get('layout', '', 'STRING'); if (!($option == 'com_' . $integration['group'] && $view == $integration['view'])) { return; } SppagebuilderHelper::loadAssets('css'); $doc = Factory::getDocument(); $doc->addScript(Uri::root(true) . '/plugins/system/sppagebuilder/assets/js/init.js?' . SppagebuilderHelper::getVersion(true)); $pagebuilder_enabled = 0; if ($page_content = self::getPageContent($option, $view, $id)) { $pagebuilder_enabled = (int) $page_content->active; } $integration_element = '.adminform'; if ($option == 'com_content') { $integration_element = '.adminform'; } else if ($option == 'com_k2') { $integration_element = '.k2ItemFormEditor'; } $doc->addScriptdeclaration('var spIntergationElement="' . $integration_element . '";'); $doc->addScriptdeclaration('var spPagebuilderEnabled=' . $pagebuilder_enabled . ';'); } else { $input = $app->input; $option = $input->get('option', '', 'STRING'); $view = $input->get('view', '', 'STRING'); $task = $input->get('task', '', 'STRING'); $id = $input->get('id', 0, 'INT'); $pageName = ''; if ($option == 'com_content' && $view == 'article') { $pageName = "{$view}-{$id}.css"; } elseif ($option == 'com_j2store' && $view == 'products' && $task == 'view') { $pageName = "article-{$id}.css"; } elseif ($option == 'com_k2' && $view == 'item') { $pageName = "item-{$id}.css"; } elseif ($option == 'com_sppagebuilder' && $view == 'page') { $pageName = "{$view}-{$id}.css"; } $file_path = JPATH_ROOT . '/media/sppagebuilder/css/' . $pageName; $file_url = Uri::base(true) . '/media/sppagebuilder/css/' . $pageName; if (file_exists($file_path)) { $doc = Factory::getDocument(); $doc->addStyleSheet($file_url); } } } function onAfterRender() { $app = Factory::getApplication(); if ($app->isClient('administrator')) { $integration = self::getIntegration(); if (!$integration) { return; } $input = $app->input; $option = $input->get('option', '', 'STRING'); $view = $input->get('view', '', 'STRING'); $layout = $input->get('layout', '', 'STRING'); $id = $input->get($integration['id_alias'], 0, 'INT'); if (!($option === 'com_' . $integration['group'] && $view === $integration['view'])) { return; } if (isset($integration['frontend_only']) && $integration['frontend_only']) { return; } // Page Builder state $pagebuilder_enabled = 0; $viewId = 0; if ($page_content = self::getPageContent($option, $view, $id)) { $viewId = $page_content->id; $pagebuilder_enabled = $page_content->active; } // Add script $body = $app->getBody(); $frontendEditorLink = 'index.php?option=com_sppagebuilder&view=form&tmpl=component&layout=edit&extension=com_content&extension_view=article&id=' . $viewId; $frontendEditorLink = str_replace('/administrator', '', SppagebuilderHelperRoute::buildRoute($frontendEditorLink)); if (!$viewId || !$pagebuilder_enabled) { $dashboardHTML = '
' . Text::_('Save the article first for getting the editor!') . '
'; } else { $dashboardHTML = 'Edit with SP Page Builder'; } if ($option === 'com_k2') { $body = str_replace('
', '
Joomla EditorEdit with SP Page Builder
', $body); } else { $body = str_replace('
', '
Joomla Editor SP Page Builder
', $body); } // Page Builder fields $body = str_replace('', '' . "\n", $body); $body = str_replace('', '' . "\n", $body); $app->setBody($body); } } private static function loadPageBuilderLanguage() { $lang = Factory::getLanguage(); $lang->load('com_sppagebuilder', JPATH_ADMINISTRATOR, $lang->getName(), true); $lang->load('tpl_' . self::getTemplate(), JPATH_SITE, $lang->getName(), true); require_once JPATH_ROOT . '/administrator/components/com_sppagebuilder/helpers/language.php'; } private static function getPageContent($extension = 'com_content', $extension_view = 'article', $view_id = 0) { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select($db->quoteName(array('id', 'text', 'active'))); $query->from($db->quoteName('#__sppagebuilder')); $query->where($db->quoteName('extension') . ' = ' . $db->quote($extension)); $query->where($db->quoteName('extension_view') . ' = ' . $db->quote($extension_view)); $query->where($db->quoteName('view_id') . ' = ' . $view_id); $db->setQuery($query); $result = $db->loadObject(); if ($result) { return $result; } return false; } private static function getIntegration() { $app = Factory::getApplication(); $option = $app->input->get('option', '', 'STRING'); $group = str_replace('com_', '', $option); $integrations = BuilderIntegrationHelper::getIntegrations(); if (!isset($integrations[$group])) { return false; } $integration = $integrations[$group]; $name = $integration['name']; $enabled = PluginHelper::isEnabled($group, $name); if ($enabled) { return $integration; } return false; } private static function getTemplate() { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select($db->quoteName(array('template'))); $query->from($db->quoteName('#__template_styles')); $query->where($db->quoteName('client_id') . ' = ' . $db->quote(0)); $query->where($db->quoteName('home') . ' = ' . $db->quote(1)); $db->setQuery($query); return $db->loadResult(); } public function onExtensionAfterSave($option, $data) { if (($option === 'com_config.component') && ($data->element === 'com_sppagebuilder')) { $admin_cache = JPATH_ROOT . '/administrator/cache/sppagebuilder'; if (\file_exists($admin_cache)) { Folder::delete($admin_cache); } $site_cache = JPATH_ROOT . '/cache/sppagebuilder'; if (\file_exists($site_cache)) { Folder::delete($site_cache); } } } } PK!:&system/sppagebuilder/assets/js/init.jsnu[jQuery(document).ready(function ($) { if (spPagebuilderEnabled) { $(spIntergationElement).hide(); $(".builder-integration-component").show(); $(".builder-integration-button-editor").addClass("is-active"); } else { $(".builder-integration-component").hide(); $(spIntergationElement).show(); $(".builder-integration-button-joomla").addClass("is-active"); } $("[action-switch-builder]").on("click", function (event) { event.preventDefault(); $("[action-switch-builder]").removeClass("is-active"); $(this).addClass("is-active"); var action = $(this).data("action"); // get shared parent container var $container = $(this).parent(".sp-pagebuilder-btn-group").parent(); if (action === "editor") { $(".builder-integration-component").hide(); $(spIntergationElement).show(); $("#jform_attribs_sppagebuilder_active").val("0"); if (typeof WFEditor !== "undefined") { $(".wf-editor", $container).each(function () { var value = this.nodeName === "TEXTAREA" ? this.value : this.innerHTML; // pass content from textarea to editor Joomla.editors.instances[this.id].setValue(value); // show editor and tabs $(this).parent(".wf-editor-container").show(); }); } } else { if (typeof WFEditor !== "undefined") { $(".wf-editor", $container).each(function () { // pass content to textarea Joomla.editors.instances[this.id].getValue(); // hide editor and tabs $(this).parent(".wf-editor-container").hide(); }); } $(spIntergationElement).hide(); $(".builder-integration-component").show(); $("#jform_attribs_sppagebuilder_active").val("1"); } }); }); PK!o,&system/sppagebuilder/sppagebuilder.xmlnu[ System - SP PageBuilder JoomShaper.com Sep 2016 Copyright (C) 2010 - 2023 JoomShaper. All rights reserved. http://www.gnu.org/licenses/gpl-2.0.html GPLv2 or later support@joomshaper.com www.joomshaper.com 4.0.8 SP Page Builder System plugin to add support for 3rd party components sppagebuilder.php assets PK!5`CC)system/languagecode/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\LanguageCode\Extension\LanguageCode; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new LanguageCode( $dispatcher, (array) PluginHelper::getPlugin('system', 'languagecode') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!h$system/languagecode/languagecode.xmlnu[ plg_system_languagecode Joomla! Project 2011-11 (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_SYSTEM_LANGUAGECODE_XML_DESCRIPTION Joomla\Plugin\System\LanguageCode services src language/en-GB/plg_system_languagecode.ini language/en-GB/plg_system_languagecode.sys.ini PK!߈82system/languagecode/src/Extension/LanguageCode.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\LanguageCode\Extension; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\LanguageHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Language Code plugin class. * * @since 2.5 */ final class LanguageCode extends CMSPlugin { /** * Plugin that changes the language code used in the tag. * * @return void * * @since 2.5 */ public function onAfterRender() { // Use this plugin only in site application. if ($this->getApplication()->isClient('site')) { // Get the response body. $body = $this->getApplication()->getBody(); // Get the current language code. $code = $this->getApplication()->getDocument()->getLanguage(); // Get the new code. $new_code = $this->params->get($code); // Replace the old code by the new code in the tag. if ($new_code) { // Replace the new code in the HTML document. $patterns = [ chr(1) . '()' . chr(1) . 'i', chr(1) . '()' . chr(1) . 'i', ]; $replace = [ '${1}' . strtolower($new_code) . '${3}', '${1}' . strtolower($new_code) . '${3}', ]; } else { $patterns = []; $replace = []; } // Replace codes in attributes. preg_match_all(chr(1) . '()' . chr(1) . 'i', $body, $matches); foreach ($matches[2] as $match) { $new_code = $this->params->get(strtolower($match)); if ($new_code) { $patterns[] = chr(1) . '()' . chr(1) . 'i'; $replace[] = '${1}' . $new_code . '${3}'; } } preg_match_all(chr(1) . '()' . chr(1) . 'i', $body, $matches); foreach ($matches[2] as $match) { $new_code = $this->params->get(strtolower($match)); if ($new_code) { $patterns[] = chr(1) . '()' . chr(1) . 'i'; $replace[] = '${1}' . $new_code . '${3}'; } } // Replace codes in itemprop content preg_match_all(chr(1) . '()' . chr(1) . 'i', $body, $matches); foreach ($matches[2] as $match) { $new_code = $this->params->get(strtolower($match)); if ($new_code) { $patterns[] = chr(1) . '()' . chr(1) . 'i'; $replace[] = '${1}' . $new_code . '${3}'; } } $this->getApplication()->setBody(preg_replace($patterns, $replace, $body)); } } /** * Prepare form. * * @param Form $form The form to be altered. * @param mixed $data The associated data for the form. * * @return boolean * * @since 2.5 */ public function onContentPrepareForm(Form $form, $data) { // Check we are manipulating the languagecode plugin. if ($form->getName() !== 'com_plugins.plugin' || !$form->getField('languagecodeplugin', 'params')) { return true; } // Get site languages. if ($languages = LanguageHelper::getKnownLanguages(JPATH_SITE)) { // Inject fields into the form. foreach ($languages as $tag => $language) { $form->load('
'); } } return true; } } PK!ھ system/tgeoip/tgeoip.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined( '_JEXEC' ) or die( 'Restricted access' ); class plgSystemTGeoIP extends JPlugin { /** * Joomla Application Object * * @var object */ protected $app; /** * Auto load plugin language * * @var boolean */ protected $autoloadLanguage = true; /** * GeoIP Class * * @var object */ private $geoIP; /** * Load GeoIP Classes * * @return void */ private function loadGeoIP() { $path = JPATH_PLUGINS . '/system/tgeoip'; if (!class_exists('TGeoIP')) { if (@file_exists($path . '/helper/tgeoip.php')) { if (@include_once($path . '/vendor/autoload.php')) { @include_once $path . '/helper/tgeoip.php'; } } } $this->geoIP = new TGeoIP(); } /** * Listens to AJAX requests on ?option=com_ajax&format=raw&plugin=tgeoip * * @return void */ public function onAjaxTgeoip() { JSession::checkToken('request') or die('Invalid Token'); // Only in admin if (!$this->app->isClient('administrator')) { return; } $this->loadGeoIP(); $task = $this->app->input->get('task', 'update'); $this->geoIP->setKey($this->app->input->get('license_key', '')); switch ($task) { // Update database and redirect case 'update-red': $result = $this->geoIP->updateDatabase(); if ($result === true) { $msg = JText::_('PLG_SYSTEM_TGEOIP_DATABASE_UPDATED'); $msgType = 'message'; } else { $msgType = 'error'; $msg = $result; } $return = base64_decode($this->app->input->get->getBase64('return', null)); $this->app->enqueueMessage($msg, $msgType); $this->app->redirect($return); break; // Update database case 'update': echo $this->geoIP->updateDatabase(); break; // IP Lookup case 'get': $ip = $this->app->input->get('ip'); echo json_encode($this->geoIP->setIP($ip)->getRecord()); break; } } } PK!P 8system/tgeoip/language/en-GB/en-GB.plg_system_tgeoip.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos ; @link http://www.tassos.gr ; @copyright Copyright © 2020 Tassos Marinos All Rights Reserved ; @license GNU GPLv3 or later TGEOIP="Tassos.gr GeoIP Plugin" PLG_SYSTEM_TGEOIP="System - Tassos.gr GeoIP Plugin" PLG_SYSTEM_TGEOIP_DESC="This plugin provides GeoIP features (finding out the country of an IP address) for Tassos.gr extensions. Without it the GeoIP features will not be available. This plugin includes GeoLite2 data created by MaxMind http://www.maxmind.com." PLG_SYSTEM_TGEOIP_ERR_NOGZSUPPORT="Your server does not support extraction of GZip (.gz) files. The GeoLite2 Country database update cannot proceed." PLG_SYSTEM_TGEOIP_ERR_EMPTYDOWNLOAD="Downloading the GeoLite2 Country database failed: empty file retrieved from server. Please contact your host." PLG_SYSTEM_TGEOIP_ERR_WRITEFAILED="Writing the temporary file failed. Please make sure that the temporary directory defined in your site's Global Configuration is writeable. The GeoLite2 Country database update cannot proceed." PLG_SYSTEM_TGEOIP_ERR_CANTUNCOMPRESS="Cannot decompress the GeoLite2 Country database file. Probably a corrupt download? The GeoLite2 Country database update cannot proceed." PLG_SYSTEM_TGEOIP_ERR_MAXMINDRATELIMIT="MaxMind's servers are busy. Please retry updating the GeoLite2 Country database in 24 hours." PLG_SYSTEM_TGEOIP_ERR_MAXMIND_GENERIC="A connection error occurred. Please retry updating the GeoLite2 Country database in 24 hours." PLG_SYSTEM_TGEOIP_ERR_INVALIDDB="Downloaded database seems to be invalid. Please retry updating the GeoLite2 Country database in 24 hours." PLG_SYSTEM_TGEOIP_ERR_WRONG_LICENSE_KEY="Your MaxMind license key appears to be incorrect." PLG_SYSTEM_TGEOIP_ERR_CANTWRITE="Moving the database file failed. Please make sure that the database directory is writeable: %s" PLG_SYSTEM_TGEOIP_UPDATE_DATABASE="Update Database" PLG_SYSTEM_TGEOIP_UPDATE_DATABASE_DESC="Update the GeoLite2 database from MaxMind servers. This might take several seconds to finish. Please be patient." PLG_SYSTEM_TGEOIP_DATABASE="Database" PLG_SYSTEM_TGEOIP_LAST_UPDATED="Last Updated" PLG_SYSTEM_TGEOIP_LAST_UPDATED_DESC="Indicates the last datetime the database updated." PLG_SYSTEM_TGEOIP_CHECK_IP="Lookup IP Address" PLG_SYSTEM_TGEOIP_CHECK_IP_DESC="Test drive the GeoIP plugin by looking up an IP address." PLG_SYSTEM_TGEOIP_MAINTENANCE="GeoIP Database Maintenance" PLG_SYSTEM_TGEOIP_MAINTENANCE_DESC="%s finds the country of your visitors' IP addresses using the MaxMind GeoLite2 Country database. You are advised to update it at least once per month. On most servers you can perform the update by clicking the button below." PLG_SYSTEM_TGEOIP_DATABASE_UPDATED="GeoIP database successfully updated!" PLG_SYSTEM_TGEOIP_LICENSE_KEY="License Key" PLG_SYSTEM_TGEOIP_LICENSE_KEY_DESC="Get your free License Key to download the latest MaxMind GeoLite2 Database." PLG_SYSTEM_TGEOIP_LICENSE_KEY_GET="Get a free License Key" PLG_SYSTEM_TGEOIP_LICENSE_KEY_EMPTY="Please enter a valid MaxMind License Key." PLG_SYSTEM_TGEOIP_ENABLE_PLUGIN="To be able to update the database you will need to enable this plugin first" PLG_SYSTEM_TGEOIP_ENABLE_DOC_LINK_LABEL="Click to learn how to enable Geolocation features in Tassos.gr extensions" PLG_SYSTEM_TGEOIP_PLEASE_WAIT="Please wait..."PK!Ю<system/tgeoip/language/en-GB/en-GB.plg_system_tgeoip.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos ; @link http://www.tassos.gr ; @copyright Copyright © 2020 Tassos Marinos All Rights Reserved ; @license GNU GPLv3 or later TGEOIP="Tassos.gr GeoIP Plugin" PLG_SYSTEM_TGEOIP="System - Tassos.gr GeoIP Plugin" PLG_SYSTEM_TGEOIP_DESC="This plugin provides GeoIP features (finding out the country of an IP address) for Tassos.gr extensions. Without it the GeoIP features will not be available. This plugin includes GeoLite2 data created by MaxMind http://www.maxmind.com."PK!1PK!U###system/tgeoip/field/lastupdated.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; class JFormFieldTG_LastUpdated extends JFormField { /** * Method to render the input field * * @return string */ public function getInput() { $file = JPATH_PLUGINS . '/system/tgeoip/db/GeoLite2-City.mmdb'; if (!JFile::exists($file)) { return ''; } return JFactory::getDate(@filemtime($file))->format('d M Y H:m'); } }PK!%z$system/tgeoip/field/updatebutton.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; class JFormFieldTG_UpdateButton extends JFormField { /** * Method to render the input field * * @return string */ public function getInput() { if (!NRFramework\Extension::pluginIsEnabled('tgeoip')) { return '' . JText::_('PLG_SYSTEM_TGEOIP_ENABLE_PLUGIN') . ''; } JHtml::stylesheet('plg_system_nrframework/joomla4.css', ['relative' => true, 'version' => 'auto']); $ajaxURL = JURI::base() . 'index.php?option=com_ajax&format=raw&plugin=tgeoip&task=update&license_key=USER_LICENSE_KEY&' . JSession::getFormToken() . '=1'; JText::script('PLG_SYSTEM_TGEOIP_DATABASE_UPDATED'); JText::script('PLG_SYSTEM_TGEOIP_PLEASE_WAIT'); JFactory::getDocument()->addScriptDeclaration(' document.addEventListener("DOMContentLoaded", function() { document.addEventListener("click", function(e) { var btn = e.target.closest(".geo button"); if (!btn) { return; } e.preventDefault(); var license_key = e.target.closest("form").querySelector("#jform_params_license_key").value; if (!license_key) { return; } var alert = document.querySelector(".geo .alert"); var url = "' . $ajaxURL . '"; url = url.replace("USER_LICENSE_KEY", license_key); // before request alert.style.display = "none"; btn.querySelector("span").innerHTML = Joomla.JText._("PLG_SYSTEM_TGEOIP_PLEASE_WAIT"); btn.classList.add("btn-working"); fetch(url, { method: "POST" }) .then(function(res){ return res.text(); }) .then(function(response){ if (response == "1") { alert.innerHTML = Joomla.JText._("PLG_SYSTEM_TGEOIP_DATABASE_UPDATED"); alert.style.display = "block"; alert.classList.remove("alert-danger"); alert.classList.add("alert-success"); } else { alert.innerHTML = response; alert.style.display = "block"; alert.classList.remove("alert-success"); alert.classList.add("alert-danger"); } btn.classList.remove("btn-working"); btn.querySelector("span").innerHTML = btn.dataset.label; }); return false; }); }); '); JFactory::getDocument()->addStyleDeclaration(' .geo .btn-working { pointer-events:none; } .geo .alert { display:none; margin-bottom: 10px; } .geo button { outline:none !important; width: auto; height: auto; line-height: inherit; } .geo button:before { margin-right:5px; position:relative; top:1px; } #wrapper .geo .icon-refresh { margin-right: 5px; } '); return '
'; } }PK! ((system/tgeoip/field/lookup.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access to this file defined('_JEXEC') or die; use NRFramework\User; class JFormFieldTG_Lookup extends JFormField { /** * GeoIP Class * * @var object */ private $geoIP; /** * Method to render the input field * * @return string */ public function getInput() { // JavaScript $ajaxURL = JURI::base() . 'index.php?option=com_ajax&format=raw&plugin=tgeoip&task=get&' . JSession::getFormToken() . '=1'; JFactory::getDocument()->addScriptDeclaration(' document.addEventListener("DOMContentLoaded", function() { document.addEventListener("click", function(e) { var btn = e.target.closest(".tGeoIPtest button"); if (!btn) { return; } e.preventDefault(); ip = document.querySelector(".tGeoIPtest input").value; if (!ip) { alert("Please enter a valid IP address"); return false; } var data = new FormData(); data.append("ip", ip); fetch("' . $ajaxURL . '", { method: "POST", body: data }) .then(function(res){ return res.json(); }) .then(function(response){ if (response) { if (response.continent) { document.querySelector(".tGeoIPtest .continent").innerHTML = response.continent.names.en; } if (response.city) { document.querySelector(".tGeoIPtest .city").innerHTML = response.city.names.en; } if (response.country) { document.querySelector(".tGeoIPtest .country").innerHTML = response.country.names.en; document.querySelector(".tGeoIPtest .country_code").innerHTML = response.country.iso_code; } document.querySelector(".tGeoIPtest .results").style.display = "block"; } else { alert("Invalid IP address"); document.querySelector(".tGeoIPtest .results").style.display = "none"; } }) return false; }) }); '); // HTML $ip = User::getIP(); return '
'; } }PK!s,w9w9'system/tgeoip/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgSystemTgeoipInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!00,system/tgeoip/vendor/geoip2/geoip2/README.mdnu[# GeoIP2 PHP API # ## Description ## This package provides an API for the GeoIP2 [web services](http://dev.maxmind.com/geoip/geoip2/web-services) and [databases](http://dev.maxmind.com/geoip/geoip2/downloadable). The API also works with the free [GeoLite2 databases](http://dev.maxmind.com/geoip/geoip2/geolite2/). ## Install via Composer ## We recommend installing this package with [Composer](http://getcomposer.org/). ### Download Composer ### To download Composer, run in the root directory of your project: ```bash curl -sS https://getcomposer.org/installer | php ``` You should now have the file `composer.phar` in your project directory. ### Install Dependencies ### Run in your project root: ``` php composer.phar require geoip2/geoip2:~2.0 ``` You should now have the files `composer.json` and `composer.lock` as well as the directory `vendor` in your project directory. If you use a version control system, `composer.json` should be added to it. ### Require Autoloader ### After installing the dependencies, you need to require the Composer autoloader from your code: ```php require 'vendor/autoload.php'; ``` ## Install via Phar ## Although we strongly recommend using Composer, we also provide a [phar archive](http://php.net/manual/en/book.phar.php) containing all of the dependencies for GeoIP2. Our latest phar archive is available on [our releases page](https://github.com/maxmind/GeoIP2-php/releases). To use the archive, just require it from your script: ```php require 'geoip2.phar'; ``` ## Optional C Extension ## The [MaxMind DB API](https://github.com/maxmind/MaxMind-DB-Reader-php) includes an optional C extension that you may install to dramatically increase the performance of lookups in GeoIP2 or GeoLite2 databases. To install, please follow the instructions included with that API. The extension has no effect on web-service lookups. ## IP Geolocation Usage ## IP geolocation is inherently imprecise. Locations are often near the center of the population. Any location provided by a GeoIP2 database or web service should not be used to identify a particular address or household. ## Database Reader ## ### Usage ### To use this API, you must create a new `\GeoIp2\Database\Reader` object with the path to the database file as the first argument to the constructor. You may then call the method corresponding to the database you are using. If the lookup succeeds, the method call will return a model class for the record in the database. This model in turn contains multiple container classes for the different parts of the data such as the city in which the IP address is located. If the record is not found, a `\GeoIp2\Exception\AddressNotFoundException` is thrown. If the database is invalid or corrupt, a `\MaxMind\Db\InvalidDatabaseException` will be thrown. See the API documentation for more details. ### City Example ### ```php city('128.101.101.101'); print($record->country->isoCode . "\n"); // 'US' print($record->country->name . "\n"); // 'United States' print($record->country->names['zh-CN'] . "\n"); // '美国' print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota' print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN' print($record->city->name . "\n"); // 'Minneapolis' print($record->postal->code . "\n"); // '55455' print($record->location->latitude . "\n"); // 44.9733 print($record->location->longitude . "\n"); // -93.2323 ``` ### Anonymous IP Example ### ```php anonymousIp('128.101.101.101'); if ($record->isAnonymous) { print "anon\n"; } print($record->ipAddress . "\n"); // '128.101.101.101' ``` ### Connection-Type Example ### ```php connectionType('128.101.101.101'); print($record->connectionType . "\n"); // 'Corporate' print($record->ipAddress . "\n"); // '128.101.101.101' ``` ### Domain Example ### ```php domain('128.101.101.101'); print($record->domain . "\n"); // 'umn.edu' print($record->ipAddress . "\n"); // '128.101.101.101' ``` ### Enterprise Example ### ```php enterprise method to do a lookup in the Enterprise database $record = $reader->enterprise('128.101.101.101'); print($record->country->confidence . "\n"); // 99 print($record->country->isoCode . "\n"); // 'US' print($record->country->name . "\n"); // 'United States' print($record->country->names['zh-CN'] . "\n"); // '美国' print($record->mostSpecificSubdivision->confidence . "\n"); // 77 print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota' print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN' print($record->city->confidence . "\n"); // 60 print($record->city->name . "\n"); // 'Minneapolis' print($record->postal->code . "\n"); // '55455' print($record->location->accuracy_radius . "\n"); // 50 print($record->location->latitude . "\n"); // 44.9733 print($record->location->longitude . "\n"); // -93.2323 ``` ### ISP Example ### ```php isp('128.101.101.101'); print($record->autonomousSystemNumber . "\n"); // 217 print($record->autonomousSystemOrganization . "\n"); // 'University of Minnesota' print($record->isp . "\n"); // 'University of Minnesota' print($record->organization . "\n"); // 'University of Minnesota' print($record->ipAddress . "\n"); // '128.101.101.101' ``` ## Web Service Client ## ### Usage ### To use this API, you must create a new `\GeoIp2\WebService\Client` object with your `$userId` and `$licenseKey`, then you call the method corresponding to a specific end point, passing it the IP address you want to look up. If the request succeeds, the method call will return a model class for the end point you called. This model in turn contains multiple record classes, each of which represents part of the data returned by the web service. If there is an error, a structured exception is thrown. See the API documentation for more details. ### Example ### ```php city('128.101.101.101'); print($record->country->isoCode . "\n"); // 'US' print($record->country->name . "\n"); // 'United States' print($record->country->names['zh-CN'] . "\n"); // '美国' print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota' print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN' print($record->city->name . "\n"); // 'Minneapolis' print($record->postal->code . "\n"); // '55455' print($record->location->latitude . "\n"); // 44.9733 print($record->location->longitude . "\n"); // -93.2323 ``` ## Values to use for Database or Array Keys ## **We strongly discourage you from using a value from any `names` property as a key in a database or array.** These names may change between releases. Instead we recommend using one of the following: * `GeoIp2\Record\City` - `$city->geonameId` * `GeoIp2\Record\Continent` - `$continent->code` or `$continent->geonameId` * `GeoIp2\Record\Country` and `GeoIp2\Record\RepresentedCountry` - `$country->isoCode` or `$country->geonameId` * `GeoIp2\Record\Subdivision` - `$subdivision->isoCode` or `$subdivision->geonameId` ### What data is returned? ### While many of the end points return the same basic records, the attributes which can be populated vary between end points. In addition, while an end point may offer a particular piece of data, MaxMind does not always have every piece of data for any given IP address. Because of these factors, it is possible for any end point to return a record where some or all of the attributes are unpopulated. See the [GeoIP2 Precision web service docs](http://dev.maxmind.com/geoip/geoip2/web-services) for details on what data each end point may return. The only piece of data which is always returned is the `ipAddress` attribute in the `GeoIp2\Record\Traits` record. ## Integration with GeoNames ## [GeoNames](http://www.geonames.org/) offers web services and downloadable databases with data on geographical features around the world, including populated places. They offer both free and paid premium data. Each feature is unique identified by a `geonameId`, which is an integer. Many of the records returned by the GeoIP2 web services and databases include a `geonameId` property. This is the ID of a geographical feature (city, region, country, etc.) in the GeoNames database. Some of the data that MaxMind provides is also sourced from GeoNames. We source things like place names, ISO codes, and other similar data from the GeoNames premium data set. ## Reporting data problems ## If the problem you find is that an IP address is incorrectly mapped, please [submit your correction to MaxMind](http://www.maxmind.com/en/correction). If you find some other sort of mistake, like an incorrect spelling, please check the [GeoNames site](http://www.geonames.org/) first. Once you've searched for a place and found it on the GeoNames map view, there are a number of links you can use to correct data ("move", "edit", "alternate names", etc.). Once the correction is part of the GeoNames data set, it will be automatically incorporated into future MaxMind releases. If you are a paying MaxMind customer and you're not sure where to submit a correction, please [contact MaxMind support](http://www.maxmind.com/en/support) for help. ## Other Support ## Please report all issues with this code using the [GitHub issue tracker](https://github.com/maxmind/GeoIP2-php/issues). If you are having an issue with a MaxMind service that is not specific to the client API, please see [our support page](http://www.maxmind.com/en/support). ## Requirements ## This code requires PHP 5.3 or greater. Older versions of PHP are not supported. This library works and is tested with HHVM. This library also relies on the [MaxMind DB Reader](https://github.com/maxmind/MaxMind-DB-Reader-php). If you are using PHP 5.3 with an autoloader besides Composer, you must load `JsonSerializable.php` in the `compat` directory. ## Contributing ## Patches and pull requests are encouraged. All code should follow the PSR-2 style guidelines. Please include unit tests whenever possible. You may obtain the test data for the maxmind-db folder by running `git submodule update --init --recursive` or adding `--recursive` to your initial clone, or from https://github.com/maxmind/MaxMind-DB ## Versioning ## The GeoIP2 PHP API uses [Semantic Versioning](http://semver.org/). ## Copyright and License ## This software is Copyright (c) 2013-2016 by MaxMind, Inc. This is free software, licensed under the Apache License, Version 2.0. PK!$0system/tgeoip/vendor/geoip2/geoip2/composer.jsonnu[{ "name": "geoip2/geoip2", "description": "MaxMind GeoIP2 PHP API", "keywords": ["geoip", "geoip2", "geolocation", "ip", "maxmind"], "homepage": "https://github.com/maxmind/GeoIP2-php", "type": "library", "license": "Apache-2.0", "authors": [ { "name": "Gregory J. Oschwald", "email": "goschwald@maxmind.com", "homepage": "http://www.maxmind.com/" } ], "require": { "maxmind-db/reader": "~1.0", "maxmind/web-service-common": "~0.3", "php": ">=5.3.1" }, "require-dev": { "phpunit/phpunit": "4.2.*", "squizlabs/php_codesniffer": "2.*" }, "autoload": { "psr-4": { "GeoIp2\\": "src" } } } PK!99/system/tgeoip/vendor/geoip2/geoip2/CHANGELOG.mdnu[CHANGELOG ========= 2.4.5 (2017-01-31) ------------------ * Additional error checking on the data returned from `MaxMind\Db\Reader` was added to help detect corrupt databases. GitHub #83. 2.4.4 (2016-10-11) ------------------ * `isset()` on `mostSpecificSubdivision` attribute now returns the correct value. Reported by Juan Francisco Giordana. GitHub #81. 2.4.3 (2016-10-11) ------------------ * `isset()` on `name` attribute now returns the correct value. Reported by Juan Francisco Giordana. GitHub #79. 2.4.2 (2016-08-17) ------------------ * Updated documentation to clarify what the accuracy radius refers to. * Upgraded `maxmind/web-service-common` to 0.3.0. This version uses `composer/ca-bundle` rather than our own CA bundle. GitHub #75. * Improved PHP documentation generation. 2.4.1 (2016-06-10) ------------------ * Corrected type annotations in documentation. GitHub #66. * Updated documentation to reflect that the accuracy radius is now included in City. * Upgraded web service client, which supports setting a proxy. GitHub #59. 2.4.0 (2016-04-15) ------------------ * Added support for the GeoIP2 Enterprise database. 2.3.3 (2015-09-24) ------------------ * Corrected case on `JsonSerializable` interface. Reported by Axel Etcheverry. GitHub #56. 2.3.2 (2015-09-23) ------------------ * `JsonSerializable` compatibility interface was moved to `GeoIp2\Compat` rather than the global namespace to prevent autoloading issues. Reported by Tomas Buteler. GitHub #54. * Missing documentation for the `$postal` property was added to the `GeoIp2\Model\City` class. Fix by Roy Sindre Norangshol. GitHub #51. * In the Phar distribution, source files for this module no longer have their documentation stripped, allowing IDE introspection to work properly. Reported by Dominic Black. GitHub #52. 2.3.1 (2015-06-30) ------------------ * Updated `maxmind/web-service-common` to version with fixes for PHP 5.3 and 5.4. 2.3.0 (2015-06-29) ------------------ * Support for demographics fields `averageIncome` and `populationDensity` in the `Location` record, returned by the Insights endpoint. * The `isAnonymousProxy` and `isSatelliteProvider` properties on `GeoIP2\Record\Traits` have been deprecated. Please use our [GeoIP2 Anonymous IP database](https://www.maxmind.com/en/geoip2-anonymous-ip-database) to determine whether an IP address is used by an anonymizing service. 2.2.0-beta1 (2015-06-09) ------------------------ * Typo fix in documentation. 2.2.0-alpha2 (2015-06-01) ------------------------- * `maxmind-ws/web-service-common` was renamed to `maxmind/web-service-common`. 2.2.0-alpha1 (2015-05-22) ------------------------- * The library no longer uses Guzzle and instead uses curl directly. * Support for `timeout` and `connectTimout` were added to the `$options` array passed to the `GeoIp2\WebService\Client` constructor. Pull request by Will Bradley. GitHub #36. 2.1.1 (2014-12-03) ------------------ * The 2.1.0 Phar builds included a shebang line, causing issues when loading it as a library. This has been corrected. GitHub #33. 2.1.0 (2014-10-29) ------------------ * Update ApiGen dependency to version that isn't broken on case sensitive file systems. * Added support for the GeoIP2 Anonymous IP database. The `GeoIP2\Database\Reader` class now has an `anonymousIp` method which returns a `GeoIP2\Model\AnonymousIp` object. * Boolean attributes like those in the `GeoIP2\Record\Traits` class now return `false` instead of `null` when they were not true. 2.0.0 (2014-09-22) ------------------ * First production release. 0.9.0 (2014-09-15) ------------------ * IMPORTANT: The deprecated `omni()` and `cityIspOrg()` methods have been removed from `GeoIp2\WebService\Client`. 0.8.1 (2014-09-12) ------------------ * The check added to the `GeoIP2\Database\Reader` lookup methods in 0.8.0 did not work with the GeoIP2 City Database Subset by Continent with World Countries. This has been fixed. Fixes GitHub issue #23. 0.8.0 (2014-09-10) ------------------ * The `GeoIp2\Database\Reader` lookup methods (e.g., `city()`, `isp()`) now throw a `BadMethodCallException` if they are used with a database that does not match the method. In particular, doing a `city()` lookup on a GeoIP2 Country database will result in an exception, and vice versa. * A `metadata()` method has been added to the `GeoIP2\Database\Reader` class. This returns a `MaxMind\Db\Reader\Metadata` class with information about the database. * The name attribute was missing from the RepresentedCountry class. 0.7.0 (2014-07-22) ------------------ * The web service client API has been updated for the v2.1 release of the web service. In particular, the `cityIspOrg` and `omni` methods on `GeoIp2\WebService\Client` should be considered deprecated. The `city` method now provides all of the data formerly provided by `cityIspOrg`, and the `omni` method has been replaced by the `insights` method. * Support was added for GeoIP2 Connection Type, Domain and ISP databases. 0.6.3 (2014-05-12) ------------------ * With the previous Phar builds, some users received `phar error: invalid url or non-existent phar` errors. The correct alias is now used for the Phar, and this should no longer be an issue. 0.6.2 (2014-05-08) ------------------ * The Phar build was broken with Guzzle 3.9.0+. This has been fixed. 0.6.1 (2014-05-01) ------------------ * This API now officially supports HHVM. * The `maxmind-db/reader` dependency was updated to a version that does not require BC Math. * The Composer compatibility autoload rules are now targeted more narrowly. * A `box.json` file is included to build a Phar package. 0.6.0 (2014-02-19) ------------------ * This API is now licensed under the Apache License, Version 2.0. * Model and record classes now implement `JsonSerializable`. * `isset` now works with model and record classes. 0.5.0 (2013-10-21) ------------------ * Renamed $languages constructor parameters to $locales for both the Client and Reader classes. * Documentation and code clean-up (Ben Morel). * Added the interface `GeoIp2\ProviderInterface`, which is implemented by both `\GeoIp2\Database\Reader` and `\GeoIp2\WebService\Client`. 0.4.0 (2013-07-16) ------------------ * This is the first release with the GeoIP2 database reader. Please see the `README.md` file and the `\GeoIp2\Database\Reader` class. * The general exception classes were replaced with specific exception classes representing particular types of errors, such as an authentication error. 0.3.0 (2013-07-12) ------------------ * In namespaces and class names, "GeoIP2" was renamed to "GeoIp2" to improve consistency. 0.2.1 (2013-06-10) ------------------ * First official beta release. * Documentation updates and corrections. 0.2.0 (2013-05-29) ------------------ * `GenericException` was renamed to `GeoIP2Exception`. * We now support more languages. The new languages are de, es, fr, and pt-BR. * The REST API now returns a record with data about your account. There is a new `GeoIP\Records\MaxMind` class for this data. * The `continentCode` attribute on `Continent` was renamed to `code`. * Documentation updates. 0.1.1 (2013-05-14) ------------------ * Updated Guzzle version requirement. * Fixed Composer example in README.md. 0.1.0 (2013-05-13) ------------------ * Initial release. PK!z:Jsystem/tgeoip/vendor/geoip2/geoip2/src/Exception/OutOfQueriesException.phpnu[Lsystem/tgeoip/vendor/geoip2/geoip2/src/Exception/AuthenticationException.phpnu[error = $error; parent::__construct($message, $httpStatus, $uri, $previous); } } PK!SwMsystem/tgeoip/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.phpnu[uri = $uri; parent::__construct($message, $httpStatus, $previous); } } PK!Գ(g g :system/tgeoip/vendor/geoip2/geoip2/src/Database/Reader.phpnu[dbReader = new DbReader($filename); $this->locales = $locales; } /** * This method returns a GeoIP2 City model. * * @param string $ipAddress IPv4 or IPv6 address as a string. * * @return \GeoIp2\Model\City * * @throws \GeoIp2\Exception\AddressNotFoundException if the address is * not in the database. * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database * is corrupt or invalid */ public function city($ipAddress) { return $this->modelFor('City', 'City', $ipAddress); } /** * This method returns a GeoIP2 Country model. * * @param string $ipAddress IPv4 or IPv6 address as a string. * * @return \GeoIp2\Model\Country * * @throws \GeoIp2\Exception\AddressNotFoundException if the address is * not in the database. * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database * is corrupt or invalid */ public function country($ipAddress) { return $this->modelFor('Country', 'Country', $ipAddress); } /** * This method returns a GeoIP2 Anonymous IP model. * * @param string $ipAddress IPv4 or IPv6 address as a string. * * @return \GeoIp2\Model\AnonymousIp * * @throws \GeoIp2\Exception\AddressNotFoundException if the address is * not in the database. * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database * is corrupt or invalid */ public function anonymousIp($ipAddress) { return $this->flatModelFor( 'AnonymousIp', 'GeoIP2-Anonymous-IP', $ipAddress ); } /** * This method returns a GeoIP2 Connection Type model. * * @param string $ipAddress IPv4 or IPv6 address as a string. * * @return \GeoIp2\Model\ConnectionType * * @throws \GeoIp2\Exception\AddressNotFoundException if the address is * not in the database. * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database * is corrupt or invalid */ public function connectionType($ipAddress) { return $this->flatModelFor( 'ConnectionType', 'GeoIP2-Connection-Type', $ipAddress ); } /** * This method returns a GeoIP2 Domain model. * * @param string $ipAddress IPv4 or IPv6 address as a string. * * @return \GeoIp2\Model\Domain * * @throws \GeoIp2\Exception\AddressNotFoundException if the address is * not in the database. * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database * is corrupt or invalid */ public function domain($ipAddress) { return $this->flatModelFor( 'Domain', 'GeoIP2-Domain', $ipAddress ); } /** * This method returns a GeoIP2 Enterprise model. * * @param string $ipAddress IPv4 or IPv6 address as a string. * * @return \GeoIp2\Model\Enterprise * * @throws \GeoIp2\Exception\AddressNotFoundException if the address is * not in the database. * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database * is corrupt or invalid */ public function enterprise($ipAddress) { return $this->modelFor('Enterprise', 'Enterprise', $ipAddress); } /** * This method returns a GeoIP2 ISP model. * * @param string $ipAddress IPv4 or IPv6 address as a string. * * @return \GeoIp2\Model\Isp * * @throws \GeoIp2\Exception\AddressNotFoundException if the address is * not in the database. * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database * is corrupt or invalid */ public function isp($ipAddress) { return $this->flatModelFor( 'Isp', 'GeoIP2-ISP', $ipAddress ); } private function modelFor($class, $type, $ipAddress) { $record = $this->getRecord($class, $type, $ipAddress); $record['traits']['ip_address'] = $ipAddress; $class = "GeoIp2\\Model\\" . $class; return new $class($record, $this->locales); } private function flatModelFor($class, $type, $ipAddress) { $record = $this->getRecord($class, $type, $ipAddress); $record['ip_address'] = $ipAddress; $class = "GeoIp2\\Model\\" . $class; return new $class($record); } private function getRecord($class, $type, $ipAddress) { if (strpos($this->metadata()->databaseType, $type) === false) { $method = lcfirst($class); throw new \BadMethodCallException( "The $method method cannot be used to open a " . $this->metadata()->databaseType . " database" ); } $record = $this->dbReader->get($ipAddress); if ($record === null) { throw new AddressNotFoundException( "The address $ipAddress is not in the database." ); } if (!is_array($record)) { // This can happen on corrupt databases. Generally, // MaxMind\Db\Reader will throw a // MaxMind\Db\Reader\InvalidDatabaseException, but occasionally // the lookup may result in a record that looks valid but is not // an array. This mostly happens when the user is ignoring all // exceptions and the more frequent InvalidDatabaseException // exceptions go unnoticed. throw new InvalidDatabaseException( "Expected an array when looking up $ipAddress but received: " . gettype($record) ); } return $record; } /** * @throws \InvalidArgumentException if arguments are passed to the method. * @throws \BadMethodCallException if the database has been closed. * @return \MaxMind\Db\Reader\Metadata object for the database. */ public function metadata() { return $this->dbReader->metadata(); } /** * Closes the GeoIP2 database and returns the resources to the system. */ public function close() { $this->dbReader->close(); } } PK!x<system/tgeoip/vendor/geoip2/geoip2/src/Model/AnonymousIp.phpnu[isAnonymous = $this->get('is_anonymous'); $this->isAnonymousVpn = $this->get('is_anonymous_vpn'); $this->isHostingProvider = $this->get('is_hosting_provider'); $this->isPublicProxy = $this->get('is_public_proxy'); $this->isTorExitNode = $this->get('is_tor_exit_node'); $this->ipAddress = $this->get('ip_address'); } } PK!9D?system/tgeoip/vendor/geoip2/geoip2/src/Model/ConnectionType.phpnu[connectionType = $this->get('connection_type'); $this->ipAddress = $this->get('ip_address'); } } PK! ??5system/tgeoip/vendor/geoip2/geoip2/src/Model/City.phpnu[city = new \GeoIp2\Record\City($this->get('city'), $locales); $this->location = new \GeoIp2\Record\Location($this->get('location')); $this->postal = new \GeoIp2\Record\Postal($this->get('postal')); $this->createSubdivisions($raw, $locales); } private function createSubdivisions($raw, $locales) { if (!isset($raw['subdivisions'])) { return; } foreach ($raw['subdivisions'] as $sub) { array_push( $this->subdivisions, new \GeoIp2\Record\Subdivision($sub, $locales) ); } } /** * @ignore */ public function __get($attr) { if ($attr == 'mostSpecificSubdivision') { return $this->$attr(); } else { return parent::__get($attr); } } /** * @ignore */ public function __isset($attr) { if ($attr == 'mostSpecificSubdivision') { // We always return a mostSpecificSubdivision, even if it is the // empty subdivision return true; } else { return parent::__isset($attr); } } private function mostSpecificSubdivision() { return empty($this->subdivisions) ? new \GeoIp2\Record\Subdivision(array(), $this->locales) : end($this->subdivisions); } } PK!{A;system/tgeoip/vendor/geoip2/geoip2/src/Model/Enterprise.phpnu[autonomousSystemNumber = $this->get('autonomous_system_number'); $this->autonomousSystemOrganization = $this->get('autonomous_system_organization'); $this->isp = $this->get('isp'); $this->organization = $this->get('organization'); $this->ipAddress = $this->get('ip_address'); } } PK!~1k22>system/tgeoip/vendor/geoip2/geoip2/src/Model/AbstractModel.phpnu[raw = $raw; } /** * @ignore */ protected function get($field) { if (isset($this->raw[$field])) { return $this->raw[$field]; } else { if (preg_match('/^is_/', $field)) { return false; } else { return null; } } } /** * @ignore */ public function __get($attr) { if ($attr != "instance" && property_exists($this, $attr)) { return $this->$attr; } throw new \RuntimeException("Unknown attribute: $attr"); } /** * @ignore */ public function __isset($attr) { return $attr != "instance" && isset($this->$attr); } public function jsonSerialize() { return $this->raw; } } PK!@v v 8system/tgeoip/vendor/geoip2/geoip2/src/Model/Country.phpnu[continent = new \GeoIp2\Record\Continent( $this->get('continent'), $locales ); $this->country = new \GeoIp2\Record\Country( $this->get('country'), $locales ); $this->maxmind = new \GeoIp2\Record\MaxMind($this->get('maxmind')); $this->registeredCountry = new \GeoIp2\Record\Country( $this->get('registered_country'), $locales ); $this->representedCountry = new \GeoIp2\Record\RepresentedCountry( $this->get('represented_country'), $locales ); $this->traits = new \GeoIp2\Record\Traits($this->get('traits')); $this->locales = $locales; } } PK!xPX7system/tgeoip/vendor/geoip2/geoip2/src/Model/Domain.phpnu[domain = $this->get('domain'); $this->ipAddress = $this->get('ip_address'); } } PK!1~9system/tgeoip/vendor/geoip2/geoip2/src/Model/Insights.phpnu[The user type associated with the IP * address. This can be one of the following values:

*
    *
  • business *
  • cafe *
  • cellular *
  • college *
  • content_delivery_network *
  • dialup *
  • government *
  • hosting *
  • library *
  • military *
  • residential *
  • router *
  • school *
  • search_engine_spider *
  • traveler *
*

* This attribute is only available from the Insights web service and the * GeoIP2 Enterprise database. *

*/ class Traits extends AbstractRecord { /** * @ignore */ protected $validAttributes = array( 'autonomousSystemNumber', 'autonomousSystemOrganization', 'connectionType', 'domain', 'isAnonymousProxy', 'isLegitimateProxy', 'isSatelliteProvider', 'isp', 'ipAddress', 'organization', 'userType' ); } PK!X1<<9system/tgeoip/vendor/geoip2/geoip2/src/Record/Country.phpnu[locales = $locales; parent::__construct($record); } /** * @ignore */ public function __get($attr) { if ($attr == 'name') { return $this->name(); } else { return parent::__get($attr); } } /** * @ignore */ public function __isset($attr) { if ($attr == 'name') { return $this->firstSetNameLocale() == null ? false : true; } else { return parent::__isset($attr); } } private function name() { $locale = $this->firstSetNameLocale(); return $locale === null ? null : $this->names[$locale]; } private function firstSetNameLocale() { foreach ($this->locales as $locale) { if (isset($this->names[$locale])) { return $locale; } } return null; } } PK! SDsystem/tgeoip/vendor/geoip2/geoip2/src/Record/RepresentedCountry.phpnu[military * but this could expand to include other types in the future. */ class RepresentedCountry extends Country { protected $validAttributes = array( 'confidence', 'geonameId', 'isoCode', 'names', 'type' ); } PK!~^^:system/tgeoip/vendor/geoip2/geoip2/src/Record/Location.phpnu[(..@system/tgeoip/vendor/geoip2/geoip2/src/Record/AbstractRecord.phpnu[record = isset($record) ? $record : array(); } /** * @ignore */ public function __get($attr) { // XXX - kind of ugly but greatly reduces boilerplate code $key = $this->attributeToKey($attr); if ($this->__isset($attr)) { return $this->record[$key]; } elseif ($this->validAttribute($attr)) { if (preg_match('/^is_/', $key)) { return false; } else { return null; } } else { throw new \RuntimeException("Unknown attribute: $attr"); } } public function __isset($attr) { return $this->validAttribute($attr) && isset($this->record[$this->attributeToKey($attr)]); } private function attributeToKey($attr) { return strtolower(preg_replace('/([A-Z])/', '_\1', $attr)); } private function validAttribute($attr) { return in_array($attr, $this->validAttributes); } public function jsonSerialize() { return $this->record; } } PK!OK<system/tgeoip/vendor/geoip2/geoip2/src/ProviderInterface.phpnu[locales = $locales; // This is for backwards compatibility. Do not remove except for a // major version bump. if (is_string($options)) { $options = array( 'host' => $options ); } if (!isset($options['host'])) { $options['host'] = 'geoip.maxmind.com'; } $options['userAgent'] = $this->userAgent(); $this->client = new WsClient($userId, $licenseKey, $options); } private function userAgent() { return 'GeoIP2-API/' . Client::VERSION; } /** * This method calls the GeoIP2 Precision: City service. * * @param string $ipAddress IPv4 or IPv6 address as a string. If no * address is provided, the address that the web service is called * from will be used. * * @return \GeoIp2\Model\City * * @throws \GeoIp2\Exception\AddressNotFoundException if the address you * provided is not in our database (e.g., a private address). * @throws \GeoIp2\Exception\AuthenticationException if there is a problem * with the user ID or license key that you provided. * @throws \GeoIp2\Exception\OutOfQueriesException if your account is out * of queries. * @throws \GeoIp2\Exception\InvalidRequestException} if your request was * received by the web service but is invalid for some other reason. * This may indicate an issue with this API. Please report the error to * MaxMind. * @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error * code or message was returned. This could indicate a problem with the * connection between your server and the web service or that the web * service returned an invalid document or 500 error code. * @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent * class to the above exceptions. It will be thrown directly if a 200 * status code is returned but the body is invalid. */ public function city($ipAddress = 'me') { return $this->responseFor('city', 'City', $ipAddress); } /** * This method calls the GeoIP2 Precision: Country service. * * @param string $ipAddress IPv4 or IPv6 address as a string. If no * address is provided, the address that the web service is called * from will be used. * * @return \GeoIp2\Model\Country * * @throws \GeoIp2\Exception\AddressNotFoundException if the address you * provided is not in our database (e.g., a private address). * @throws \GeoIp2\Exception\AuthenticationException if there is a problem * with the user ID or license key that you provided. * @throws \GeoIp2\Exception\OutOfQueriesException if your account is out * of queries. * @throws \GeoIp2\Exception\InvalidRequestException} if your request was * received by the web service but is invalid for some other reason. * This may indicate an issue with this API. Please report the error to * MaxMind. * @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error * code or message was returned. This could indicate a problem with the * connection between your server and the web service or that the web * service returned an invalid document or 500 error code. * @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent * class to the above exceptions. It will be thrown directly if a 200 * status code is returned but the body is invalid. */ public function country($ipAddress = 'me') { return $this->responseFor('country', 'Country', $ipAddress); } /** * This method calls the GeoIP2 Precision: Insights service. * * @param string $ipAddress IPv4 or IPv6 address as a string. If no * address is provided, the address that the web service is called * from will be used. * * @return \GeoIp2\Model\Insights * * @throws \GeoIp2\Exception\AddressNotFoundException if the address you * provided is not in our database (e.g., a private address). * @throws \GeoIp2\Exception\AuthenticationException if there is a problem * with the user ID or license key that you provided. * @throws \GeoIp2\Exception\OutOfQueriesException if your account is out * of queries. * @throws \GeoIp2\Exception\InvalidRequestException} if your request was * received by the web service but is invalid for some other reason. * This may indicate an issue with this API. Please report the error to * MaxMind. * @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error * code or message was returned. This could indicate a problem with the * connection between your server and the web service or that the web * service returned an invalid document or 500 error code. * @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent * class to the above exceptions. It will be thrown directly if a 200 * status code is returned but the body is invalid. */ public function insights($ipAddress = 'me') { return $this->responseFor('insights', 'Insights', $ipAddress); } private function responseFor($endpoint, $class, $ipAddress) { $path = implode('/', array(self::$basePath, $endpoint, $ipAddress)); try { $body = $this->client->get('GeoIP2 ' . $class, $path); } catch (\MaxMind\Exception\IpAddressNotFoundException $ex) { throw new AddressNotFoundException( $ex->getMessage(), $ex->getStatusCode(), $ex ); } catch (\MaxMind\Exception\AuthenticationException $ex) { throw new AuthenticationException( $ex->getMessage(), $ex->getStatusCode(), $ex ); } catch (\MaxMind\Exception\InsufficientFundsException $ex) { throw new OutOfQueriesException( $ex->getMessage(), $ex->getStatusCode(), $ex ); } catch (\MaxMind\Exception\InvalidRequestException $ex) { throw new InvalidRequestException( $ex->getMessage(), $ex->getErrorCode(), $ex->getStatusCode(), $ex->getUri(), $ex ); } catch (\MaxMind\Exception\HttpException $ex) { throw new HttpException( $ex->getMessage(), $ex->getStatusCode(), $ex->getUri(), $ex ); } catch (\MaxMind\Exception\WebServiceException $ex) { throw new GeoIp2Exception( $ex->getMessage(), $ex->getCode(), $ex ); } $class = "GeoIp2\\Model\\" . $class; return new $class($body, $this->locales); } } PK!Ȝqq5system/tgeoip/vendor/splitbrain/php-archive/README.mdnu[PHPArchive - Pure PHP ZIP and TAR handling ========================================== This library allows to handle new ZIP and TAR archives without the need for any special PHP extensions (gz and bzip are needed for compression). It can create new files or extract existing ones. To keep things simple, the modification (adding or removing files) of existing archives is not supported. [![Build Status](https://travis-ci.org/splitbrain/php-archive.svg)](https://travis-ci.org/splitbrain/php-archive) Install ------- Use composer: ```php composer.phar require splitbrain/php-archive``` Usage ----- The usage for the Zip and Tar classes are basically the same. Here are some examples for working with TARs to get you started. Check the [API docs](https://splitbrain.github.io/php-archive/) for more info. ```php require_once 'vendor/autoload.php'; use splitbrain\PHPArchive\Tar; // To list the contents of an existing TAR archive, open() it and use // contents() on it: $tar = new Tar(); $tar->open('myfile.tgz'); $toc = $tar->contents(); print_r($toc); // array of FileInfo objects // To extract the contents of an existing TAR archive, open() it and use // extract() on it: $tar = new Tar(); $tar->open('myfile.tgz'); $tar->extract('/tmp'); // To create a new TAR archive directly on the filesystem (low memory // requirements), create() it: $tar = new Tar(); $tar->create('myfile.tgz'); $tar->addFile(...); $tar->addData(...); ... $tar->close(); // To create a TAR archive directly in memory, create() it, add*() // files and then either save() or getArchive() it: $tar = new Tar(); $tar->setCompression(9, Archive::COMPRESS_BZIP); $tar->create(); $tar->addFile(...); $tar->addData(...); ... $tar->save('myfile.tbz'); // compresses and saves it echo $tar->getArchive(); // compresses and returns it ``` Differences between Tar and Zip: Tars are compressed as a whole, while Zips compress each file individually. Therefore you can call ```setCompression``` before each ```addFile()``` and ```addData()``` function call. The FileInfo class can be used to specify additional info like ownership or permissions when adding a file to an archive. PK!A*9system/tgeoip/vendor/splitbrain/php-archive/composer.jsonnu[{ "name": "splitbrain/php-archive", "description": "Pure-PHP implementation to read and write TAR and ZIP archives", "keywords": ["zip", "tar", "archive", "unpack", "extract", "unzip"], "authors": [ { "name": "Andreas Gohr", "email": "andi@splitbrain.org" } ], "license": "MIT", "require": { "php": ">=5.4" }, "suggest": { "ext-iconv": "Used for proper filename encode handling", "ext-mbstring": "Can be used alternatively for handling filename encoding" }, "require-dev": { "phpunit/phpunit": "^4.8", "mikey179/vfsStream": "^1.6", "ext-zip": "*", "ext-bz2": "*" }, "autoload": { "psr-4": { "splitbrain\\PHPArchive\\": "src" } }, "autoload-dev": { "psr-4": { "splitbrain\\PHPArchive\\": "tests" } } } PK!C݇7system/tgeoip/vendor/splitbrain/php-archive/.travis.ymlnu[language: php php: - 5.4 - 5.5 - 5.6 - 7.0 - 7.1 - 7.2 - nightly - hhvm before_script: - composer install script: ./vendor/bin/phpunit after_success: - sh generate-api.sh env: global: secure: ctCQVPQgQziwIZf5QGHcnhHlXsyauG0W3AWF/6R8cTP+in2S/RygunPp7CkXiqA1YMluGr2Lo9h4DTVg7oqeXl79FXFXedijQmQEu3g3f4iDWtxbQhGf4bJQk57jXFldge4rQedlOJDzwGzJ1abrimJQlu090BZNeonzWL5cRK4= PK!^7system/tgeoip/vendor/splitbrain/php-archive/phpunit.xmlnu[ ./tests/ src PK!zjI;system/tgeoip/vendor/splitbrain/php-archive/src/Archive.phpnu[callback = $callback; } } PK!ڠquuFsystem/tgeoip/vendor/splitbrain/php-archive/src/ArchiveIOException.phpnu[ * @package splitbrain\PHPArchive * @license MIT */ class FileInfo { protected $isdir = false; protected $path = ''; protected $size = 0; protected $csize = 0; protected $mtime = 0; protected $mode = 0664; protected $owner = ''; protected $group = ''; protected $uid = 0; protected $gid = 0; protected $comment = ''; /** * initialize dynamic defaults * * @param string $path The path of the file, can also be set later through setPath() */ public function __construct($path = '') { $this->mtime = time(); $this->setPath($path); } /** * Factory to build FileInfo from existing file or directory * * @param string $path path to a file on the local file system * @param string $as optional path to use inside the archive * @throws FileInfoException * @return FileInfo */ public static function fromPath($path, $as = '') { clearstatcache(false, $path); if (!file_exists($path)) { throw new FileInfoException("$path does not exist"); } $stat = stat($path); $file = new FileInfo(); $file->setPath($path); $file->setIsdir(is_dir($path)); $file->setMode(fileperms($path)); $file->setOwner(fileowner($path)); $file->setGroup(filegroup($path)); $file->setSize(filesize($path)); $file->setUid($stat['uid']); $file->setGid($stat['gid']); $file->setMtime($stat['mtime']); if ($as) { $file->setPath($as); } return $file; } /** * @return int the filesize. always 0 for directories */ public function getSize() { if($this->isdir) return 0; return $this->size; } /** * @param int $size */ public function setSize($size) { $this->size = $size; } /** * @return int */ public function getCompressedSize() { return $this->csize; } /** * @param int $csize */ public function setCompressedSize($csize) { $this->csize = $csize; } /** * @return int */ public function getMtime() { return $this->mtime; } /** * @param int $mtime */ public function setMtime($mtime) { $this->mtime = $mtime; } /** * @return int */ public function getGid() { return $this->gid; } /** * @param int $gid */ public function setGid($gid) { $this->gid = $gid; } /** * @return int */ public function getUid() { return $this->uid; } /** * @param int $uid */ public function setUid($uid) { $this->uid = $uid; } /** * @return string */ public function getComment() { return $this->comment; } /** * @param string $comment */ public function setComment($comment) { $this->comment = $comment; } /** * @return string */ public function getGroup() { return $this->group; } /** * @param string $group */ public function setGroup($group) { $this->group = $group; } /** * @return boolean */ public function getIsdir() { return $this->isdir; } /** * @param boolean $isdir */ public function setIsdir($isdir) { // default mode for directories if ($isdir && $this->mode === 0664) { $this->mode = 0775; } $this->isdir = $isdir; } /** * @return int */ public function getMode() { return $this->mode; } /** * @param int $mode */ public function setMode($mode) { $this->mode = $mode; } /** * @return string */ public function getOwner() { return $this->owner; } /** * @param string $owner */ public function setOwner($owner) { $this->owner = $owner; } /** * @return string */ public function getPath() { return $this->path; } /** * @param string $path */ public function setPath($path) { $this->path = $this->cleanPath($path); } /** * Cleans up a path and removes relative parts, also strips leading slashes * * @param string $path * @return string */ protected function cleanPath($path) { $path = str_replace('\\', '/', $path); $path = explode('/', $path); $newpath = array(); foreach ($path as $p) { if ($p === '' || $p === '.') { continue; } if ($p === '..') { array_pop($newpath); continue; } array_push($newpath, $p); } return trim(implode('/', $newpath), '/'); } /** * Strip given prefix or number of path segments from the filename * * The $strip parameter allows you to strip a certain number of path components from the filenames * found in the tar file, similar to the --strip-components feature of GNU tar. This is triggered when * an integer is passed as $strip. * Alternatively a fixed string prefix may be passed in $strip. If the filename matches this prefix, * the prefix will be stripped. It is recommended to give prefixes with a trailing slash. * * @param int|string $strip */ public function strip($strip) { $filename = $this->getPath(); $striplen = strlen($strip); if (is_int($strip)) { // if $strip is an integer we strip this many path components $parts = explode('/', $filename); if (!$this->getIsdir()) { $base = array_pop($parts); // keep filename itself } else { $base = ''; } $filename = join('/', array_slice($parts, $strip)); if ($base) { $filename .= "/$base"; } } else { // if strip is a string, we strip a prefix here if (substr($filename, 0, $striplen) == $strip) { $filename = substr($filename, $striplen); } } $this->setPath($filename); } /** * Does the file match the given include and exclude expressions? * * Exclude rules take precedence over include rules * * @param string $include Regular expression of files to include * @param string $exclude Regular expression of files to exclude * @return bool */ public function match($include = '', $exclude = '') { $extract = true; if ($include && !preg_match($include, $this->getPath())) { $extract = false; } if ($exclude && preg_match($exclude, $this->getPath())) { $extract = false; } return $extract; } } PK! 7[[7system/tgeoip/vendor/splitbrain/php-archive/src/Tar.phpnu[100 chars) are supported in POSIX ustar and GNU longlink formats. * * @author Andreas Gohr * @package splitbrain\PHPArchive * @license MIT */ class Tar extends Archive { protected $file = ''; protected $comptype = Archive::COMPRESS_AUTO; protected $complevel = 9; protected $fh; protected $memory = ''; protected $closed = true; protected $writeaccess = false; /** * Sets the compression to use * * @param int $level Compression level (0 to 9) * @param int $type Type of compression to use (use COMPRESS_* constants) * @throws ArchiveIllegalCompressionException */ public function setCompression($level = 9, $type = Archive::COMPRESS_AUTO) { $this->compressioncheck($type); if ($level < -1 || $level > 9) { throw new ArchiveIllegalCompressionException('Compression level should be between -1 and 9'); } $this->comptype = $type; $this->complevel = $level; if($level == 0) $this->comptype = Archive::COMPRESS_NONE; if($type == Archive::COMPRESS_NONE) $this->complevel = 0; } /** * Open an existing TAR file for reading * * @param string $file * @throws ArchiveIOException * @throws ArchiveIllegalCompressionException */ public function open($file) { $this->file = $file; // update compression to mach file if ($this->comptype == Tar::COMPRESS_AUTO) { $this->setCompression($this->complevel, $this->filetype($file)); } // open file handles if ($this->comptype === Archive::COMPRESS_GZIP) { $this->fh = @gzopen($this->file, 'rb'); } elseif ($this->comptype === Archive::COMPRESS_BZIP) { $this->fh = @bzopen($this->file, 'r'); } else { $this->fh = @fopen($this->file, 'rb'); } if (!$this->fh) { throw new ArchiveIOException('Could not open file for reading: '.$this->file); } $this->closed = false; } /** * Read the contents of a TAR archive * * This function lists the files stored in the archive * * The archive is closed afer reading the contents, because rewinding is not possible in bzip2 streams. * Reopen the file with open() again if you want to do additional operations * * @throws ArchiveIOException * @throws ArchiveCorruptedException * @returns FileInfo[] */ public function contents() { if ($this->closed || !$this->file) { throw new ArchiveIOException('Can not read from a closed archive'); } $result = array(); while ($read = $this->readbytes(512)) { $header = $this->parseHeader($read); if (!is_array($header)) { continue; } $this->skipbytes(ceil($header['size'] / 512) * 512); $result[] = $this->header2fileinfo($header); } $this->close(); return $result; } /** * Extract an existing TAR archive * * The $strip parameter allows you to strip a certain number of path components from the filenames * found in the tar file, similar to the --strip-components feature of GNU tar. This is triggered when * an integer is passed as $strip. * Alternatively a fixed string prefix may be passed in $strip. If the filename matches this prefix, * the prefix will be stripped. It is recommended to give prefixes with a trailing slash. * * By default this will extract all files found in the archive. You can restrict the output using the $include * and $exclude parameter. Both expect a full regular expression (including delimiters and modifiers). If * $include is set only files that match this expression will be extracted. Files that match the $exclude * expression will never be extracted. Both parameters can be used in combination. Expressions are matched against * stripped filenames as described above. * * The archive is closed afer reading the contents, because rewinding is not possible in bzip2 streams. * Reopen the file with open() again if you want to do additional operations * * @param string $outdir the target directory for extracting * @param int|string $strip either the number of path components or a fixed prefix to strip * @param string $exclude a regular expression of files to exclude * @param string $include a regular expression of files to include * @throws ArchiveIOException * @throws ArchiveCorruptedException * @return FileInfo[] */ public function extract($outdir, $strip = '', $exclude = '', $include = '') { if ($this->closed || !$this->file) { throw new ArchiveIOException('Can not read from a closed archive'); } $outdir = rtrim($outdir, '/'); @mkdir($outdir, 0777, true); if (!is_dir($outdir)) { throw new ArchiveIOException("Could not create directory '$outdir'"); } $extracted = array(); while ($dat = $this->readbytes(512)) { // read the file header $header = $this->parseHeader($dat); if (!is_array($header)) { continue; } $fileinfo = $this->header2fileinfo($header); // apply strip rules $fileinfo->strip($strip); // skip unwanted files if (!strlen($fileinfo->getPath()) || !$fileinfo->match($include, $exclude)) { $this->skipbytes(ceil($header['size'] / 512) * 512); continue; } // create output directory $output = $outdir.'/'.$fileinfo->getPath(); $directory = ($fileinfo->getIsdir()) ? $output : dirname($output); @mkdir($directory, 0777, true); // extract data if (!$fileinfo->getIsdir()) { $fp = @fopen($output, "wb"); if (!$fp) { throw new ArchiveIOException('Could not open file for writing: '.$output); } $size = floor($header['size'] / 512); for ($i = 0; $i < $size; $i++) { fwrite($fp, $this->readbytes(512), 512); } if (($header['size'] % 512) != 0) { fwrite($fp, $this->readbytes(512), $header['size'] % 512); } fclose($fp); @touch($output, $fileinfo->getMtime()); @chmod($output, $fileinfo->getMode()); } else { $this->skipbytes(ceil($header['size'] / 512) * 512); // the size is usually 0 for directories } if(is_callable($this->callback)) { call_user_func($this->callback, $fileinfo); } $extracted[] = $fileinfo; } $this->close(); return $extracted; } /** * Create a new TAR file * * If $file is empty, the tar file will be created in memory * * @param string $file * @throws ArchiveIOException * @throws ArchiveIllegalCompressionException */ public function create($file = '') { $this->file = $file; $this->memory = ''; $this->fh = 0; if ($this->file) { // determine compression if ($this->comptype == Archive::COMPRESS_AUTO) { $this->setCompression($this->complevel, $this->filetype($file)); } if ($this->comptype === Archive::COMPRESS_GZIP) { $this->fh = @gzopen($this->file, 'wb'.$this->complevel); } elseif ($this->comptype === Archive::COMPRESS_BZIP) { $this->fh = @bzopen($this->file, 'w'); } else { $this->fh = @fopen($this->file, 'wb'); } if (!$this->fh) { throw new ArchiveIOException('Could not open file for writing: '.$this->file); } } $this->writeaccess = true; $this->closed = false; } /** * Add a file to the current TAR archive using an existing file in the filesystem * * @param string $file path to the original file * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data, empty to take from original * @throws ArchiveCorruptedException when the file changes while reading it, the archive will be corrupt and should be deleted * @throws ArchiveIOException there was trouble reading the given file, it was not added * @throws FileInfoException trouble reading file info, it was not added */ public function addFile($file, $fileinfo = '') { if (is_string($fileinfo)) { $fileinfo = FileInfo::fromPath($file, $fileinfo); } if ($this->closed) { throw new ArchiveIOException('Archive has been closed, files can no longer be added'); } $fp = @fopen($file, 'rb'); if (!$fp) { throw new ArchiveIOException('Could not open file for reading: '.$file); } // create file header $this->writeFileHeader($fileinfo); // write data $read = 0; while (!feof($fp)) { $data = fread($fp, 512); $read += strlen($data); if ($data === false) { break; } if ($data === '') { break; } $packed = pack("a512", $data); $this->writebytes($packed); } fclose($fp); if($read != $fileinfo->getSize()) { $this->close(); throw new ArchiveCorruptedException("The size of $file changed while reading, archive corrupted. read $read expected ".$fileinfo->getSize()); } if(is_callable($this->callback)) { call_user_func($this->callback, $fileinfo); } } /** * Add a file to the current TAR archive using the given $data as content * * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data * @param string $data binary content of the file to add * @throws ArchiveIOException */ public function addData($fileinfo, $data) { if (is_string($fileinfo)) { $fileinfo = new FileInfo($fileinfo); } if ($this->closed) { throw new ArchiveIOException('Archive has been closed, files can no longer be added'); } $len = strlen($data); $fileinfo->setSize($len); $this->writeFileHeader($fileinfo); for ($s = 0; $s < $len; $s += 512) { $this->writebytes(pack("a512", substr($data, $s, 512))); } if (is_callable($this->callback)) { call_user_func($this->callback, $fileinfo); } } /** * Add the closing footer to the archive if in write mode, close all file handles * * After a call to this function no more data can be added to the archive, for * read access no reading is allowed anymore * * "Physically, an archive consists of a series of file entries terminated by an end-of-archive entry, which * consists of two 512 blocks of zero bytes" * * @link http://www.gnu.org/software/tar/manual/html_chapter/tar_8.html#SEC134 * @throws ArchiveIOException */ public function close() { if ($this->closed) { return; } // we did this already // write footer if ($this->writeaccess) { $this->writebytes(pack("a512", "")); $this->writebytes(pack("a512", "")); } // close file handles if ($this->file) { if ($this->comptype === Archive::COMPRESS_GZIP) { gzclose($this->fh); } elseif ($this->comptype === Archive::COMPRESS_BZIP) { bzclose($this->fh); } else { fclose($this->fh); } $this->file = ''; $this->fh = 0; } $this->writeaccess = false; $this->closed = true; } /** * Returns the created in-memory archive data * * This implicitly calls close() on the Archive * @throws ArchiveIOException */ public function getArchive() { $this->close(); if ($this->comptype === Archive::COMPRESS_AUTO) { $this->comptype = Archive::COMPRESS_NONE; } if ($this->comptype === Archive::COMPRESS_GZIP) { return gzencode($this->memory, $this->complevel); } if ($this->comptype === Archive::COMPRESS_BZIP) { return bzcompress($this->memory); } return $this->memory; } /** * Save the created in-memory archive data * * Note: It more memory effective to specify the filename in the create() function and * let the library work on the new file directly. * * @param string $file * @throws ArchiveIOException * @throws ArchiveIllegalCompressionException */ public function save($file) { if ($this->comptype === Archive::COMPRESS_AUTO) { $this->setCompression($this->complevel, $this->filetype($file)); } if (!@file_put_contents($file, $this->getArchive())) { throw new ArchiveIOException('Could not write to file: '.$file); } } /** * Read from the open file pointer * * @param int $length bytes to read * @return string */ protected function readbytes($length) { if ($this->comptype === Archive::COMPRESS_GZIP) { return @gzread($this->fh, $length); } elseif ($this->comptype === Archive::COMPRESS_BZIP) { return @bzread($this->fh, $length); } else { return @fread($this->fh, $length); } } /** * Write to the open filepointer or memory * * @param string $data * @throws ArchiveIOException * @return int number of bytes written */ protected function writebytes($data) { if (!$this->file) { $this->memory .= $data; $written = strlen($data); } elseif ($this->comptype === Archive::COMPRESS_GZIP) { $written = @gzwrite($this->fh, $data); } elseif ($this->comptype === Archive::COMPRESS_BZIP) { $written = @bzwrite($this->fh, $data); } else { $written = @fwrite($this->fh, $data); } if ($written === false) { throw new ArchiveIOException('Failed to write to archive stream'); } return $written; } /** * Skip forward in the open file pointer * * This is basically a wrapper around seek() (and a workaround for bzip2) * * @param int $bytes seek to this position */ protected function skipbytes($bytes) { if ($this->comptype === Archive::COMPRESS_GZIP) { @gzseek($this->fh, $bytes, SEEK_CUR); } elseif ($this->comptype === Archive::COMPRESS_BZIP) { // there is no seek in bzip2, we simply read on // bzread allows to read a max of 8kb at once while($bytes) { $toread = min(8192, $bytes); @bzread($this->fh, $toread); $bytes -= $toread; } } else { @fseek($this->fh, $bytes, SEEK_CUR); } } /** * Write the given file meta data as header * * @param FileInfo $fileinfo * @throws ArchiveIOException */ protected function writeFileHeader(FileInfo $fileinfo) { $this->writeRawFileHeader( $fileinfo->getPath(), $fileinfo->getUid(), $fileinfo->getGid(), $fileinfo->getMode(), $fileinfo->getSize(), $fileinfo->getMtime(), $fileinfo->getIsdir() ? '5' : '0' ); } /** * Write a file header to the stream * * @param string $name * @param int $uid * @param int $gid * @param int $perm * @param int $size * @param int $mtime * @param string $typeflag Set to '5' for directories * @throws ArchiveIOException */ protected function writeRawFileHeader($name, $uid, $gid, $perm, $size, $mtime, $typeflag = '') { // handle filename length restrictions $prefix = ''; $namelen = strlen($name); if ($namelen > 100) { $file = basename($name); $dir = dirname($name); if (strlen($file) > 100 || strlen($dir) > 155) { // we're still too large, let's use GNU longlink $this->writeRawFileHeader('././@LongLink', 0, 0, 0, $namelen, 0, 'L'); for ($s = 0; $s < $namelen; $s += 512) { $this->writebytes(pack("a512", substr($name, $s, 512))); } $name = substr($name, 0, 100); // cut off name } else { // we're fine when splitting, use POSIX ustar $prefix = $dir; $name = $file; } } // values are needed in octal $uid = sprintf("%6s ", decoct($uid)); $gid = sprintf("%6s ", decoct($gid)); $perm = sprintf("%6s ", decoct($perm)); $size = sprintf("%11s ", decoct($size)); $mtime = sprintf("%11s", decoct($mtime)); $data_first = pack("a100a8a8a8a12A12", $name, $perm, $uid, $gid, $size, $mtime); $data_last = pack("a1a100a6a2a32a32a8a8a155a12", $typeflag, '', 'ustar', '', '', '', '', '', $prefix, ""); for ($i = 0, $chks = 0; $i < 148; $i++) { $chks += ord($data_first[$i]); } for ($i = 156, $chks += 256, $j = 0; $i < 512; $i++, $j++) { $chks += ord($data_last[$j]); } $this->writebytes($data_first); $chks = pack("a8", sprintf("%6s ", decoct($chks))); $this->writebytes($chks.$data_last); } /** * Decode the given tar file header * * @param string $block a 512 byte block containing the header data * @return array|false returns false when this was a null block * @throws ArchiveCorruptedException */ protected function parseHeader($block) { if (!$block || strlen($block) != 512) { throw new ArchiveCorruptedException('Unexpected length of header'); } // null byte blocks are ignored if(trim($block) === '') return false; for ($i = 0, $chks = 0; $i < 148; $i++) { $chks += ord($block[$i]); } for ($i = 156, $chks += 256; $i < 512; $i++) { $chks += ord($block[$i]); } $header = @unpack( "a100filename/a8perm/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix", $block ); if (!$header) { throw new ArchiveCorruptedException('Failed to parse header'); } $return['checksum'] = OctDec(trim($header['checksum'])); if ($return['checksum'] != $chks) { throw new ArchiveCorruptedException('Header does not match it\'s checksum'); } $return['filename'] = trim($header['filename']); $return['perm'] = OctDec(trim($header['perm'])); $return['uid'] = OctDec(trim($header['uid'])); $return['gid'] = OctDec(trim($header['gid'])); $return['size'] = OctDec(trim($header['size'])); $return['mtime'] = OctDec(trim($header['mtime'])); $return['typeflag'] = $header['typeflag']; $return['link'] = trim($header['link']); $return['uname'] = trim($header['uname']); $return['gname'] = trim($header['gname']); // Handle ustar Posix compliant path prefixes if (trim($header['prefix'])) { $return['filename'] = trim($header['prefix']).'/'.$return['filename']; } // Handle Long-Link entries from GNU Tar if ($return['typeflag'] == 'L') { // following data block(s) is the filename $filename = trim($this->readbytes(ceil($return['size'] / 512) * 512)); // next block is the real header $block = $this->readbytes(512); $return = $this->parseHeader($block); // overwrite the filename $return['filename'] = $filename; } return $return; } /** * Creates a FileInfo object from the given parsed header * * @param $header * @return FileInfo */ protected function header2fileinfo($header) { $fileinfo = new FileInfo(); $fileinfo->setPath($header['filename']); $fileinfo->setMode($header['perm']); $fileinfo->setUid($header['uid']); $fileinfo->setGid($header['gid']); $fileinfo->setSize($header['size']); $fileinfo->setMtime($header['mtime']); $fileinfo->setOwner($header['uname']); $fileinfo->setGroup($header['gname']); $fileinfo->setIsdir((bool) $header['typeflag']); return $fileinfo; } /** * Checks if the given compression type is available and throws an exception if not * * @param $comptype * @throws ArchiveIllegalCompressionException */ protected function compressioncheck($comptype) { if ($comptype === Archive::COMPRESS_GZIP && !function_exists('gzopen')) { throw new ArchiveIllegalCompressionException('No gzip support available'); } if ($comptype === Archive::COMPRESS_BZIP && !function_exists('bzopen')) { throw new ArchiveIllegalCompressionException('No bzip2 support available'); } } /** * Guesses the wanted compression from the given file * * Uses magic bytes for existing files, the file extension otherwise * * You don't need to call this yourself. It's used when you pass Archive::COMPRESS_AUTO somewhere * * @param string $file * @return int */ public function filetype($file) { // for existing files, try to read the magic bytes if(file_exists($file) && is_readable($file) && filesize($file) > 5) { $fh = @fopen($file, 'rb'); if(!$fh) return false; $magic = fread($fh, 5); fclose($fh); if(strpos($magic, "\x42\x5a") === 0) return Archive::COMPRESS_BZIP; if(strpos($magic, "\x1f\x8b") === 0) return Archive::COMPRESS_GZIP; } // otherwise rely on file name $file = strtolower($file); if (substr($file, -3) == '.gz' || substr($file, -4) == '.tgz') { return Archive::COMPRESS_GZIP; } elseif (substr($file, -4) == '.bz2' || substr($file, -4) == '.tbz') { return Archive::COMPRESS_BZIP; } return Archive::COMPRESS_NONE; } } PK!|NzzEsystem/tgeoip/vendor/splitbrain/php-archive/src/FileInfoException.phpnu[ * @package splitbrain\PHPArchive * @license MIT */ class Zip extends Archive { protected $file = ''; protected $fh; protected $memory = ''; protected $closed = true; protected $writeaccess = false; protected $ctrl_dir; protected $complevel = 9; /** * Set the compression level. * * Compression Type is ignored for ZIP * * You can call this function before adding each file to set differen compression levels * for each file. * * @param int $level Compression level (0 to 9) * @param int $type Type of compression to use ignored for ZIP * @throws ArchiveIllegalCompressionException */ public function setCompression($level = 9, $type = Archive::COMPRESS_AUTO) { if ($level < -1 || $level > 9) { throw new ArchiveIllegalCompressionException('Compression level should be between -1 and 9'); } $this->complevel = $level; } /** * Open an existing ZIP file for reading * * @param string $file * @throws ArchiveIOException */ public function open($file) { $this->file = $file; $this->fh = @fopen($this->file, 'rb'); if (!$this->fh) { throw new ArchiveIOException('Could not open file for reading: '.$this->file); } $this->closed = false; } /** * Read the contents of a ZIP archive * * This function lists the files stored in the archive, and returns an indexed array of FileInfo objects * * The archive is closed afer reading the contents, for API compatibility with TAR files * Reopen the file with open() again if you want to do additional operations * * @throws ArchiveIOException * @return FileInfo[] */ public function contents() { if ($this->closed || !$this->file) { throw new ArchiveIOException('Can not read from a closed archive'); } $result = array(); $centd = $this->readCentralDir(); @rewind($this->fh); @fseek($this->fh, $centd['offset']); for ($i = 0; $i < $centd['entries']; $i++) { $result[] = $this->header2fileinfo($this->readCentralFileHeader()); } $this->close(); return $result; } /** * Extract an existing ZIP archive * * The $strip parameter allows you to strip a certain number of path components from the filenames * found in the tar file, similar to the --strip-components feature of GNU tar. This is triggered when * an integer is passed as $strip. * Alternatively a fixed string prefix may be passed in $strip. If the filename matches this prefix, * the prefix will be stripped. It is recommended to give prefixes with a trailing slash. * * By default this will extract all files found in the archive. You can restrict the output using the $include * and $exclude parameter. Both expect a full regular expression (including delimiters and modifiers). If * $include is set only files that match this expression will be extracted. Files that match the $exclude * expression will never be extracted. Both parameters can be used in combination. Expressions are matched against * stripped filenames as described above. * * @param string $outdir the target directory for extracting * @param int|string $strip either the number of path components or a fixed prefix to strip * @param string $exclude a regular expression of files to exclude * @param string $include a regular expression of files to include * @throws ArchiveIOException * @return FileInfo[] */ public function extract($outdir, $strip = '', $exclude = '', $include = '') { if ($this->closed || !$this->file) { throw new ArchiveIOException('Can not read from a closed archive'); } $outdir = rtrim($outdir, '/'); @mkdir($outdir, 0777, true); $extracted = array(); $cdir = $this->readCentralDir(); $pos_entry = $cdir['offset']; // begin of the central file directory for ($i = 0; $i < $cdir['entries']; $i++) { // read file header @fseek($this->fh, $pos_entry); $header = $this->readCentralFileHeader(); $header['index'] = $i; $pos_entry = ftell($this->fh); // position of the next file in central file directory fseek($this->fh, $header['offset']); // seek to beginning of file header $header = $this->readFileHeader($header); $fileinfo = $this->header2fileinfo($header); // apply strip rules $fileinfo->strip($strip); // skip unwanted files if (!strlen($fileinfo->getPath()) || !$fileinfo->match($include, $exclude)) { continue; } $extracted[] = $fileinfo; // create output directory $output = $outdir.'/'.$fileinfo->getPath(); $directory = ($header['folder']) ? $output : dirname($output); @mkdir($directory, 0777, true); // nothing more to do for directories if ($fileinfo->getIsdir()) { if(is_callable($this->callback)) { call_user_func($this->callback, $fileinfo); } continue; } // compressed files are written to temporary .gz file first if ($header['compression'] == 0) { $extractto = $output; } else { $extractto = $output.'.gz'; } // open file for writing $fp = @fopen($extractto, "wb"); if (!$fp) { throw new ArchiveIOException('Could not open file for writing: '.$extractto); } // prepend compression header if ($header['compression'] != 0) { $binary_data = pack( 'va1a1Va1a1', 0x8b1f, chr($header['compression']), chr(0x00), time(), chr(0x00), chr(3) ); fwrite($fp, $binary_data, 10); } // read the file and store it on disk $size = $header['compressed_size']; while ($size != 0) { $read_size = ($size < 2048 ? $size : 2048); $buffer = fread($this->fh, $read_size); $binary_data = pack('a'.$read_size, $buffer); fwrite($fp, $binary_data, $read_size); $size -= $read_size; } // finalize compressed file if ($header['compression'] != 0) { $binary_data = pack('VV', $header['crc'], $header['size']); fwrite($fp, $binary_data, 8); } // close file fclose($fp); // unpack compressed file if ($header['compression'] != 0) { $gzp = @gzopen($extractto, 'rb'); if (!$gzp) { @unlink($extractto); throw new ArchiveIOException('Failed file extracting. gzip support missing?'); } $fp = @fopen($output, 'wb'); if (!$fp) { throw new ArchiveIOException('Could not open file for writing: '.$extractto); } $size = $header['size']; while ($size != 0) { $read_size = ($size < 2048 ? $size : 2048); $buffer = gzread($gzp, $read_size); $binary_data = pack('a'.$read_size, $buffer); @fwrite($fp, $binary_data, $read_size); $size -= $read_size; } fclose($fp); gzclose($gzp); unlink($extractto); // remove temporary gz file } @touch($output, $fileinfo->getMtime()); //FIXME what about permissions? if(is_callable($this->callback)) { call_user_func($this->callback, $fileinfo); } } $this->close(); return $extracted; } /** * Create a new ZIP file * * If $file is empty, the zip file will be created in memory * * @param string $file * @throws ArchiveIOException */ public function create($file = '') { $this->file = $file; $this->memory = ''; $this->fh = 0; if ($this->file) { $this->fh = @fopen($this->file, 'wb'); if (!$this->fh) { throw new ArchiveIOException('Could not open file for writing: '.$this->file); } } $this->writeaccess = true; $this->closed = false; $this->ctrl_dir = array(); } /** * Add a file to the current ZIP archive using an existing file in the filesystem * * @param string $file path to the original file * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data, empty to take from original * @throws ArchiveIOException */ /** * Add a file to the current archive using an existing file in the filesystem * * @param string $file path to the original file * @param string|FileInfo $fileinfo either the name to use in archive (string) or a FileInfo oject with all meta data, empty to take from original * @throws ArchiveIOException * @throws FileInfoException */ public function addFile($file, $fileinfo = '') { if (is_string($fileinfo)) { $fileinfo = FileInfo::fromPath($file, $fileinfo); } if ($this->closed) { throw new ArchiveIOException('Archive has been closed, files can no longer be added'); } $data = @file_get_contents($file); if ($data === false) { throw new ArchiveIOException('Could not open file for reading: '.$file); } // FIXME could we stream writing compressed data? gzwrite on a fopen handle? $this->addData($fileinfo, $data); } /** * Add a file to the current Zip archive using the given $data as content * * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data * @param string $data binary content of the file to add * @throws ArchiveIOException */ public function addData($fileinfo, $data) { if (is_string($fileinfo)) { $fileinfo = new FileInfo($fileinfo); } if ($this->closed) { throw new ArchiveIOException('Archive has been closed, files can no longer be added'); } // prepare info and compress data $size = strlen($data); $crc = crc32($data); if ($this->complevel) { $data = gzcompress($data, $this->complevel); $data = substr($data, 2, -4); // strip compression headers } $csize = strlen($data); $offset = $this->dataOffset(); $name = $fileinfo->getPath(); $time = $fileinfo->getMtime(); // write local file header $this->writebytes($this->makeLocalFileHeader( $time, $crc, $size, $csize, $name, (bool) $this->complevel )); // we store no encryption header // write data $this->writebytes($data); // we store no data descriptor // add info to central file directory $this->ctrl_dir[] = $this->makeCentralFileRecord( $offset, $time, $crc, $size, $csize, $name, (bool) $this->complevel ); if(is_callable($this->callback)) { call_user_func($this->callback, $fileinfo); } } /** * Add the closing footer to the archive if in write mode, close all file handles * * After a call to this function no more data can be added to the archive, for * read access no reading is allowed anymore * @throws ArchiveIOException */ public function close() { if ($this->closed) { return; } // we did this already if ($this->writeaccess) { // write central directory $offset = $this->dataOffset(); $ctrldir = join('', $this->ctrl_dir); $this->writebytes($ctrldir); // write end of central directory record $this->writebytes("\x50\x4b\x05\x06"); // end of central dir signature $this->writebytes(pack('v', 0)); // number of this disk $this->writebytes(pack('v', 0)); // number of the disk with the start of the central directory $this->writebytes(pack('v', count($this->ctrl_dir))); // total number of entries in the central directory on this disk $this->writebytes(pack('v', count($this->ctrl_dir))); // total number of entries in the central directory $this->writebytes(pack('V', strlen($ctrldir))); // size of the central directory $this->writebytes(pack('V', $offset)); // offset of start of central directory with respect to the starting disk number $this->writebytes(pack('v', 0)); // .ZIP file comment length $this->ctrl_dir = array(); } // close file handles if ($this->file) { fclose($this->fh); $this->file = ''; $this->fh = 0; } $this->writeaccess = false; $this->closed = true; } /** * Returns the created in-memory archive data * * This implicitly calls close() on the Archive * @throws ArchiveIOException */ public function getArchive() { $this->close(); return $this->memory; } /** * Save the created in-memory archive data * * Note: It's more memory effective to specify the filename in the create() function and * let the library work on the new file directly. * * @param $file * @throws ArchiveIOException */ public function save($file) { if (!@file_put_contents($file, $this->getArchive())) { throw new ArchiveIOException('Could not write to file: '.$file); } } /** * Read the central directory * * This key-value list contains general information about the ZIP file * * @return array */ protected function readCentralDir() { $size = filesize($this->file); if ($size < 277) { $maximum_size = $size; } else { $maximum_size = 277; } @fseek($this->fh, $size - $maximum_size); $pos = ftell($this->fh); $bytes = 0x00000000; while ($pos < $size) { $byte = @fread($this->fh, 1); $bytes = (($bytes << 8) & 0xFFFFFFFF) | ord($byte); if ($bytes == 0x504b0506) { break; } $pos++; } $data = unpack( 'vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', fread($this->fh, 18) ); if ($data['comment_size'] != 0) { $centd['comment'] = fread($this->fh, $data['comment_size']); } else { $centd['comment'] = ''; } $centd['entries'] = $data['entries']; $centd['disk_entries'] = $data['disk_entries']; $centd['offset'] = $data['offset']; $centd['disk_start'] = $data['disk_start']; $centd['size'] = $data['size']; $centd['disk'] = $data['disk']; return $centd; } /** * Read the next central file header * * Assumes the current file pointer is pointing at the right position * * @return array */ protected function readCentralFileHeader() { $binary_data = fread($this->fh, 46); $header = unpack( 'vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $binary_data ); if ($header['filename_len'] != 0) { $header['filename'] = fread($this->fh, $header['filename_len']); } else { $header['filename'] = ''; } if ($header['extra_len'] != 0) { $header['extra'] = fread($this->fh, $header['extra_len']); $header['extradata'] = $this->parseExtra($header['extra']); } else { $header['extra'] = ''; $header['extradata'] = array(); } if ($header['comment_len'] != 0) { $header['comment'] = fread($this->fh, $header['comment_len']); } else { $header['comment'] = ''; } $header['mtime'] = $this->makeUnixTime($header['mdate'], $header['mtime']); $header['stored_filename'] = $header['filename']; $header['status'] = 'ok'; if (substr($header['filename'], -1) == '/') { $header['external'] = 0x41FF0010; } $header['folder'] = ($header['external'] == 0x41FF0010 || $header['external'] == 16) ? 1 : 0; return $header; } /** * Reads the local file header * * This header precedes each individual file inside the zip file. Assumes the current file pointer is pointing at * the right position already. Enhances the given central header with the data found at the local header. * * @param array $header the central file header read previously (see above) * @return array */ protected function readFileHeader($header) { $binary_data = fread($this->fh, 30); $data = unpack( 'vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data ); $header['filename'] = fread($this->fh, $data['filename_len']); if ($data['extra_len'] != 0) { $header['extra'] = fread($this->fh, $data['extra_len']); $header['extradata'] = array_merge($header['extradata'], $this->parseExtra($header['extra'])); } else { $header['extra'] = ''; $header['extradata'] = array(); } $header['compression'] = $data['compression']; foreach (array( 'size', 'compressed_size', 'crc' ) as $hd) { // On ODT files, these headers are 0. Keep the previous value. if ($data[$hd] != 0) { $header[$hd] = $data[$hd]; } } $header['flag'] = $data['flag']; $header['mtime'] = $this->makeUnixTime($data['mdate'], $data['mtime']); $header['stored_filename'] = $header['filename']; $header['status'] = "ok"; $header['folder'] = ($header['external'] == 0x41FF0010 || $header['external'] == 16) ? 1 : 0; return $header; } /** * Parse the extra headers into fields * * @param string $header * @return array */ protected function parseExtra($header) { $extra = array(); // parse all extra fields as raw values while (strlen($header) !== 0) { $set = unpack('vid/vlen', $header); $header = substr($header, 4); $value = substr($header, 0, $set['len']); $header = substr($header, $set['len']); $extra[$set['id']] = $value; } // handle known ones if(isset($extra[0x6375])) { $extra['utf8comment'] = substr($extra[0x7075], 5); // strip version and crc } if(isset($extra[0x7075])) { $extra['utf8path'] = substr($extra[0x7075], 5); // strip version and crc } return $extra; } /** * Create fileinfo object from header data * * @param $header * @return FileInfo */ protected function header2fileinfo($header) { $fileinfo = new FileInfo(); $fileinfo->setSize($header['size']); $fileinfo->setCompressedSize($header['compressed_size']); $fileinfo->setMtime($header['mtime']); $fileinfo->setComment($header['comment']); $fileinfo->setIsdir($header['external'] == 0x41FF0010 || $header['external'] == 16); if(isset($header['extradata']['utf8path'])) { $fileinfo->setPath($header['extradata']['utf8path']); } else { $fileinfo->setPath($this->cpToUtf8($header['filename'])); } if(isset($header['extradata']['utf8comment'])) { $fileinfo->setComment($header['extradata']['utf8comment']); } else { $fileinfo->setComment($this->cpToUtf8($header['comment'])); } return $fileinfo; } /** * Convert the given CP437 encoded string to UTF-8 * * Tries iconv with the correct encoding first, falls back to mbstring with CP850 which is * similar enough. CP437 seems not to be available in mbstring. Lastly falls back to keeping the * string as is, which is still better than nothing. * * On some systems iconv is available, but the codepage is not. We also check for that. * * @param $string * @return string */ protected function cpToUtf8($string) { if (function_exists('iconv') && @iconv_strlen('', 'CP437') !== false) { return iconv('CP437', 'UTF-8', $string); } elseif (function_exists('mb_convert_encoding')) { return mb_convert_encoding($string, 'UTF-8', 'CP850'); } else { return $string; } } /** * Convert the given UTF-8 encoded string to CP437 * * Same caveats as for cpToUtf8() apply * * @param $string * @return string */ protected function utf8ToCp($string) { // try iconv first if (function_exists('iconv')) { $conv = @iconv('UTF-8', 'CP437//IGNORE', $string); if($conv) return $conv; // it worked } // still here? iconv failed to convert the string. Try another method // see http://php.net/manual/en/function.iconv.php#108643 if (function_exists('mb_convert_encoding')) { return mb_convert_encoding($string, 'CP850', 'UTF-8'); } else { return $string; } } /** * Write to the open filepointer or memory * * @param string $data * @throws ArchiveIOException * @return int number of bytes written */ protected function writebytes($data) { if (!$this->file) { $this->memory .= $data; $written = strlen($data); } else { $written = @fwrite($this->fh, $data); } if ($written === false) { throw new ArchiveIOException('Failed to write to archive stream'); } return $written; } /** * Current data pointer position * * @fixme might need a -1 * @return int */ protected function dataOffset() { if ($this->file) { return ftell($this->fh); } else { return strlen($this->memory); } } /** * Create a DOS timestamp from a UNIX timestamp * * DOS timestamps start at 1980-01-01, earlier UNIX stamps will be set to this date * * @param $time * @return int */ protected function makeDosTime($time) { $timearray = getdate($time); if ($timearray['year'] < 1980) { $timearray['year'] = 1980; $timearray['mon'] = 1; $timearray['mday'] = 1; $timearray['hours'] = 0; $timearray['minutes'] = 0; $timearray['seconds'] = 0; } return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); } /** * Create a UNIX timestamp from a DOS timestamp * * @param $mdate * @param $mtime * @return int */ protected function makeUnixTime($mdate = null, $mtime = null) { if ($mdate && $mtime) { $year = (($mdate & 0xFE00) >> 9) + 1980; $month = ($mdate & 0x01E0) >> 5; $day = $mdate & 0x001F; $hour = ($mtime & 0xF800) >> 11; $minute = ($mtime & 0x07E0) >> 5; $seconde = ($mtime & 0x001F) << 1; $mtime = mktime($hour, $minute, $seconde, $month, $day, $year); } else { $mtime = time(); } return $mtime; } /** * Returns a local file header for the given data * * @param int $offset location of the local header * @param int $ts unix timestamp * @param int $crc CRC32 checksum of the uncompressed data * @param int $len length of the uncompressed data * @param int $clen length of the compressed data * @param string $name file name * @param boolean|null $comp if compression is used, if null it's determined from $len != $clen * @return string */ protected function makeCentralFileRecord($offset, $ts, $crc, $len, $clen, $name, $comp = null) { if(is_null($comp)) $comp = $len != $clen; $comp = $comp ? 8 : 0; $dtime = dechex($this->makeDosTime($ts)); list($name, $extra) = $this->encodeFilename($name); $header = "\x50\x4b\x01\x02"; // central file header signature $header .= pack('v', 14); // version made by - VFAT $header .= pack('v', 20); // version needed to extract - 2.0 $header .= pack('v', 0); // general purpose flag - no flags set $header .= pack('v', $comp); // compression method - deflate|none $header .= pack( 'H*', $dtime[6] . $dtime[7] . $dtime[4] . $dtime[5] . $dtime[2] . $dtime[3] . $dtime[0] . $dtime[1] ); // last mod file time and date $header .= pack('V', $crc); // crc-32 $header .= pack('V', $clen); // compressed size $header .= pack('V', $len); // uncompressed size $header .= pack('v', strlen($name)); // file name length $header .= pack('v', strlen($extra)); // extra field length $header .= pack('v', 0); // file comment length $header .= pack('v', 0); // disk number start $header .= pack('v', 0); // internal file attributes $header .= pack('V', 0); // external file attributes @todo was 0x32!? $header .= pack('V', $offset); // relative offset of local header $header .= $name; // file name $header .= $extra; // extra (utf-8 filename) return $header; } /** * Returns a local file header for the given data * * @param int $ts unix timestamp * @param int $crc CRC32 checksum of the uncompressed data * @param int $len length of the uncompressed data * @param int $clen length of the compressed data * @param string $name file name * @param boolean|null $comp if compression is used, if null it's determined from $len != $clen * @return string */ protected function makeLocalFileHeader($ts, $crc, $len, $clen, $name, $comp = null) { if(is_null($comp)) $comp = $len != $clen; $comp = $comp ? 8 : 0; $dtime = dechex($this->makeDosTime($ts)); list($name, $extra) = $this->encodeFilename($name); $header = "\x50\x4b\x03\x04"; // local file header signature $header .= pack('v', 20); // version needed to extract - 2.0 $header .= pack('v', 0); // general purpose flag - no flags set $header .= pack('v', $comp); // compression method - deflate|none $header .= pack( 'H*', $dtime[6] . $dtime[7] . $dtime[4] . $dtime[5] . $dtime[2] . $dtime[3] . $dtime[0] . $dtime[1] ); // last mod file time and date $header .= pack('V', $crc); // crc-32 $header .= pack('V', $clen); // compressed size $header .= pack('V', $len); // uncompressed size $header .= pack('v', strlen($name)); // file name length $header .= pack('v', strlen($extra)); // extra field length $header .= $name; // file name $header .= $extra; // extra (utf-8 filename) return $header; } /** * Returns an allowed filename and an extra field header * * When encoding stuff outside the 7bit ASCII range it needs to be placed in a separate * extra field * * @param $original * @return array($filename, $extra) */ protected function encodeFilename($original) { $cp437 = $this->utf8ToCp($original); if ($cp437 === $original) { return array($original, ''); } $extra = pack( 'vvCV', 0x7075, // tag strlen($original) + 5, // length of file + version + crc 1, // version crc32($original) // crc ); $extra .= $original; return array($cp437, $extra); } } PK!<Msystem/tgeoip/vendor/splitbrain/php-archive/src/ArchiveCorruptedException.phpnu[ /dev/null git checkout -B gh-pages # Push generated files git add . git commit -m "Docs updated by Travis" git push origin gh-pages -fq > /dev/null PK!]0system/tgeoip/vendor/maxmind-db/reader/README.mdnu[# MaxMind DB Reader PHP API # ## Description ## This is the PHP API for reading MaxMind DB files. MaxMind DB is a binary file format that stores data indexed by IP address subnets (IPv4 or IPv6). ## Installation ## We recommend installing this package with [Composer](http://getcomposer.org/). ### Download Composer ### To download Composer, run in the root directory of your project: ```bash curl -sS https://getcomposer.org/installer | php ``` You should now have the file `composer.phar` in your project directory. ### Install Dependencies ### Run in your project root: ``` php composer.phar require maxmind-db/reader:~1.0 ``` You should now have the files `composer.json` and `composer.lock` as well as the directory `vendor` in your project directory. If you use a version control system, `composer.json` should be added to it. ### Require Autoloader ### After installing the dependencies, you need to require the Composer autoloader from your code: ```php require 'vendor/autoload.php'; ``` ## Usage ## ## Example ## ```php get($ipAddress)); $reader->close(); ``` ## Optional PHP C Extension ## MaxMind provides an optional C extension that is a drop-in replacement for `MaxMind\Db\Reader`. In order to use this extension, you must install the Reader API as described above and install the extension as described below. If you are using an autoloader, no changes to your code should be necessary. ### Installing Extension ### First install [libmaxminddb](https://github.com/maxmind/libmaxminddb) as described in its [README.md file](https://github.com/maxmind/libmaxminddb/blob/master/README.md#installing-from-a-tarball). After successfully installing libmaxmindb, run the following commands from the top-level directory of this distribution: ``` cd ext phpize ./configure make make test sudo make install ``` You then must load your extension. The recommend method is to add the following to your `php.ini` file: ``` extension=maxminddb.so ``` Note: You may need to install the PHP development package on your OS such as php5-dev for Debian-based systems or php-devel for RedHat/Fedora-based ones. ## 128-bit Integer Support ## The MaxMind DB format includes 128-bit unsigned integer as a type. Although no MaxMind-distributed database currently makes use of this type, both the pure PHP reader and the C extension support this type. The pure PHP reader requires gmp or bcmath to read databases with 128-bit unsigned integers. The integer is currently returned as a hexadecimal string (prefixed with "0x") by the C extension and a decimal string (no prefix) by the pure PHP reader. Any change to make the reader implementations always return either a hexadecimal or decimal representation of the integer will NOT be considered a breaking change. ## Support ## Please report all issues with this code using the [GitHub issue tracker] (https://github.com/maxmind/MaxMind-DB-Reader-php/issues). If you are having an issue with a MaxMind service that is not specific to the client API, please see [our support page](http://www.maxmind.com/en/support). ## Requirements ## This library requires PHP 5.3 or greater. Older versions of PHP are not supported. The pure PHP reader included with this library is works and is tested with HHVM. The GMP or BCMath extension may be required to read some databases using the pure PHP API. ## Contributing ## Patches and pull requests are encouraged. All code should follow the PSR-1 and PSR-2 style guidelines. Please include unit tests whenever possible. ## Versioning ## The MaxMind DB Reader PHP API uses [Semantic Versioning](http://semver.org/). ## Copyright and License ## This software is Copyright (c) 2014 by MaxMind, Inc. This is free software, licensed under the Apache License, Version 2.0. PK!==4system/tgeoip/vendor/maxmind-db/reader/composer.jsonnu[{ "name": "maxmind-db/reader", "description": "MaxMind DB Reader API", "keywords": ["database", "geoip", "geoip2", "geolocation", "maxmind"], "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php", "type": "library", "license": "Apache-2.0", "authors": [ { "name": "Gregory J. Oschwald", "email": "goschwald@maxmind.com", "homepage": "http://www.maxmind.com/" } ], "require": { "php": ">=5.3.1" }, "suggest": { "ext-bcmath": "bcmath or gmp is requred for decoding larger integers with the pure PHP decoder", "ext-gmp": "bcmath or gmp is requred for decoding larger integers with the pure PHP decoder", "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups" }, "require-dev": { "phpunit/phpunit": "4.2.*", "satooshi/php-coveralls": "1.0.*", "squizlabs/php_codesniffer": "2.*" }, "autoload": { "psr-4": { "MaxMind\\Db\\": "src/MaxMind/Db" } } } PK!c4system/tgeoip/vendor/maxmind-db/reader/ext/config.m4nu[PHP_ARG_WITH(maxminddb, [Whether to enable the MaxMind DB Reader extension], [ --with-maxminddb Enable MaxMind DB Reader extension support]) PHP_ARG_ENABLE(maxminddb-debug, for MaxMind DB debug support, [ --enable-maxminddb-debug Enable enable MaxMind DB deubg support], no, no) if test $PHP_MAXMINDDB != "no"; then PHP_CHECK_LIBRARY(maxminddb, MMDB_open) if test $PHP_MAXMINDDB_DEBUG != "no"; then CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror" fi PHP_ADD_LIBRARY(maxminddb, 1, MAXMINDDB_SHARED_LIBADD) PHP_SUBST(MAXMINDDB_SHARED_LIBADD) PHP_NEW_EXTENSION(maxminddb, maxminddb.c, $ext_shared) fi PK!S]]:system/tgeoip/vendor/maxmind-db/reader/ext/php_maxminddb.hnu[/* MaxMind, Inc., licenses this file to you under the Apache License, Version * 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ #include #ifndef PHP_MAXMINDDB_H #define PHP_MAXMINDDB_H 1 #define PHP_MAXMINDDB_VERSION "1.1.3" #define PHP_MAXMINDDB_EXTNAME "maxminddb" extern zend_module_entry maxminddb_module_entry; #define phpext_maxminddb_ptr &maxminddb_module_entry #endif PK!?'a(FF6system/tgeoip/vendor/maxmind-db/reader/ext/maxminddb.cnu[/* MaxMind, Inc., licenses this file to you under the Apache License, Version * 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ #include "php_maxminddb.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "Zend/zend_exceptions.h" #include #ifdef ZTS #include #endif #define __STDC_FORMAT_MACROS #include #define PHP_MAXMINDDB_NS ZEND_NS_NAME("MaxMind", "Db") #define PHP_MAXMINDDB_READER_NS ZEND_NS_NAME(PHP_MAXMINDDB_NS, "Reader") #define PHP_MAXMINDDB_READER_EX_NS \ ZEND_NS_NAME(PHP_MAXMINDDB_READER_NS, \ "InvalidDatabaseException") #ifdef ZEND_ENGINE_3 #define Z_MAXMINDDB_P(zv) php_maxminddb_fetch_object(Z_OBJ_P(zv)) #define _ZVAL_STRING ZVAL_STRING #define _ZVAL_STRINGL ZVAL_STRINGL typedef size_t strsize_t; typedef zend_object free_obj_t; #else #define Z_MAXMINDDB_P(zv) (maxminddb_obj *) zend_object_store_get_object(zv TSRMLS_CC) #define _ZVAL_STRING(a, b) ZVAL_STRING(a, b, 1) #define _ZVAL_STRINGL(a, b, c) ZVAL_STRINGL(a, b, c, 1) typedef int strsize_t; typedef void free_obj_t; #endif #ifdef ZEND_ENGINE_3 typedef struct _maxminddb_obj { MMDB_s *mmdb; zend_object std; } maxminddb_obj; #else typedef struct _maxminddb_obj { zend_object std; MMDB_s *mmdb; } maxminddb_obj; #endif PHP_FUNCTION(maxminddb); static const MMDB_entry_data_list_s *handle_entry_data_list( const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC); static const MMDB_entry_data_list_s *handle_array( const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC); static const MMDB_entry_data_list_s *handle_map( const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC); static void handle_uint128(const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC); static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC); static zend_class_entry * lookup_class(const char *name TSRMLS_DC); #define CHECK_ALLOCATED(val) \ if (!val ) { \ zend_error(E_ERROR, "Out of memory"); \ return; \ } \ #define THROW_EXCEPTION(name, ... ) \ { \ zend_class_entry *exception_ce = lookup_class(name TSRMLS_CC); \ zend_throw_exception_ex(exception_ce, 0 TSRMLS_CC, __VA_ARGS__); \ } \ #if PHP_VERSION_ID < 50399 #define object_properties_init(zo, class_type) \ { \ zval *tmp; \ zend_hash_copy((*zo).properties, \ &class_type->default_properties, \ (copy_ctor_func_t)zval_add_ref, \ (void *)&tmp, \ sizeof(zval *)); \ } #endif static zend_object_handlers maxminddb_obj_handlers; static zend_class_entry *maxminddb_ce; static inline maxminddb_obj *php_maxminddb_fetch_object(zend_object *obj TSRMLS_DC){ #ifdef ZEND_ENGINE_3 return (maxminddb_obj *)((char*)(obj) - XtOffsetOf(maxminddb_obj, std)); #else return (maxminddb_obj *)obj; #endif } PHP_METHOD(MaxMind_Db_Reader, __construct){ char *db_file = NULL; strsize_t name_len; zval * _this_zval = NULL; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &_this_zval, maxminddb_ce, &db_file, &name_len) == FAILURE) { THROW_EXCEPTION("InvalidArgumentException", "The constructor takes exactly one argument."); return; } if (0 != access(db_file, R_OK)) { THROW_EXCEPTION("InvalidArgumentException", "The file \"%s\" does not exist or is not readable.", db_file); return; } MMDB_s *mmdb = (MMDB_s *)emalloc(sizeof(MMDB_s)); uint16_t status = MMDB_open(db_file, MMDB_MODE_MMAP, mmdb); if (MMDB_SUCCESS != status) { THROW_EXCEPTION( PHP_MAXMINDDB_READER_EX_NS, "Error opening database file (%s). Is this a valid MaxMind DB file?", db_file); efree(mmdb); return; } maxminddb_obj *mmdb_obj = Z_MAXMINDDB_P(getThis()); mmdb_obj->mmdb = mmdb; } PHP_METHOD(MaxMind_Db_Reader, get){ char *ip_address = NULL; strsize_t name_len; zval * _this_zval = NULL; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &_this_zval, maxminddb_ce, &ip_address, &name_len) == FAILURE) { THROW_EXCEPTION("InvalidArgumentException", "Method takes exactly one argument."); return; } const maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis()); MMDB_s *mmdb = mmdb_obj->mmdb; if (NULL == mmdb) { THROW_EXCEPTION("BadMethodCallException", "Attempt to read from a closed MaxMind DB."); return; } int gai_error = 0; int mmdb_error = MMDB_SUCCESS; MMDB_lookup_result_s result = MMDB_lookup_string(mmdb, ip_address, &gai_error, &mmdb_error); if (MMDB_SUCCESS != gai_error) { THROW_EXCEPTION("InvalidArgumentException", "The value \"%s\" is not a valid IP address.", ip_address); return; } if (MMDB_SUCCESS != mmdb_error) { char *exception_name; if (MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR == mmdb_error) { exception_name = "InvalidArgumentException"; } else { exception_name = PHP_MAXMINDDB_READER_EX_NS; } THROW_EXCEPTION(exception_name, "Error looking up %s. %s", ip_address, MMDB_strerror(mmdb_error)); return; } MMDB_entry_data_list_s *entry_data_list = NULL; if (!result.found_entry) { RETURN_NULL(); } int status = MMDB_get_entry_data_list(&result.entry, &entry_data_list); if (MMDB_SUCCESS != status) { THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS, "Error while looking up data for %s. %s", ip_address, MMDB_strerror(status)); MMDB_free_entry_data_list(entry_data_list); return; } else if (NULL == entry_data_list) { THROW_EXCEPTION( PHP_MAXMINDDB_READER_EX_NS, "Error while looking up data for %s. Your database may be corrupt or you have found a bug in libmaxminddb.", ip_address); return; } handle_entry_data_list(entry_data_list, return_value TSRMLS_CC); MMDB_free_entry_data_list(entry_data_list); } PHP_METHOD(MaxMind_Db_Reader, metadata){ if (ZEND_NUM_ARGS() != 0) { THROW_EXCEPTION("InvalidArgumentException", "Method takes no arguments."); return; } const maxminddb_obj *const mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis()); if (NULL == mmdb_obj->mmdb) { THROW_EXCEPTION("BadMethodCallException", "Attempt to read from a closed MaxMind DB."); return; } const char *const name = ZEND_NS_NAME(PHP_MAXMINDDB_READER_NS, "Metadata"); zend_class_entry *metadata_ce = lookup_class(name TSRMLS_CC); object_init_ex(return_value, metadata_ce); #ifdef ZEND_ENGINE_3 zval _metadata_array; zval *metadata_array = &_metadata_array; ZVAL_NULL(metadata_array); #else zval *metadata_array; ALLOC_INIT_ZVAL(metadata_array); #endif MMDB_entry_data_list_s *entry_data_list; MMDB_get_metadata_as_entry_data_list(mmdb_obj->mmdb, &entry_data_list); handle_entry_data_list(entry_data_list, metadata_array TSRMLS_CC); MMDB_free_entry_data_list(entry_data_list); #ifdef ZEND_ENGINE_3 zend_call_method_with_1_params(return_value, metadata_ce, &metadata_ce->constructor, ZEND_CONSTRUCTOR_FUNC_NAME, NULL, metadata_array); zval_ptr_dtor(metadata_array); #else zend_call_method_with_1_params(&return_value, metadata_ce, &metadata_ce->constructor, ZEND_CONSTRUCTOR_FUNC_NAME, NULL, metadata_array); zval_ptr_dtor(&metadata_array); #endif } PHP_METHOD(MaxMind_Db_Reader, close){ if (ZEND_NUM_ARGS() != 0) { THROW_EXCEPTION("InvalidArgumentException", "Method takes no arguments."); return; } maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis()); if (NULL == mmdb_obj->mmdb) { THROW_EXCEPTION("BadMethodCallException", "Attempt to close a closed MaxMind DB."); return; } MMDB_close(mmdb_obj->mmdb); efree(mmdb_obj->mmdb); mmdb_obj->mmdb = NULL; } static const MMDB_entry_data_list_s *handle_entry_data_list( const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC) { switch (entry_data_list->entry_data.type) { case MMDB_DATA_TYPE_MAP: return handle_map(entry_data_list, z_value TSRMLS_CC); case MMDB_DATA_TYPE_ARRAY: return handle_array(entry_data_list, z_value TSRMLS_CC); case MMDB_DATA_TYPE_UTF8_STRING: _ZVAL_STRINGL(z_value, (char *)entry_data_list->entry_data.utf8_string, entry_data_list->entry_data.data_size); break; case MMDB_DATA_TYPE_BYTES: _ZVAL_STRINGL(z_value, (char *)entry_data_list->entry_data.bytes, entry_data_list->entry_data.data_size); break; case MMDB_DATA_TYPE_DOUBLE: ZVAL_DOUBLE(z_value, entry_data_list->entry_data.double_value); break; case MMDB_DATA_TYPE_FLOAT: ZVAL_DOUBLE(z_value, entry_data_list->entry_data.float_value); break; case MMDB_DATA_TYPE_UINT16: ZVAL_LONG(z_value, entry_data_list->entry_data.uint16); break; case MMDB_DATA_TYPE_UINT32: ZVAL_LONG(z_value, entry_data_list->entry_data.uint32); break; case MMDB_DATA_TYPE_BOOLEAN: ZVAL_BOOL(z_value, entry_data_list->entry_data.boolean); break; case MMDB_DATA_TYPE_UINT64: handle_uint64(entry_data_list, z_value TSRMLS_CC); break; case MMDB_DATA_TYPE_UINT128: handle_uint128(entry_data_list, z_value TSRMLS_CC); break; case MMDB_DATA_TYPE_INT32: ZVAL_LONG(z_value, entry_data_list->entry_data.int32); break; default: THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS, "Invalid data type arguments: %d", entry_data_list->entry_data.type); return NULL; } return entry_data_list; } static const MMDB_entry_data_list_s *handle_map( const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC) { array_init(z_value); const uint32_t map_size = entry_data_list->entry_data.data_size; uint i; for (i = 0; i < map_size && entry_data_list; i++ ) { entry_data_list = entry_data_list->next; char *key = estrndup((char *)entry_data_list->entry_data.utf8_string, entry_data_list->entry_data.data_size); if (NULL == key) { THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS, "Invalid data type arguments"); return NULL; } entry_data_list = entry_data_list->next; #ifdef ZEND_ENGINE_3 zval _new_value; zval * new_value = &_new_value; ZVAL_NULL(new_value); #else zval *new_value; ALLOC_INIT_ZVAL(new_value); #endif entry_data_list = handle_entry_data_list(entry_data_list, new_value TSRMLS_CC); add_assoc_zval(z_value, key, new_value); efree(key); } return entry_data_list; } static const MMDB_entry_data_list_s *handle_array( const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC) { const uint32_t size = entry_data_list->entry_data.data_size; array_init(z_value); uint i; for (i = 0; i < size && entry_data_list; i++) { entry_data_list = entry_data_list->next; #ifdef ZEND_ENGINE_3 zval _new_value; zval * new_value = &_new_value; ZVAL_NULL(new_value); #else zval *new_value; ALLOC_INIT_ZVAL(new_value); #endif entry_data_list = handle_entry_data_list(entry_data_list, new_value TSRMLS_CC); add_next_index_zval(z_value, new_value); } return entry_data_list; } static void handle_uint128(const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC) { uint64_t high = 0; uint64_t low = 0; #if MMDB_UINT128_IS_BYTE_ARRAY int i; for (i = 0; i < 8; i++) { high = (high << 8) | entry_data_list->entry_data.uint128[i]; } for (i = 8; i < 16; i++) { low = (low << 8) | entry_data_list->entry_data.uint128[i]; } #else high = entry_data_list->entry_data.uint128 >> 64; low = (uint64_t)entry_data_list->entry_data.uint128; #endif char *num_str; spprintf(&num_str, 0, "0x%016" PRIX64 "%016" PRIX64, high, low); CHECK_ALLOCATED(num_str); _ZVAL_STRING(z_value, num_str); efree(num_str); } static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list, zval *z_value TSRMLS_DC) { // We return it as a string because PHP uses signed longs char *int_str; spprintf(&int_str, 0, "%" PRIu64, entry_data_list->entry_data.uint64); CHECK_ALLOCATED(int_str); _ZVAL_STRING(z_value, int_str); efree(int_str); } static zend_class_entry *lookup_class(const char *name TSRMLS_DC) { #ifdef ZEND_ENGINE_3 zend_string *n = zend_string_init(name, strlen(name), 0); zend_class_entry *ce = zend_lookup_class(n); zend_string_release(n); if( NULL == ce ) { zend_error(E_ERROR, "Class %s not found", name); } return ce; #else zend_class_entry **ce; if (FAILURE == zend_lookup_class(name, strlen(name), &ce TSRMLS_CC)) { zend_error(E_ERROR, "Class %s not found", name); } return *ce; #endif } static void maxminddb_free_storage(free_obj_t *object TSRMLS_DC) { maxminddb_obj *obj = php_maxminddb_fetch_object((zend_object *)object TSRMLS_CC); if (obj->mmdb != NULL) { MMDB_close(obj->mmdb); efree(obj->mmdb); } zend_object_std_dtor(&obj->std TSRMLS_CC); #ifndef ZEND_ENGINE_3 efree(object); #endif } #ifdef ZEND_ENGINE_3 static zend_object *maxminddb_create_handler( zend_class_entry *type TSRMLS_DC) { maxminddb_obj *obj = (maxminddb_obj *)ecalloc(1, sizeof(maxminddb_obj)); zend_object_std_init(&obj->std, type TSRMLS_CC); object_properties_init(&(obj->std), type); obj->std.handlers = &maxminddb_obj_handlers; return &obj->std; } #else static zend_object_value maxminddb_create_handler( zend_class_entry *type TSRMLS_DC) { zend_object_value retval; maxminddb_obj *obj = (maxminddb_obj *)ecalloc(1, sizeof(maxminddb_obj)); zend_object_std_init(&obj->std, type TSRMLS_CC); object_properties_init(&(obj->std), type); retval.handle = zend_objects_store_put(obj, NULL, maxminddb_free_storage, NULL TSRMLS_CC); retval.handlers = &maxminddb_obj_handlers; return retval; } #endif /* *INDENT-OFF* */ static zend_function_entry maxminddb_methods[] = { PHP_ME(MaxMind_Db_Reader, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(MaxMind_Db_Reader, close, NULL, ZEND_ACC_PUBLIC) PHP_ME(MaxMind_Db_Reader, get, NULL, ZEND_ACC_PUBLIC) PHP_ME(MaxMind_Db_Reader, metadata, NULL, ZEND_ACC_PUBLIC) { NULL, NULL, NULL } }; /* *INDENT-ON* */ PHP_MINIT_FUNCTION(maxminddb){ zend_class_entry ce; INIT_CLASS_ENTRY(ce, PHP_MAXMINDDB_READER_NS, maxminddb_methods); maxminddb_ce = zend_register_internal_class(&ce TSRMLS_CC); maxminddb_ce->create_object = maxminddb_create_handler; maxminddb_ce->ce_flags |= ZEND_ACC_FINAL; memcpy(&maxminddb_obj_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); maxminddb_obj_handlers.clone_obj = NULL; #ifdef ZEND_ENGINE_3 maxminddb_obj_handlers.offset = XtOffsetOf(maxminddb_obj, std); maxminddb_obj_handlers.free_obj = maxminddb_free_storage; #endif return SUCCESS; } zend_module_entry maxminddb_module_entry = { STANDARD_MODULE_HEADER, PHP_MAXMINDDB_EXTNAME, NULL, PHP_MINIT(maxminddb), NULL, NULL, NULL, NULL, PHP_MAXMINDDB_VERSION, STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_MAXMINDDB ZEND_GET_MODULE(maxminddb) #endif PK!o>system/tgeoip/vendor/maxmind-db/reader/ext/tests/001-load.phptnu[--TEST-- Check for maxminddb presence --SKIPIF-- --FILE-- --EXPECT-- maxminddb extension is available PK!\h 3system/tgeoip/vendor/maxmind-db/reader/CHANGELOG.mdnu[CHANGELOG ========= 1.1.3 (2017-01-19) ------------------ * Fix incorrect version in `ext/php_maxminddb.h`. GitHub #48. 1.1.2 (2016-11-22) ------------------ * Searching for database metadata only occurs within the last 128KB (128 * 1024 bytes) of the file, speeding detection of corrupt datafiles. Reported by Eric Teubert. GitHub #42. * Suggest relevant extensions when installing with Composer. GitHub #37. 1.1.1 (2016-09-15) ------------------ * Development files were added to the `.gitattributes` as `export-ignore` so that they are not part of the Composer release. Pull request by Michele Locati. GitHub #39. 1.1.0 (2016-01-04) ------------------ * The MaxMind DB extension now supports PHP 7. Pull request by John Boehr. GitHub #27. 1.0.3 (2015-03-13) ------------------ * All uses of `strlen` were removed. This should prevent issues in situations where the function is overloaded or otherwise broken. 1.0.2 (2015-01-19) ------------------ * Previously the MaxMind DB extension would cause a segfault if the Reader object's destructor was called without first having called the constructor. (Reported by Matthias Saou & Juan Peri. GitHub #20.) 1.0.1 (2015-01-12) ------------------ * In the last several releases, the version number in the extension was incorrect. This release is being done to correct it. No other code changes are included. 1.0.0 (2014-09-22) ------------------ * First production release. * In the pure PHP reader, a string length test after `fread()` was replaced with the difference between the start pointer and the end pointer. This provided a 15% speed increase. 0.3.3 (2014-09-15) ------------------ * Clarified behavior of 128-bit type in documentation. * Updated phpunit and fixed some test breakage from the newer version. 0.3.2 (2014-09-10) ------------------ * Fixed invalid reference to global class RuntimeException from namespaced code. Fixed by Steven Don. GitHub issue #15. * Additional documentation of `Metadata` class as well as misc. documentation cleanup. 0.3.1 (2014-05-01) ------------------ * The API now works when `mbstring.func_overload` is set. * BCMath is no longer required. If the decoder encounters a big integer, it will try to use GMP and then BCMath. If both of those fail, it will throw an exception. No databases released by MaxMind currently use big integers. * The API now officially supports HHVM when using the pure PHP reader. 0.3.0 (2014-02-19) ------------------ * This API is now licensed under the Apache License, Version 2.0. * The code for the C extension was cleaned up, fixing several potential issues. 0.2.0 (2013-10-21) ------------------ * Added optional C extension for using libmaxminddb in place of the pure PHP reader. * Significantly improved error handling in pure PHP reader. * Improved performance for IPv4 lookups in an IPv6 database. 0.1.0 (2013-07-16) ------------------ * Initial release PK!Ga''@system/tgeoip/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.phpnu[get method. */ class Reader { private static $DATA_SECTION_SEPARATOR_SIZE = 16; private static $METADATA_START_MARKER = "\xAB\xCD\xEFMaxMind.com"; private static $METADATA_START_MARKER_LENGTH = 14; private static $METADATA_MAX_SIZE = 131072; // 128 * 1024 = 128KB private $decoder; private $fileHandle; private $fileSize; private $ipV4Start; private $metadata; /** * Constructs a Reader for the MaxMind DB format. The file passed to it must * be a valid MaxMind DB file such as a GeoIp2 database file. * * @param string $database * the MaxMind DB file to use. * @throws \InvalidArgumentException for invalid database path or unknown arguments * @throws \MaxMind\Db\Reader\InvalidDatabaseException * if the database is invalid or there is an error reading * from it. */ public function __construct($database) { if (func_num_args() != 1) { throw new \InvalidArgumentException( 'The constructor takes exactly one argument.' ); } if (!is_readable($database)) { throw new \InvalidArgumentException( "The file \"$database\" does not exist or is not readable." ); } $this->fileHandle = @fopen($database, 'rb'); if ($this->fileHandle === false) { throw new \InvalidArgumentException( "Error opening \"$database\"." ); } $this->fileSize = @filesize($database); if ($this->fileSize === false) { throw new \UnexpectedValueException( "Error determining the size of \"$database\"." ); } $start = $this->findMetadataStart($database); $metadataDecoder = new Decoder($this->fileHandle, $start); list($metadataArray) = $metadataDecoder->decode($start); $this->metadata = new Metadata($metadataArray); $this->decoder = new Decoder( $this->fileHandle, $this->metadata->searchTreeSize + self::$DATA_SECTION_SEPARATOR_SIZE ); } /** * Looks up the address in the MaxMind DB. * * @param string $ipAddress * the IP address to look up. * @return array the record for the IP address. * @throws \BadMethodCallException if this method is called on a closed database. * @throws \InvalidArgumentException if something other than a single IP address is passed to the method. * @throws InvalidDatabaseException * if the database is invalid or there is an error reading * from it. */ public function get($ipAddress) { if (func_num_args() != 1) { throw new \InvalidArgumentException( 'Method takes exactly one argument.' ); } if (!is_resource($this->fileHandle)) { throw new \BadMethodCallException( 'Attempt to read from a closed MaxMind DB.' ); } if (!filter_var($ipAddress, FILTER_VALIDATE_IP)) { throw new \InvalidArgumentException( "The value \"$ipAddress\" is not a valid IP address." ); } if ($this->metadata->ipVersion == 4 && strrpos($ipAddress, ':')) { throw new \InvalidArgumentException( "Error looking up $ipAddress. You attempted to look up an" . " IPv6 address in an IPv4-only database." ); } $pointer = $this->findAddressInTree($ipAddress); if ($pointer == 0) { return null; } return $this->resolveDataPointer($pointer); } private function findAddressInTree($ipAddress) { // XXX - could simplify. Done as a byte array to ease porting $rawAddress = array_merge(unpack('C*', inet_pton($ipAddress))); $bitCount = count($rawAddress) * 8; // The first node of the tree is always node 0, at the beginning of the // value $node = $this->startNode($bitCount); for ($i = 0; $i < $bitCount; $i++) { if ($node >= $this->metadata->nodeCount) { break; } $tempBit = 0xFF & $rawAddress[$i >> 3]; $bit = 1 & ($tempBit >> 7 - ($i % 8)); $node = $this->readNode($node, $bit); } if ($node == $this->metadata->nodeCount) { // Record is empty return 0; } elseif ($node > $this->metadata->nodeCount) { // Record is a data pointer return $node; } throw new InvalidDatabaseException("Something bad happened"); } private function startNode($length) { // Check if we are looking up an IPv4 address in an IPv6 tree. If this // is the case, we can skip over the first 96 nodes. if ($this->metadata->ipVersion == 6 && $length == 32) { return $this->ipV4StartNode(); } // The first node of the tree is always node 0, at the beginning of the // value return 0; } private function ipV4StartNode() { // This is a defensive check. There is no reason to call this when you // have an IPv4 tree. if ($this->metadata->ipVersion == 4) { return 0; } if ($this->ipV4Start != 0) { return $this->ipV4Start; } $node = 0; for ($i = 0; $i < 96 && $node < $this->metadata->nodeCount; $i++) { $node = $this->readNode($node, 0); } $this->ipV4Start = $node; return $node; } private function readNode($nodeNumber, $index) { $baseOffset = $nodeNumber * $this->metadata->nodeByteSize; // XXX - probably could condense this. switch ($this->metadata->recordSize) { case 24: $bytes = Util::read($this->fileHandle, $baseOffset + $index * 3, 3); list(, $node) = unpack('N', "\x00" . $bytes); return $node; case 28: $middleByte = Util::read($this->fileHandle, $baseOffset + 3, 1); list(, $middle) = unpack('C', $middleByte); if ($index == 0) { $middle = (0xF0 & $middle) >> 4; } else { $middle = 0x0F & $middle; } $bytes = Util::read($this->fileHandle, $baseOffset + $index * 4, 3); list(, $node) = unpack('N', chr($middle) . $bytes); return $node; case 32: $bytes = Util::read($this->fileHandle, $baseOffset + $index * 4, 4); list(, $node) = unpack('N', $bytes); return $node; default: throw new InvalidDatabaseException( 'Unknown record size: ' . $this->metadata->recordSize ); } } private function resolveDataPointer($pointer) { $resolved = $pointer - $this->metadata->nodeCount + $this->metadata->searchTreeSize; if ($resolved > $this->fileSize) { throw new InvalidDatabaseException( "The MaxMind DB file's search tree is corrupt" ); } list($data) = $this->decoder->decode($resolved); return $data; } /* * This is an extremely naive but reasonably readable implementation. There * are much faster algorithms (e.g., Boyer-Moore) for this if speed is ever * an issue, but I suspect it won't be. */ private function findMetadataStart($filename) { $handle = $this->fileHandle; $fstat = fstat($handle); $fileSize = $fstat['size']; $marker = self::$METADATA_START_MARKER; $markerLength = self::$METADATA_START_MARKER_LENGTH; $metadataMaxLengthExcludingMarker = min(self::$METADATA_MAX_SIZE, $fileSize) - $markerLength; for ($i = 0; $i <= $metadataMaxLengthExcludingMarker; $i++) { for ($j = 0; $j < $markerLength; $j++) { fseek($handle, $fileSize - $i - $j - 1); $matchBit = fgetc($handle); if ($matchBit != $marker[$markerLength - $j - 1]) { continue 2; } } return $fileSize - $i; } throw new InvalidDatabaseException( "Error opening database file ($filename). " . 'Is this a valid MaxMind DB file?' ); } /** * @throws \InvalidArgumentException if arguments are passed to the method. * @throws \BadMethodCallException if the database has been closed. * @return Metadata object for the database. */ public function metadata() { if (func_num_args()) { throw new \InvalidArgumentException( 'Method takes no arguments.' ); } // Not technically required, but this makes it consistent with // C extension and it allows us to change our implementation later. if (!is_resource($this->fileHandle)) { throw new \BadMethodCallException( 'Attempt to read from a closed MaxMind DB.' ); } return $this->metadata; } /** * Closes the MaxMind DB and returns resources to the system. * * @throws \Exception * if an I/O error occurs. */ public function close() { if (!is_resource($this->fileHandle)) { throw new \BadMethodCallException( 'Attempt to close a closed MaxMind DB.' ); } fclose($this->fileHandle); } } PK!ϞYsystem/tgeoip/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.phpnu[ 'extended', 1 => 'pointer', 2 => 'utf8_string', 3 => 'double', 4 => 'bytes', 5 => 'uint16', 6 => 'uint32', 7 => 'map', 8 => 'int32', 9 => 'uint64', 10 => 'uint128', 11 => 'array', 12 => 'container', 13 => 'end_marker', 14 => 'boolean', 15 => 'float', ); public function __construct( $fileStream, $pointerBase = 0, $pointerTestHack = false ) { $this->fileStream = $fileStream; $this->pointerBase = $pointerBase; $this->pointerTestHack = $pointerTestHack; $this->switchByteOrder = $this->isPlatformLittleEndian(); } public function decode($offset) { list(, $ctrlByte) = unpack( 'C', Util::read($this->fileStream, $offset, 1) ); $offset++; $type = $this->types[$ctrlByte >> 5]; // Pointers are a special case, we don't read the next $size bytes, we // use the size to determine the length of the pointer and then follow // it. if ($type == 'pointer') { list($pointer, $offset) = $this->decodePointer($ctrlByte, $offset); // for unit testing if ($this->pointerTestHack) { return array($pointer); } list($result) = $this->decode($pointer); return array($result, $offset); } if ($type == 'extended') { list(, $nextByte) = unpack( 'C', Util::read($this->fileStream, $offset, 1) ); $typeNum = $nextByte + 7; if ($typeNum < 8) { throw new InvalidDatabaseException( "Something went horribly wrong in the decoder. An extended type " . "resolved to a type number < 8 (" . $this->types[$typeNum] . ")" ); } $type = $this->types[$typeNum]; $offset++; } list($size, $offset) = $this->sizeFromCtrlByte($ctrlByte, $offset); return $this->decodeByType($type, $offset, $size); } private function decodeByType($type, $offset, $size) { switch ($type) { case 'map': return $this->decodeMap($size, $offset); case 'array': return $this->decodeArray($size, $offset); case 'boolean': return array($this->decodeBoolean($size), $offset); } $newOffset = $offset + $size; $bytes = Util::read($this->fileStream, $offset, $size); switch ($type) { case 'utf8_string': return array($this->decodeString($bytes), $newOffset); case 'double': $this->verifySize(8, $size); return array($this->decodeDouble($bytes), $newOffset); case 'float': $this->verifySize(4, $size); return array($this->decodeFloat($bytes), $newOffset); case 'bytes': return array($bytes, $newOffset); case 'uint16': case 'uint32': return array($this->decodeUint($bytes), $newOffset); case 'int32': return array($this->decodeInt32($bytes), $newOffset); case 'uint64': case 'uint128': return array($this->decodeBigUint($bytes, $size), $newOffset); default: throw new InvalidDatabaseException( "Unknown or unexpected type: " . $type ); } } private function verifySize($expected, $actual) { if ($expected != $actual) { throw new InvalidDatabaseException( "The MaxMind DB file's data section contains bad data (unknown data type or corrupt data)" ); } } private function decodeArray($size, $offset) { $array = array(); for ($i = 0; $i < $size; $i++) { list($value, $offset) = $this->decode($offset); array_push($array, $value); } return array($array, $offset); } private function decodeBoolean($size) { return $size == 0 ? false : true; } private function decodeDouble($bits) { // XXX - Assumes IEEE 754 double on platform list(, $double) = unpack('d', $this->maybeSwitchByteOrder($bits)); return $double; } private function decodeFloat($bits) { // XXX - Assumes IEEE 754 floats on platform list(, $float) = unpack('f', $this->maybeSwitchByteOrder($bits)); return $float; } private function decodeInt32($bytes) { $bytes = $this->zeroPadLeft($bytes, 4); list(, $int) = unpack('l', $this->maybeSwitchByteOrder($bytes)); return $int; } private function decodeMap($size, $offset) { $map = array(); for ($i = 0; $i < $size; $i++) { list($key, $offset) = $this->decode($offset); list($value, $offset) = $this->decode($offset); $map[$key] = $value; } return array($map, $offset); } private $pointerValueOffset = array( 1 => 0, 2 => 2048, 3 => 526336, 4 => 0, ); private function decodePointer($ctrlByte, $offset) { $pointerSize = (($ctrlByte >> 3) & 0x3) + 1; $buffer = Util::read($this->fileStream, $offset, $pointerSize); $offset = $offset + $pointerSize; $packed = $pointerSize == 4 ? $buffer : (pack('C', $ctrlByte & 0x7)) . $buffer; $unpacked = $this->decodeUint($packed); $pointer = $unpacked + $this->pointerBase + $this->pointerValueOffset[$pointerSize]; return array($pointer, $offset); } private function decodeUint($bytes) { list(, $int) = unpack('N', $this->zeroPadLeft($bytes, 4)); return $int; } private function decodeBigUint($bytes, $byteLength) { $maxUintBytes = log(PHP_INT_MAX, 2) / 8; if ($byteLength == 0) { return 0; } $numberOfLongs = ceil($byteLength / 4); $paddedLength = $numberOfLongs * 4; $paddedBytes = $this->zeroPadLeft($bytes, $paddedLength); $unpacked = array_merge(unpack("N$numberOfLongs", $paddedBytes)); $integer = 0; // 2^32 $twoTo32 = '4294967296'; foreach ($unpacked as $part) { // We only use gmp or bcmath if the final value is too big if ($byteLength <= $maxUintBytes) { $integer = ($integer << 32) + $part; } elseif (extension_loaded('gmp')) { $integer = gmp_strval(gmp_add(gmp_mul($integer, $twoTo32), $part)); } elseif (extension_loaded('bcmath')) { $integer = bcadd(bcmul($integer, $twoTo32), $part); } else { throw new \RuntimeException( 'The gmp or bcmath extension must be installed to read this database.' ); } } return $integer; } private function decodeString($bytes) { // XXX - NOOP. As far as I know, the end user has to explicitly set the // encoding in PHP. Strings are just bytes. return $bytes; } private function sizeFromCtrlByte($ctrlByte, $offset) { $size = $ctrlByte & 0x1f; $bytesToRead = $size < 29 ? 0 : $size - 28; $bytes = Util::read($this->fileStream, $offset, $bytesToRead); $decoded = $this->decodeUint($bytes); if ($size == 29) { $size = 29 + $decoded; } elseif ($size == 30) { $size = 285 + $decoded; } elseif ($size > 30) { $size = ($decoded & (0x0FFFFFFF >> (32 - (8 * $bytesToRead)))) + 65821; } return array($size, $offset + $bytesToRead); } private function zeroPadLeft($content, $desiredLength) { return str_pad($content, $desiredLength, "\x00", STR_PAD_LEFT); } private function maybeSwitchByteOrder($bytes) { return $this->switchByteOrder ? strrev($bytes) : $bytes; } private function isPlatformLittleEndian() { $testint = 0x00FF; $packed = pack('S', $testint); return $testint === current(unpack('v', $packed)); } } PK!Pܠ< < Isystem/tgeoip/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.phpnu[binaryFormatMajorVersion = $metadata['binary_format_major_version']; $this->binaryFormatMinorVersion = $metadata['binary_format_minor_version']; $this->buildEpoch = $metadata['build_epoch']; $this->databaseType = $metadata['database_type']; $this->languages = $metadata['languages']; $this->description = $metadata['description']; $this->ipVersion = $metadata['ip_version']; $this->nodeCount = $metadata['node_count']; $this->recordSize = $metadata['record_size']; $this->nodeByteSize = $this->recordSize / 4; $this->searchTreeSize = $this->nodeCount * $this->nodeByteSize; } public function __get($var) { return $this->$var; } } PK!O-9system/tgeoip/vendor/maxmind/web-service-common/README.mdnu[# MaxMind Web Service Common # This is _not_ intended for direct use by third parties. Rather, it is for shared code between MaxMind's various web service APIs. ## Requirements ## This code requires PHP 5.3 or greater. Older versions of PHP are not supported. This library works and is tested with HHVM. There are several other dependencies as defined in the `composer.json` file. ## Contributing ## Patches and pull requests are encouraged. All code should follow the PSR-2 style guidelines. Please include unit tests whenever possible. ## Versioning ## This API uses [Semantic Versioning](http://semver.org/). ## Copyright and License ## This software is Copyright (c) 2015 by MaxMind, Inc. This is free software, licensed under the Apache License, Version 2.0. PK!yrr=system/tgeoip/vendor/maxmind/web-service-common/composer.jsonnu[{ "name": "maxmind/web-service-common", "description": "Internal MaxMind Web Service API", "minimum-stability": "stable", "homepage": "https://github.com/maxmind/mm-web-service-api-php", "type": "library", "license": "Apache-2.0", "authors": [ { "name": "Gregory Oschwald", "email": "goschwald@maxmind.com" } ], "require": { "php": ">=5.3", "composer/ca-bundle": "^1.0.3", "ext-curl": "*", "ext-json": "*" }, "require-dev": { "phpunit/phpunit": "4.*", "squizlabs/php_codesniffer": "2.*" }, "autoload": { "psr-4": { "MaxMind\\": "src" } } } PK!wW<system/tgeoip/vendor/maxmind/web-service-common/CHANGELOG.mdnu[CHANGELOG ========= 0.3.1 (2016-08-10) ------------------ * On Mac OS X when using a curl built against SecureTransport, the certs in the system's keychain will now be used instead of the CA bundle on the file system. 0.3.0 (2016-08-09) ------------------ * This package now uses `composer/ca-bundle` by default rather than a CA bundle distributed with this package. `composer/ca-bundle` will first try to use the system CA bundle and will fall back to the Mozilla CA bundle when no system bundle is available. You may still specify your own bundle using the `caBundle` option. 0.2.1 (2016-06-13) ------------------ * Fix typo in code to copy cert to temp directory. 0.2.0 (2016-06-10) ------------------ * Added handling of additional error codes that the web service may return. * A `USER_ID_UNKNOWN` error will now throw a `MaxMind\Exception\AuthenticationException`. * Added support for `proxy` option. Closes #6. 0.1.0 (2016-05-23) ------------------ * A `PERMISSION_REQUIRED` error will now throw a `PermissionRequiredException` exception. * Added a `.gitattributes` file to exclude tests from Composer releases. GitHub #7. * Updated included cert bundle. 0.0.4 (2015-07-21) ------------------ * Added extremely basic tests for the curl calls. * Fixed broken POSTs. 0.0.3 (2015-06-30) ------------------ * Floats now work with the `timeout` and `connectTimeout` options. Fix by Benjamin Pick. GitHub PR #2. * `curl_error` is now used instead of `curl_strerror`. The latter is only available for PHP 5.5 or later. Fix by Benjamin Pick. GitHub PR #1. 0.0.2 (2015-06-09) ------------------ * An exception is now immediately thrown curl error rather than letting later status code checks throw an exception. This improves the exception message greatly. * If this library is inside a phar archive, the CA certs are copied out of the archive to a temporary file so that curl can use them. 0.0.1 (2015-06-01) ------------------ * Initial release. PK!S^]system/tgeoip/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.phpnu[error = $error; parent::__construct($message, $httpStatus, $uri, $previous); } public function getErrorCode() { return $this->error; } } PK!þ ''Wsystem/tgeoip/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.phpnu[uri = $uri; parent::__construct($message, $httpStatus, $previous); } public function getUri() { return $this->uri; } public function getStatusCode() { return $this->getCode(); } } PK!Y(-Vsystem/tgeoip/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.phpnu[url = $url; $this->options = $options; } /** * @param $body * @return array */ public function post($body) { $curl = $this->createCurl(); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $body); return $this->execute($curl); } public function get() { $curl = $this->createCurl(); curl_setopt($curl, CURLOPT_HTTPGET, true); return $this->execute($curl); } /** * @return resource */ private function createCurl() { $curl = curl_init($this->url); if (!empty($this->options['caBundle'])) { $opts[CURLOPT_CAINFO] = $this->options['caBundle']; } $opts[CURLOPT_SSL_VERIFYHOST] = 2; $opts[CURLOPT_FOLLOWLOCATION] = false; $opts[CURLOPT_SSL_VERIFYPEER] = true; $opts[CURLOPT_RETURNTRANSFER] = true; $opts[CURLOPT_HTTPHEADER] = $this->options['headers']; $opts[CURLOPT_USERAGENT] = $this->options['userAgent']; $opts[CURLOPT_PROXY] = $this->options['proxy']; // The defined()s are here as the *_MS opts are not available on older // cURL versions $connectTimeout = $this->options['connectTimeout']; if (defined('CURLOPT_CONNECTTIMEOUT_MS')) { $opts[CURLOPT_CONNECTTIMEOUT_MS] = ceil($connectTimeout * 1000); } else { $opts[CURLOPT_CONNECTTIMEOUT] = ceil($connectTimeout); } $timeout = $this->options['timeout']; if (defined('CURLOPT_TIMEOUT_MS')) { $opts[CURLOPT_TIMEOUT_MS] = ceil($timeout * 1000); } else { $opts[CURLOPT_TIMEOUT] = ceil($timeout); } curl_setopt_array($curl, $opts); return $curl; } private function execute($curl) { $body = curl_exec($curl); if ($errno = curl_errno($curl)) { $errorMessage = curl_error($curl); throw new HttpException( "cURL error ({$errno}): {$errorMessage}", 0, $this->url ); } $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE); curl_close($curl); return array($statusCode, $contentType, $body); } } PK!ᬇ5::Isystem/tgeoip/vendor/maxmind/web-service-common/src/WebService/Client.phpnu[userId = $userId; $this->licenseKey = $licenseKey; $this->httpRequestFactory = isset($options['httpRequestFactory']) ? $options['httpRequestFactory'] : new RequestFactory(); if (isset($options['host'])) { $this->host = $options['host']; } if (isset($options['userAgent'])) { $this->userAgentPrefix = $options['userAgent'] . ' '; } $this->caBundle = isset($options['caBundle']) ? $this->caBundle = $options['caBundle'] : $this->getCaBundle(); if (isset($options['connectTimeout'])) { $this->connectTimeout = $options['connectTimeout']; } if (isset($options['timeout'])) { $this->timeout = $options['timeout']; } if (isset($options['proxy'])) { $this->proxy = $options['proxy']; } } /** * @param string $service name of the service querying * @param string $path the URI path to use * @param array $input the data to be posted as JSON * @return array The decoded content of a successful response * @throws InvalidInputException when the request has missing or invalid * data. * @throws AuthenticationException when there is an issue authenticating the * request. * @throws InsufficientFundsException when your account is out of funds. * @throws InvalidRequestException when the request is invalid for some * other reason, e.g., invalid JSON in the POST. * @throws HttpException when an unexpected HTTP error occurs. * @throws WebServiceException when some other error occurs. This also * serves as the base class for the above exceptions. */ public function post($service, $path, $input) { $body = json_encode($input); if ($body === false) { throw new InvalidInputException( 'Error encoding input as JSON: ' . $this->jsonErrorDescription() ); } $request = $this->createRequest( $path, array('Content-Type: application/json') ); list($statusCode, $contentType, $body) = $request->post($body); return $this->handleResponse( $statusCode, $contentType, $body, $service, $path ); } public function get($service, $path) { $request = $this->createRequest($path); list($statusCode, $contentType, $body) = $request->get(); return $this->handleResponse( $statusCode, $contentType, $body, $service, $path ); } private function userAgent() { $curlVersion = curl_version(); return $this->userAgentPrefix . 'MaxMind-WS-API/' . Client::VERSION . ' PHP/' . PHP_VERSION . ' curl/' . $curlVersion['version']; } private function createRequest($path, $headers = array()) { array_push( $headers, 'Authorization: Basic ' . base64_encode($this->userId . ':' . $this->licenseKey), 'Accept: application/json' ); return $this->httpRequestFactory->request( $this->urlFor($path), array( 'caBundle' => $this->caBundle, 'connectTimeout' => $this->connectTimeout, 'headers' => $headers, 'proxy' => $this->proxy, 'timeout' => $this->timeout, 'userAgent' => $this->userAgent(), ) ); } /** * @param integer $statusCode the HTTP status code of the response * @param string $contentType the Content-Type of the response * @param string $body the response body * @param string $service the name of the service * @param string $path the path used in the request * @return array The decoded content of a successful response * @throws AuthenticationException when there is an issue authenticating the * request. * @throws InsufficientFundsException when your account is out of funds. * @throws InvalidRequestException when the request is invalid for some * other reason, e.g., invalid JSON in the POST. * @throws HttpException when an unexpected HTTP error occurs. * @throws WebServiceException when some other error occurs. This also * serves as the base class for the above exceptions */ private function handleResponse( $statusCode, $contentType, $body, $service, $path ) { if ($statusCode >= 400 && $statusCode <= 499) { $this->handle4xx($statusCode, $contentType, $body, $service, $path); } elseif ($statusCode >= 500) { $this->handle5xx($statusCode, $service, $path); } elseif ($statusCode != 200) { $this->handleUnexpectedStatus($statusCode, $service, $path); } return $this->handleSuccess($body, $service); } /** * @return string describing the JSON error */ private function jsonErrorDescription() { $errno = json_last_error(); switch ($errno) { case JSON_ERROR_DEPTH: return 'The maximum stack depth has been exceeded.'; case JSON_ERROR_STATE_MISMATCH: return 'Invalid or malformed JSON.'; case JSON_ERROR_CTRL_CHAR: return 'Control character error.'; case JSON_ERROR_SYNTAX: return 'Syntax error.'; case JSON_ERROR_UTF8: return 'Malformed UTF-8 characters.'; default: return "Other JSON error ($errno)."; } } /** * @param string $path The path to use in the URL * @return string The constructed URL */ private function urlFor($path) { return 'https://' . $this->host . $path; } /** * @param int $statusCode The HTTP status code * @param string $contentType The response content-type * @param string $body The response body * @param string $service The service name * @param string $path The path used in the request * @throws AuthenticationException * @throws HttpException * @throws InsufficientFundsException * @throws InvalidRequestException */ private function handle4xx( $statusCode, $contentType, $body, $service, $path ) { if (strlen($body) === 0) { throw new HttpException( "Received a $statusCode error for $service with no body", $statusCode, $this->urlFor($path) ); } if (!strstr($contentType, 'json')) { throw new HttpException( "Received a $statusCode error for $service with " . "the following body: " . $body, $statusCode, $this->urlFor($path) ); } $message = json_decode($body, true); if ($message === null) { throw new HttpException( "Received a $statusCode error for $service but could " . 'not decode the response as JSON: ' . $this->jsonErrorDescription() . ' Body: ' . $body, $statusCode, $this->urlFor($path) ); } if (!isset($message['code']) || !isset($message['error'])) { throw new HttpException( 'Error response contains JSON but it does not ' . 'specify code or error keys: ' . $body, $statusCode, $this->urlFor($path) ); } $this->handleWebServiceError( $message['error'], $message['code'], $statusCode, $path ); } /** * @param string $message The error message from the web service * @param string $code The error code from the web service * @param int $statusCode The HTTP status code * @param string $path The path used in the request * @throws AuthenticationException * @throws InvalidRequestException * @throws InsufficientFundsException */ private function handleWebServiceError( $message, $code, $statusCode, $path ) { switch ($code) { case 'IP_ADDRESS_NOT_FOUND': case 'IP_ADDRESS_RESERVED': throw new IpAddressNotFoundException( $message, $code, $statusCode, $this->urlFor($path) ); case 'AUTHORIZATION_INVALID': case 'LICENSE_KEY_REQUIRED': case 'USER_ID_REQUIRED': case 'USER_ID_UNKNOWN': throw new AuthenticationException( $message, $code, $statusCode, $this->urlFor($path) ); case 'OUT_OF_QUERIES': case 'INSUFFICIENT_FUNDS': throw new InsufficientFundsException( $message, $code, $statusCode, $this->urlFor($path) ); case 'PERMISSION_REQUIRED': throw new PermissionRequiredException( $message, $code, $statusCode, $this->urlFor($path) ); default: throw new InvalidRequestException( $message, $code, $statusCode, $this->urlFor($path) ); } } /** * @param int $statusCode The HTTP status code * @param string $service The service name * @param string $path The URI path used in the request * @throws HttpException */ private function handle5xx($statusCode, $service, $path) { throw new HttpException( "Received a server error ($statusCode) for $service", $statusCode, $this->urlFor($path) ); } /** * @param int $statusCode The HTTP status code * @param string $service The service name * @param string $path The URI path used in the request * @throws HttpException */ private function handleUnexpectedStatus($statusCode, $service, $path) { throw new HttpException( 'Received an unexpected HTTP status ' . "($statusCode) for $service", $statusCode, $this->urlFor($path) ); } /** * @param string $body The successful request body * @param string $service The service name * @return array The decoded request body * @throws WebServiceException if the request body cannot be decoded as * JSON */ private function handleSuccess($body, $service) { if (strlen($body) == 0) { throw new WebServiceException( "Received a 200 response for $service but did not " . "receive a HTTP body." ); } $decodedContent = json_decode($body, true); if ($decodedContent === null) { throw new WebServiceException( "Received a 200 response for $service but could " . 'not decode the response as JSON: ' . $this->jsonErrorDescription() . ' Body: ' . $body ); } return $decodedContent; } private function getCaBundle() { $curlVersion = curl_version(); // On OS X, when the SSL version is "SecureTransport", the system's // keychain will be used. if ($curlVersion['ssl_version'] ==='SecureTransport') { return; } $cert = CaBundle::getSystemCaRootBundlePath(); // Check if the cert is inside a phar. If so, we need to copy the cert // to a temp file so that curl can see it. if (substr($cert, 0, 7) == 'phar://') { $tempDir = sys_get_temp_dir(); $newCert = tempnam($tempDir, 'geoip2-'); if ($newCert === false) { throw new \RuntimeException( "Unable to create temporary file in $tempDir" ); } if (!copy($cert, $newCert)) { throw new \RuntimeException( "Could not copy $cert to $newCert: " . var_export(error_get_last(), true) ); } // We use a shutdown function rather than the destructor as the // destructor isn't called on a fatal error such as an uncaught // exception. register_shutdown_function( function () use ($newCert) { unlink($newCert); } ); $cert = $newCert; } if (!file_exists($cert)) { throw new \RuntimeException("CA cert does not exist at $cert"); } return $cert; } } PK!C!system/tgeoip/vendor/autoload.phpnu[ array($vendorDir . '/splitbrain/php-archive/src'), 'MaxMind\\Db\\' => array($vendorDir . '/maxmind-db/reader/src/MaxMind/Db'), 'MaxMind\\' => array($vendorDir . '/maxmind/web-service-common/src'), 'GeoIp2\\' => array($vendorDir . '/geoip2/geoip2/src'), 'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'), ); PK!Ti$II1system/tgeoip/vendor/composer/autoload_static.phpnu[ array ( 'splitbrain\\PHPArchive\\' => 22, ), 'M' => array ( 'MaxMind\\Db\\' => 11, 'MaxMind\\' => 8, ), 'G' => array ( 'GeoIp2\\' => 7, ), 'C' => array ( 'Composer\\CaBundle\\' => 18, ), ); public static $prefixDirsPsr4 = array ( 'splitbrain\\PHPArchive\\' => array ( 0 => __DIR__ . '/..' . '/splitbrain/php-archive/src', ), 'MaxMind\\Db\\' => array ( 0 => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db', ), 'MaxMind\\' => array ( 0 => __DIR__ . '/..' . '/maxmind/web-service-common/src', ), 'GeoIp2\\' => array ( 0 => __DIR__ . '/..' . '/geoip2/geoip2/src', ), 'Composer\\CaBundle\\' => array ( 0 => __DIR__ . '/..' . '/composer/ca-bundle/src', ), ); public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInit2994eebabe3e6b260b60cab24a9b085e::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit2994eebabe3e6b260b60cab24a9b085e::$prefixDirsPsr4; }, null, ClassLoader::class); } } PK!b3system/tgeoip/vendor/composer/autoload_classmap.phpnu[ * Jordi Boggiano * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Composer\Autoload; /** * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. * * $loader = new \Composer\Autoload\ClassLoader(); * * // register classes with namespaces * $loader->add('Symfony\Component', __DIR__.'/component'); * $loader->add('Symfony', __DIR__.'/framework'); * * // activate the autoloader * $loader->register(); * * // to enable searching the include path (eg. for PEAR packages) * $loader->setUseIncludePath(true); * * In this example, if you try to use a class in the Symfony\Component * namespace or one of its children (Symfony\Component\Console for instance), * the autoloader will first look for the class under the component/ * directory, and it will then fallback to the framework/ directory if not * found before giving up. * * This class is loosely based on the Symfony UniversalClassLoader. * * @author Fabien Potencier * @author Jordi Boggiano * @see http://www.php-fig.org/psr/psr-0/ * @see http://www.php-fig.org/psr/psr-4/ */ class ClassLoader { // PSR-4 private $prefixLengthsPsr4 = array(); private $prefixDirsPsr4 = array(); private $fallbackDirsPsr4 = array(); // PSR-0 private $prefixesPsr0 = array(); private $fallbackDirsPsr0 = array(); private $useIncludePath = false; private $classMap = array(); private $classMapAuthoritative = false; private $missingClasses = array(); private $apcuPrefix; public function getPrefixes() { if (!empty($this->prefixesPsr0)) { return call_user_func_array('array_merge', $this->prefixesPsr0); } return array(); } public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } public function getFallbackDirs() { return $this->fallbackDirsPsr0; } public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } public function getClassMap() { return $this->classMap; } /** * @param array $classMap Class to filename map */ public function addClassMap(array $classMap) { if ($this->classMap) { $this->classMap = array_merge($this->classMap, $classMap); } else { $this->classMap = $classMap; } } /** * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * * @param string $prefix The prefix * @param array|string $paths The PSR-0 root directories * @param bool $prepend Whether to prepend the directories */ public function add($prefix, $paths, $prepend = false) { if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( (array) $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, (array) $paths ); } return; } $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { $this->prefixesPsr0[$first][$prefix] = (array) $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( (array) $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], (array) $paths ); } } /** * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * * @param string $prefix The prefix/namespace, with trailing '\\' * @param array|string $paths The PSR-4 base directories * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException */ public function addPsr4($prefix, $paths, $prepend = false) { if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( (array) $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, (array) $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { // Register directories for a new namespace. $length = strlen($prefix); if ('\\' !== $prefix[$length - 1]) { throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; $this->prefixDirsPsr4[$prefix] = (array) $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( (array) $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], (array) $paths ); } } /** * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * * @param string $prefix The prefix * @param array|string $paths The PSR-0 base directories */ public function set($prefix, $paths) { if (!$prefix) { $this->fallbackDirsPsr0 = (array) $paths; } else { $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; } } /** * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * * @param string $prefix The prefix/namespace, with trailing '\\' * @param array|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException */ public function setPsr4($prefix, $paths) { if (!$prefix) { $this->fallbackDirsPsr4 = (array) $paths; } else { $length = strlen($prefix); if ('\\' !== $prefix[$length - 1]) { throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; $this->prefixDirsPsr4[$prefix] = (array) $paths; } } /** * Turns on searching the include path for class files. * * @param bool $useIncludePath */ public function setUseIncludePath($useIncludePath) { $this->useIncludePath = $useIncludePath; } /** * Can be used to check if the autoloader uses the include path to check * for classes. * * @return bool */ public function getUseIncludePath() { return $this->useIncludePath; } /** * Turns off searching the prefix and fallback directories for classes * that have not been registered with the class map. * * @param bool $classMapAuthoritative */ public function setClassMapAuthoritative($classMapAuthoritative) { $this->classMapAuthoritative = $classMapAuthoritative; } /** * Should class lookup fail if not found in the current class map? * * @return bool */ public function isClassMapAuthoritative() { return $this->classMapAuthoritative; } /** * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix */ public function setApcuPrefix($apcuPrefix) { $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** * The APCu prefix in use, or null if APCu caching is not enabled. * * @return string|null */ public function getApcuPrefix() { return $this->apcuPrefix; } /** * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); } /** * Unregisters this instance as an autoloader. */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); } /** * Loads the given class or interface. * * @param string $class The name of the class * @return bool|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { includeFile($file); return true; } } /** * Finds the path to the file where the class is defined. * * @param string $class The name of the class * * @return string|false The path if found, false otherwise */ public function findFile($class) { // class map lookup if (isset($this->classMap[$class])) { return $this->classMap[$class]; } if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { return false; } if (null !== $this->apcuPrefix) { $file = apcu_fetch($this->apcuPrefix.$class, $hit); if ($hit) { return $file; } } $file = $this->findFileWithExtension($class, '.php'); // Search for Hack files if we are running on HHVM if (false === $file && defined('HHVM_VERSION')) { $file = $this->findFileWithExtension($class, '.hh'); } if (null !== $this->apcuPrefix) { apcu_add($this->apcuPrefix.$class, $file); } if (false === $file) { // Remember that this class does not exist. $this->missingClasses[$class] = true; } return $file; } private function findFileWithExtension($class, $ext) { // PSR-4 lookup $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; $first = $class[0]; if (isset($this->prefixLengthsPsr4[$first])) { $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { if (file_exists($file = $dir . $pathEnd)) { return $file; } } } } } // PSR-4 fallback dirs foreach ($this->fallbackDirsPsr4 as $dir) { if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { return $file; } } // PSR-0 lookup if (false !== $pos = strrpos($class, '\\')) { // namespaced class name $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); } else { // PEAR-like class name $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; } if (isset($this->prefixesPsr0[$first])) { foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { if (0 === strpos($class, $prefix)) { foreach ($dirs as $dir) { if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { return $file; } } } } } // PSR-0 fallback dirs foreach ($this->fallbackDirsPsr0 as $dir) { if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { return $file; } } // PSR-0 include paths. if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { return $file; } return false; } } /** * Scope isolated include. * * Prevents access to $this/self from included files. */ function includeFile($file) { include $file; } PK!Agի1system/tgeoip/vendor/composer/ca-bundle/README.mdnu[composer/ca-bundle ================== Small utility library that lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle. Originally written as part of [composer/composer](https://github.com/composer/composer), now extracted and made available as a stand-alone library. Installation ------------ Install the latest version with: ```bash $ composer require composer/ca-bundle ``` Requirements ------------ * PHP 5.3.2 is required but using the latest version of PHP is highly recommended. Basic usage ----------- # `Composer\CaBundle\CaBundle` - `CaBundle::getSystemCaRootBundlePath()`: Returns the system CA bundle path, or a path to the bundled one as fallback - `CaBundle::getBundledCaBundlePath()`: Returns the path to the bundled CA file - `CaBundle::validateCaFile($filename)`: Validates a CA file using opensl_x509_parse only if it is safe to use - `CaBundle::isOpensslParseSafe()`: Test if it is safe to use the PHP function openssl_x509_parse() - `CaBundle::reset()`: Resets the static caches ## To use with curl ```php $curl = curl_init("https://example.org/"); curl_setopt($curl, CURLOPT_CAINFO, \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath()); $result = curl_exec($curl); ``` ## To use with php streams ```php $opts = array( 'http' => array( 'method' => "GET" ) ); $caPath = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(); if (is_dir($caPath)) { $opts['ssl']['capath'] = $caPath; } else { $opts['ssl']['cafile'] = $caPath; } $context = stream_context_create($opts); $result = file_get_contents('https://example.com', false, $context); ``` License ------- composer/ca-bundle is licensed under the MIT License, see the LICENSE file for details. PK!C;5system/tgeoip/vendor/composer/ca-bundle/composer.jsonnu[{ "name": "composer/ca-bundle", "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", "type": "library", "license": "MIT", "keywords": [ "cabundle", "cacert", "certificate", "ssl", "tls" ], "authors": [ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be" } ], "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues" }, "require": { "ext-openssl": "*", "ext-pcre": "*", "php": "^5.3.2 || ^7.0" }, "require-dev": { "psr/log": "^1.0", "symfony/process": "^2.5 || ^3.0" }, "suggest": { "symfony/process": "This is necessary to reliably check whether openssl_x509_parse is vulnerable on older php versions, but can be ignored on PHP 5.5.6+" }, "autoload": { "psr-4": { "Composer\\CaBundle\\": "src" } }, "autoload-dev": { "psr-4": { "Composer\\CaBundle\\": "tests" } }, "extra": { "branch-alias": { "dev-master": "1.x-dev" } } } PK!ps558system/tgeoip/vendor/composer/ca-bundle/src/CaBundle.phpnu[ * * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ namespace Composer\CaBundle; use Psr\Log\LoggerInterface; use Symfony\Component\Process\PhpProcess; /** * @author Chris Smith * @author Jordi Boggiano */ class CaBundle { private static $caPath; private static $caFileValidity = array(); private static $useOpensslParse; /** * Returns the system CA bundle path, or a path to the bundled one * * This method was adapted from Sslurp. * https://github.com/EvanDotPro/Sslurp * * (c) Evan Coury * * For the full copyright and license information, please see below: * * Copyright (c) 2013, Evan Coury * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @param LoggerInterface $logger optional logger for information about which CA files were loaded * @return string path to a CA bundle file or directory */ public static function getSystemCaRootBundlePath(LoggerInterface $logger = null) { if (self::$caPath !== null) { return self::$caPath; } // If SSL_CERT_FILE env variable points to a valid certificate/bundle, use that. // This mimics how OpenSSL uses the SSL_CERT_FILE env variable. $envCertFile = getenv('SSL_CERT_FILE'); if ($envCertFile && is_readable($envCertFile) && static::validateCaFile($envCertFile, $logger)) { return self::$caPath = $envCertFile; } // If SSL_CERT_DIR env variable points to a valid certificate/bundle, use that. // This mimics how OpenSSL uses the SSL_CERT_FILE env variable. $envCertDir = getenv('SSL_CERT_DIR'); if ($envCertDir && is_dir($envCertDir) && is_readable($envCertDir)) { return self::$caPath = $envCertDir; } $configured = ini_get('openssl.cafile'); if ($configured && strlen($configured) > 0 && is_readable($configured) && static::validateCaFile($configured, $logger)) { return self::$caPath = $configured; } $configured = ini_get('openssl.capath'); if ($configured && is_dir($configured) && is_readable($configured)) { return self::$caPath = $configured; } $caBundlePaths = array( '/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package) '/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package) '/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package) '/usr/local/share/certs/ca-root-nss.crt', // FreeBSD (ca_root_nss_package) '/usr/ssl/certs/ca-bundle.crt', // Cygwin '/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package '/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option) '/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat? '/etc/ssl/cert.pem', // OpenBSD '/usr/local/etc/ssl/cert.pem', // FreeBSD 10.x '/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package ); foreach ($caBundlePaths as $caBundle) { if (@is_readable($caBundle) && static::validateCaFile($caBundle, $logger)) { return self::$caPath = $caBundle; } } foreach ($caBundlePaths as $caBundle) { $caBundle = dirname($caBundle); if (@is_dir($caBundle) && glob($caBundle.'/*')) { return self::$caPath = $caBundle; } } return self::$caPath = static::getBundledCaBundlePath(); // Bundled CA file, last resort } /** * Returns the path to the bundled CA file * * In case you don't want to trust the user or the system, you can use this directly * * @return string path to a CA bundle file */ public static function getBundledCaBundlePath() { return __DIR__.'/../res/cacert.pem'; } /** * Validates a CA file using opensl_x509_parse only if it is safe to use * * @param string $filename * @param LoggerInterface $logger optional logger for information about which CA files were loaded * * @return bool */ public static function validateCaFile($filename, LoggerInterface $logger = null) { static $warned = false; if (isset(self::$caFileValidity[$filename])) { return self::$caFileValidity[$filename]; } $contents = file_get_contents($filename); // assume the CA is valid if php is vulnerable to // https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html if (!static::isOpensslParseSafe()) { if (!$warned && $logger) { $logger->warning(sprintf( 'Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.', PHP_VERSION )); $warned = true; } $isValid = !empty($contents); } else { $isValid = (bool) openssl_x509_parse($contents); } if ($logger) { $logger->debug('Checked CA file '.realpath($filename).': '.($isValid ? 'valid' : 'invalid')); } return self::$caFileValidity[$filename] = $isValid; } /** * Test if it is safe to use the PHP function openssl_x509_parse(). * * This checks if OpenSSL extensions is vulnerable to remote code execution * via the exploit documented as CVE-2013-6420. * * @return bool */ public static function isOpensslParseSafe() { if (null !== self::$useOpensslParse) { return self::$useOpensslParse; } if (PHP_VERSION_ID >= 50600) { return self::$useOpensslParse = true; } // Vulnerable: // PHP 5.3.0 - PHP 5.3.27 // PHP 5.4.0 - PHP 5.4.22 // PHP 5.5.0 - PHP 5.5.6 if ( (PHP_VERSION_ID < 50400 && PHP_VERSION_ID >= 50328) || (PHP_VERSION_ID < 50500 && PHP_VERSION_ID >= 50423) || (PHP_VERSION_ID < 50600 && PHP_VERSION_ID >= 50507) ) { // This version of PHP has the fix for CVE-2013-6420 applied. return self::$useOpensslParse = true; } if (defined('PHP_WINDOWS_VERSION_BUILD')) { // Windows is probably insecure in this case. return self::$useOpensslParse = false; } $compareDistroVersionPrefix = function ($prefix, $fixedVersion) { $regex = '{^'.preg_quote($prefix).'([0-9]+)$}'; if (preg_match($regex, PHP_VERSION, $m)) { return ((int) $m[1]) >= $fixedVersion; } return false; }; // Hard coded list of PHP distributions with the fix backported. if ( $compareDistroVersionPrefix('5.3.3-7+squeeze', 18) // Debian 6 (Squeeze) || $compareDistroVersionPrefix('5.4.4-14+deb7u', 7) // Debian 7 (Wheezy) || $compareDistroVersionPrefix('5.3.10-1ubuntu3.', 9) // Ubuntu 12.04 (Precise) ) { return self::$useOpensslParse = true; } // Symfony Process component is missing so we assume it is unsafe at this point if (!class_exists('Symfony\Component\Process\PhpProcess')) { return self::$useOpensslParse = false; } // This is where things get crazy, because distros backport security // fixes the chances are on NIX systems the fix has been applied but // it's not possible to verify that from the PHP version. // // To verify exec a new PHP process and run the issue testcase with // known safe input that replicates the bug. // Based on testcase in https://github.com/php/php-src/commit/c1224573c773b6845e83505f717fbf820fc18415 // changes in https://github.com/php/php-src/commit/76a7fd893b7d6101300cc656058704a73254d593 $cert = 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwRENDQTR5Z0F3SUJBZ0lKQUp6dThyNnU2ZUJjTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUhETVFzd0NRWUQKVlFRR0V3SkVSVEVjTUJvR0ExVUVDQXdUVG05eVpISm9aV2x1TFZkbGMzUm1ZV3hsYmpFUU1BNEdBMVVFQnd3SApTOE9Ed3Jac2JqRVVNQklHQTFVRUNnd0xVMlZyZEdsdmJrVnBibk14SHpBZEJnTlZCQXNNRmsxaGJHbGphVzkxCmN5QkRaWEowSUZObFkzUnBiMjR4SVRBZkJnTlZCQU1NR0cxaGJHbGphVzkxY3k1elpXdDBhVzl1WldsdWN5NWsKWlRFcU1DZ0dDU3FHU0liM0RRRUpBUlliYzNSbFptRnVMbVZ6YzJWeVFITmxhM1JwYjI1bGFXNXpMbVJsTUhVWQpaREU1TnpBd01UQXhNREF3TURBd1dnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBCkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEKQUFBQUFBQVhEVEUwTVRFeU9ERXhNemt6TlZvd2djTXhDekFKQmdOVkJBWVRBa1JGTVJ3d0dnWURWUVFJREJOTwpiM0prY21obGFXNHRWMlZ6ZEdaaGJHVnVNUkF3RGdZRFZRUUhEQWRMdzRQQ3RteHVNUlF3RWdZRFZRUUtEQXRUClpXdDBhVzl1UldsdWN6RWZNQjBHQTFVRUN3d1dUV0ZzYVdOcGIzVnpJRU5sY25RZ1UyVmpkR2x2YmpFaE1COEcKQTFVRUF3d1liV0ZzYVdOcGIzVnpMbk5sYTNScGIyNWxhVzV6TG1SbE1Tb3dLQVlKS29aSWh2Y05BUWtCRmh0egpkR1ZtWVc0dVpYTnpaWEpBYzJWcmRHbHZibVZwYm5NdVpHVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRERBZjNobDdKWTBYY0ZuaXlFSnBTU0RxbjBPcUJyNlFQNjV1c0pQUnQvOFBhRG9xQnUKd0VZVC9OYSs2ZnNnUGpDMHVLOURaZ1dnMnRIV1dvYW5TYmxBTW96NVBINlorUzRTSFJaN2UyZERJalBqZGhqaAowbUxnMlVNTzV5cDBWNzk3R2dzOWxOdDZKUmZIODFNTjJvYlhXczROdHp0TE11RDZlZ3FwcjhkRGJyMzRhT3M4CnBrZHVpNVVhd1Raa3N5NXBMUEhxNWNNaEZHbTA2djY1Q0xvMFYyUGQ5K0tBb2tQclBjTjVLTEtlYno3bUxwazYKU01lRVhPS1A0aWRFcXh5UTdPN2ZCdUhNZWRzUWh1K3ByWTNzaTNCVXlLZlF0UDVDWm5YMmJwMHdLSHhYMTJEWAoxbmZGSXQ5RGJHdkhUY3lPdU4rblpMUEJtM3ZXeG50eUlJdlZBZ01CQUFHalFqQkFNQWtHQTFVZEV3UUNNQUF3CkVRWUpZSVpJQVliNFFnRUJCQVFEQWdlQU1Bc0dBMVVkRHdRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFHMGZaWVlDVGJkajFYWWMrMVNub2FQUit2SThDOENhRAo4KzBVWWhkbnlVNGdnYTBCQWNEclk5ZTk0ZUVBdTZacXljRjZGakxxWFhkQWJvcHBXb2NyNlQ2R0QxeDMzQ2tsClZBcnpHL0t4UW9oR0QySmVxa2hJTWxEb214SE83a2EzOStPYThpMnZXTFZ5alU4QVp2V01BcnVIYTRFRU55RzcKbFcyQWFnYUZLRkNyOVRuWFRmcmR4R1ZFYnY3S1ZRNmJkaGc1cDVTanBXSDErTXEwM3VSM1pYUEJZZHlWODMxOQpvMGxWajFLRkkyRENML2xpV2lzSlJvb2YrMWNSMzVDdGQwd1lCY3BCNlRac2xNY09QbDc2ZHdLd0pnZUpvMlFnClpzZm1jMnZDMS9xT2xOdU5xLzBUenprVkd2OEVUVDNDZ2FVK1VYZTRYT1Z2a2NjZWJKbjJkZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K'; $script = <<<'EOT' error_reporting(-1); $info = openssl_x509_parse(base64_decode('%s')); var_dump(PHP_VERSION, $info['issuer']['emailAddress'], $info['validFrom_time_t']); EOT; $script = '<'."?php\n".sprintf($script, $cert); try { $process = new PhpProcess($script); $process->mustRun(); } catch (\Exception $e) { // In the case of any exceptions just accept it is not possible to // determine the safety of openssl_x509_parse and bail out. return self::$useOpensslParse = false; } $output = preg_split('{\r?\n}', trim($process->getOutput())); $errorOutput = trim($process->getErrorOutput()); if ( count($output) === 3 && $output[0] === sprintf('string(%d) "%s"', strlen(PHP_VERSION), PHP_VERSION) && $output[1] === 'string(27) "stefan.esser@sektioneins.de"' && $output[2] === 'int(-1)' && preg_match('{openssl_x509_parse\(\): illegal (?:ASN1 data type for|length in) timestamp in - on line \d+}', $errorOutput) ) { // This PHP has the fix backported probably by a distro security team. return self::$useOpensslParse = true; } return self::$useOpensslParse = false; } /** * Resets the static caches */ public static function reset() { self::$caFileValidity = array(); self::$caPath = null; self::$useOpensslParse = null; } } PK!]61E E 6system/tgeoip/vendor/composer/ca-bundle/res/cacert.pemnu[## ## Bundle of CA Root Certificates ## ## Certificate data from Mozilla as of: Wed Nov 2 04:12:05 2016 GMT ## ## 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: ## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt ## ## It contains the certificates in PEM format and therefore ## can be directly used with curl / libcurl / php_curl, or with ## an Apache+mod_ssl webserver for SSL client authentication. ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.27. ## SHA256: 17e2a90c8a5cfd6a675b3475d3d467e1ab1fe0d5397e907b08206182389caa08 ## Equifax Secure CA ================= -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW 8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 70+sB3c4 -----END CERTIFICATE----- GlobalSign Root CA ================== -----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE----- GlobalSign Root CA - R2 ======================= -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp 9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu 01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- Verisign Class 3 Public Primary Certification Authority - G3 ============================================================ -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- Entrust.net Premium 2048 Secure Server CA ========================================= -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= -----END CERTIFICATE----- Baltimore CyberTrust Root ========================= -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- AddTrust Low-Value Services Root ================================ -----BEGIN CERTIFICATE----- MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= -----END CERTIFICATE----- AddTrust External Root ====================== -----BEGIN CERTIFICATE----- MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 +iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy 2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= -----END CERTIFICATE----- AddTrust Public Services Root ============================= -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB /zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL +YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= -----END CERTIFICATE----- AddTrust Qualified Certificates Root ==================================== -----BEGIN CERTIFICATE----- MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx 64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= -----END CERTIFICATE----- Entrust Root Certification Authority ==================================== -----BEGIN CERTIFICATE----- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- RSA Security 2048 v3 ==================== -----BEGIN CERTIFICATE----- MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP +Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj 0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA pKnXwiJPZ9d37CAFYd4= -----END CERTIFICATE----- GeoTrust Global CA ================== -----BEGIN CERTIFICATE----- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet 8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm Mw== -----END CERTIFICATE----- GeoTrust Global CA 2 ==================== -----BEGIN CERTIFICATE----- MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF H4z1Ir+rzoPz4iIprn2DQKi6bA== -----END CERTIFICATE----- GeoTrust Universal CA ===================== -----BEGIN CERTIFICATE----- MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs 7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d 8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI P/rmMuGNG2+k5o7Y+SlIis5z/iw= -----END CERTIFICATE----- GeoTrust Universal CA 2 ======================= -----BEGIN CERTIFICATE----- MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP 20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG 8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 +/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ 4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS -----END CERTIFICATE----- Visa eCommerce Root =================== -----BEGIN CERTIFICATE----- MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI /k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt 398znM/jra6O1I7mT1GvFpLgXPYHDw== -----END CERTIFICATE----- Certum Root CA ============== -----BEGIN CERTIFICATE----- MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ 89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ 0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== -----END CERTIFICATE----- Comodo AAA Services root ======================== -----BEGIN CERTIFICATE----- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm 7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z 8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- Comodo Secure Services root =========================== -----BEGIN CERTIFICATE----- MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP 9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm 4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H RR3B7Hzs/Sk= -----END CERTIFICATE----- Comodo Trusted Services root ============================ -----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y /9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB /zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O 9y5Xt5hwXsjEeLBi -----END CERTIFICATE----- QuoVadis Root CA ================ -----BEGIN CERTIFICATE----- MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi 5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi 5nrQNiOKSnQ2+Q== -----END CERTIFICATE----- QuoVadis Root CA 2 ================== -----BEGIN CERTIFICATE----- MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt 66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK +JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II 4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u -----END CERTIFICATE----- QuoVadis Root CA 3 ================== -----BEGIN CERTIFICATE----- MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp 8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- Security Communication Root CA ============================== -----BEGIN CERTIFICATE----- MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw 8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX 5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g 0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ 6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi FL39vmwLAw== -----END CERTIFICATE----- Sonera Class 2 Root CA ====================== -----BEGIN CERTIFICATE----- MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 /Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt 0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH llpwrN9M -----END CERTIFICATE----- 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----- XRamp Global CA Root ==================== -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc /Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz 8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= -----END CERTIFICATE----- Go Daddy Class 2 CA =================== -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b vZ8= -----END CERTIFICATE----- Starfield Class 2 CA ==================== -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- StartCom Certification Authority ================================ -----BEGIN CERTIFICATE----- MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt 2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z 6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT 37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh 3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl 1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro g14= -----END CERTIFICATE----- Taiwan GRCA =========== -----BEGIN CERTIFICATE----- MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O 1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk 7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy +fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS -----END CERTIFICATE----- Swisscom Root CA 1 ================== -----BEGIN CERTIFICATE----- MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn 7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW NY6E0F/6MBr1mmz0DlP5OlvRHA== -----END CERTIFICATE----- DigiCert Assured ID Root CA =========================== -----BEGIN CERTIFICATE----- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO 9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW /lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF 66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i 8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- DigiCert Global Root CA ======================= -----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H 4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y 7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm 8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE----- DigiCert High Assurance EV Root CA ================================== -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K -----END CERTIFICATE----- Certplus Class 2 Primary CA =========================== -----BEGIN CERTIFICATE----- MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR 5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ 7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW //1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 l7+ijrRU -----END CERTIFICATE----- DST Root CA X3 ============== -----BEGIN CERTIFICATE----- MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ -----END CERTIFICATE----- DST ACES CA X6 ============== -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 oKfN5XozNmr6mis= -----END CERTIFICATE----- SwissSign Gold CA - G2 ====================== -----BEGIN CERTIFICATE----- MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR 7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm 5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr 44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- SwissSign Silver CA - G2 ======================== -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG 9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm +/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH 6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P 4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L 3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx /uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- GeoTrust Primary Certification Authority ======================================== -----BEGIN CERTIFICATE----- MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG 1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= -----END CERTIFICATE----- thawte Primary Root CA ====================== -----BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ 1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== -----END CERTIFICATE----- VeriSign Class 3 Public Primary Certification Authority - G5 ============================================================ -----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq -----END CERTIFICATE----- SecureTrust CA ============== -----BEGIN CERTIFICATE----- MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b 01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= -----END CERTIFICATE----- Secure Global CA ================ -----BEGIN CERTIFICATE----- MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g 8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi 0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW -----END CERTIFICATE----- COMODO Certification Authority ============================== -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH +7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV 4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA 1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== -----END CERTIFICATE----- Network Solutions Certificate Authority ======================================= -----BEGIN CERTIFICATE----- MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc /Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q 4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- WellsSecure Public Root Certificate Authority ============================================= -----BEGIN CERTIFICATE----- MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ tylv2G0xffX8oRAHh84vWdw+WNs= -----END CERTIFICATE----- COMODO ECC Certification Authority ================================== -----BEGIN CERTIFICATE----- MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X 4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- IGC/A ===== -----BEGIN CERTIFICATE----- MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF 0mBWWg== -----END CERTIFICATE----- Security Communication EV RootCA1 ================================= -----BEGIN CERTIFICATE----- MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO /VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK 9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 -----END CERTIFICATE----- OISTE WISeKey Global Root GA CA =============================== -----BEGIN CERTIFICATE----- MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ /yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 +vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= -----END CERTIFICATE----- Microsec e-Szigno Root CA ========================= -----BEGIN CERTIFICATE----- MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA 4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a 86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= -----END CERTIFICATE----- Certigna ======== -----BEGIN CERTIFICATE----- MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY 1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- Deutsche Telekom Root CA 2 ========================== -----BEGIN CERTIFICATE----- MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU Cm26OWMohpLzGITY+9HPBVZkVw== -----END CERTIFICATE----- Cybertrust Global Root ====================== -----BEGIN CERTIFICATE----- MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW 0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin 89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT 8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi 5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW WL1WMRJOEcgh4LMRkWXbtKaIOM5V -----END CERTIFICATE----- ePKI Root Certification Authority ================================= -----BEGIN CERTIFICATE----- MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX 12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= -----END CERTIFICATE----- T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 ============================================================================================================================= -----BEGIN CERTIFICATE----- MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR 6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= -----END CERTIFICATE----- Buypass Class 2 CA 1 ==================== -----BEGIN CERTIFICATE----- MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV 1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt 7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho -----END CERTIFICATE----- EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 ========================================================================== -----BEGIN CERTIFICATE----- MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0 Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB /wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK 1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt 2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9 AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT -----END CERTIFICATE----- certSIGN ROOT CA ================ -----BEGIN CERTIFICATE----- MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD 0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD -----END CERTIFICATE----- CNNIC ROOT ========== -----BEGIN CERTIFICATE----- MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m mxE= -----END CERTIFICATE----- ApplicationCA - Japanese Government =================================== -----BEGIN CERTIFICATE----- MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g /DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL rosot4LKGAfmt1t06SAZf7IbiVQ= -----END CERTIFICATE----- GeoTrust Primary Certification Authority - G3 ============================================= -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr 2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt -----END CERTIFICATE----- thawte Primary Root CA - G2 =========================== -----BEGIN CERTIFICATE----- MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== -----END CERTIFICATE----- thawte Primary Root CA - G3 =========================== -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC +BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY 7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC 8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= -----END CERTIFICATE----- GeoTrust Primary Certification Authority - G2 ============================================= -----BEGIN CERTIFICATE----- MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 npaqBA+K -----END CERTIFICATE----- VeriSign Universal Root Certification Authority =============================================== -----BEGIN CERTIFICATE----- MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj 1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 mJO37M2CYfE45k+XmCpajQ== -----END CERTIFICATE----- VeriSign Class 3 Public Primary Certification Authority - G4 ============================================================ -----BEGIN CERTIFICATE----- MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB /zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== -----END CERTIFICATE----- NetLock Arany (Class Gold) Főtanúsítvány ======================================== -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu 0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw /HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- Staat der Nederlanden Root CA - G2 ================================== -----BEGIN CERTIFICATE----- MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ 5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz +51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm 66+KAQ== -----END CERTIFICATE----- Juur-SK ======= -----BEGIN CERTIFICATE----- MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC +Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 yyqcjg== -----END CERTIFICATE----- Hongkong Post Root CA 1 ======================= -----BEGIN CERTIFICATE----- MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== -----END CERTIFICATE----- SecureSign RootCA11 =================== -----BEGIN CERTIFICATE----- MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= -----END CERTIFICATE----- ACEDICOM Root ============= -----BEGIN CERTIFICATE----- MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz 4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU 9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== -----END CERTIFICATE----- Microsec e-Szigno Root CA 2009 ============================== -----BEGIN CERTIFICATE----- MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG 0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm 1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi LXpUq3DDfSJlgnCW -----END CERTIFICATE----- GlobalSign Root CA - R3 ======================= -----BEGIN CERTIFICATE----- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ 0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r kpeDMdmztcpHWD9f -----END CERTIFICATE----- Autoridad de Certificacion Firmaprofesional CIF A62634068 ========================================================= -----BEGIN CERTIFICATE----- MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY 7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx 51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi 6Et8Vcad+qMUu2WFbm5PEn4KPJ2V -----END CERTIFICATE----- Izenpe.com ========== -----BEGIN CERTIFICATE----- MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ 03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU +zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK 0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ 0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== -----END CERTIFICATE----- Chambers of Commerce Root - 2008 ================================ -----BEGIN CERTIFICATE----- MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ 0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH 3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF 9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ -----END CERTIFICATE----- Global Chambersign Root - 2008 ============================== -----BEGIN CERTIFICATE----- MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB /gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp 1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG /5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg 9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B -----END CERTIFICATE----- Go Daddy Root Certificate Authority - G2 ======================================== -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq 9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD +qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r 5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 -----END CERTIFICATE----- Starfield Root Certificate Authority - G2 ========================================= -----BEGIN CERTIFICATE----- MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx 4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 -----END CERTIFICATE----- Starfield Services Root Certificate Authority - G2 ================================================== -----BEGIN CERTIFICATE----- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 -----END CERTIFICATE----- AffirmTrust Commercial ====================== -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv 0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= -----END CERTIFICATE----- AffirmTrust Networking ====================== -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 /PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 /ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= -----END CERTIFICATE----- AffirmTrust Premium =================== -----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV 5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs +7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 /bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo +Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC 6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK +4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== -----END CERTIFICATE----- AffirmTrust Premium ECC ======================= -----BEGIN CERTIFICATE----- MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X 57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM eQ== -----END CERTIFICATE----- Certum Trusted Network CA ========================= -----BEGIN CERTIFICATE----- MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= -----END CERTIFICATE----- Certinomis - Autorité Racine ============================ -----BEGIN CERTIFICATE----- MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw 2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g 530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna 4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ vgt2Fl43N+bYdJeimUV5 -----END CERTIFICATE----- Root CA Generalitat Valenciana ============================== -----BEGIN CERTIFICATE----- MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt +GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= -----END CERTIFICATE----- TWCA Root Certification Authority ================================= -----BEGIN CERTIFICATE----- MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP 4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG 9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== -----END CERTIFICATE----- Security Communication RootCA2 ============================== -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ +T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R 3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk 3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- EC-ACC ====== -----BEGIN CERTIFICATE----- MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw 0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D 5EI= -----END CERTIFICATE----- Hellenic Academic and Research Institutions RootCA 2011 ======================================================= -----BEGIN CERTIFICATE----- MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI 1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa 71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u 8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH 3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD /md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N 7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 -----END CERTIFICATE----- Actalis Authentication Root CA ============================== -----BEGIN CERTIFICATE----- MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC 4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo 2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== -----END CERTIFICATE----- Trustis FPS Root CA =================== -----BEGIN CERTIFICATE----- MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P 8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl iB6XzCGcKQENZetX2fNXlrtIzYE= -----END CERTIFICATE----- StartCom Certification Authority ================================ -----BEGIN CERTIFICATE----- MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt 2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z 6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT 37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA 2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= -----END CERTIFICATE----- StartCom Certification Authority G2 =================================== -----BEGIN CERTIFICATE----- MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG 4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K 2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG /+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm 7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm obp573PYtlNXLfbQ4ddI -----END CERTIFICATE----- Buypass Class 2 Root CA ======================= -----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn 9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b /+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN rJgWVqA= -----END CERTIFICATE----- Buypass Class 3 Root CA ======================= -----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR 5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh 7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH 2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV /afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz 6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi Cp/HuZc= -----END CERTIFICATE----- T-TeleSec GlobalRoot Class 3 ============================ -----BEGIN CERTIFICATE----- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK 9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W 0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== -----END CERTIFICATE----- EE Certification Centre Root CA =============================== -----BEGIN CERTIFICATE----- MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw 93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU 3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM dcGWxZ0= -----END CERTIFICATE----- TURKTRUST Certificate Services Provider Root 2007 ================================================= -----BEGIN CERTIFICATE----- MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK poRq0Tl9 -----END CERTIFICATE----- D-TRUST Root Class 3 CA 2 2009 ============================== -----BEGIN CERTIFICATE----- MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ 4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm 2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= -----END CERTIFICATE----- D-TRUST Root Class 3 CA 2 EV 2009 ================================= -----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T 7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv w9y4AyHqnxbxLFS1 -----END CERTIFICATE----- PSCProcert ========== -----BEGIN CERTIFICATE----- MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1dG9yaWRhZCBk ZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9sYW5vMQswCQYDVQQGEwJWRTEQ MA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlzdHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lz dGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBl cmludGVuZGVuY2lhIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUw IwYJKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEwMFoXDTIw MTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHByb2NlcnQubmV0LnZlMQ8w DQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGExKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBD ZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZp Y2FjaW9uIEVsZWN0cm9uaWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIw DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo97BVC wfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74BCXfgI8Qhd19L3uA 3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38GieU89RLAu9MLmV+QfI4tL3czkkoh RqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmO EO8GqQKJ/+MMbpfg353bIdD0PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG2 0qCZyFSTXai20b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH 0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/6mnbVSKVUyqU td+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1mv6JpIzi4mWCZDlZTOpx+FIyw Bm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvp r2uKGcfLFFb14dq12fy/czja+eevbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/ AgEBMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAz Ni0wMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFDgBStuyId xuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRp ZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQH EwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5h Y2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5k ZW5jaWEgZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG 9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQDAgEGME0GA1UdEQRG MESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0wMDAwMDKgGwYFYIZeAgKgEgwQUklG LUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEagRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52 ZS9sY3IvQ0VSVElGSUNBRE8tUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNy YWl6LnN1c2NlcnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsGAQUFBwIBFh5o dHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcNAQELBQADggIBACtZ6yKZu4Sq T96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmN g7+mvTV+LFwxNG9s2/NkAZiqlCxB3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4q uxtxj7mkoP3YldmvWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1 n8GhHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHmpHmJWhSn FFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXzsOfIt+FTvZLm8wyWuevo 5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bEqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq 3TNWOByyrYDT13K9mmyZY+gAu0F2BbdbmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5 poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km -----END CERTIFICATE----- China Internet Network Information Center EV Certificates Root ============================================================== -----BEGIN CERTIFICATE----- MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCQ04xMjAwBgNV BAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyMUcwRQYDVQQDDD5D aGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMg Um9vdDAeFw0xMDA4MzEwNzExMjVaFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAG A1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMM PkNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRl cyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z7r07eKpkQ0H1UN+U8i6y jUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV 98YPjUesWgbdYavi7NifFy2cyjw1l1VxzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2H klY0bBoQCxfVWhyXWIQ8hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23 KzhmBsUs4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54ugQEC 7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oYNJKiyoOCWTAPBgNV HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfHJLOcfA22KlT5uqGDSSosqD glkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd5 0XPFtQO3WKwMVC/GVhMPMdoG52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM 7+czV0I664zBechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrIzo9uoV1/A3U0 5K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATywy39FCqQmbkHzJ8= -----END CERTIFICATE----- Swisscom Root CA 2 ================== -----BEGIN CERTIFICATE----- MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQG EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2 MjUwNzM4MTRaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIIC IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvErjw0DzpPM LgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r0rk0X2s682Q2zsKwzxNo ysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJ wDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVPACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpH Wrumnf2U5NGKpV+GY3aFy6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1a SgJA/MTAtukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL6yxS NLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0uPoTXGiTOmekl9Ab mbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrALacywlKinh/LTSlDcX3KwFnUey7QY Ypqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velhk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3 qPyZ7iVNTA6z00yPhOgpD/0QVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw HQYDVR0hBBYwFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqhb97iEoHF8Twu MA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4RfbgZPnm3qKhyN2abGu2sEzsO v2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ 82YqZh6NM4OKb3xuqFp1mrjX2lhIREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLz o9v/tdhZsnPdTSpxsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcs a0vvaGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciATwoCqISxx OQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99nBjx8Oto0QuFmtEYE3saW mA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5Wt6NlUe07qxS/TFED6F+KBZvuim6c779o +sjaC+NCydAXFJy3SuCvkychVSa1ZC+N8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TC rvJcwhbtkj6EPnNgiLx29CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX 5OfNeOI5wSsSnqaeG8XmDtkx2Q== -----END CERTIFICATE----- Swisscom Root EV CA 2 ===================== -----BEGIN CERTIFICATE----- MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UE BhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdpdGFsIENlcnRpZmljYXRlIFNl cnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcN MzEwNjI1MDg0NTA4WjBnMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsT HERpZ2l0YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYg Q0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7BxUglgRCgz o3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD1ycfMQ4jFrclyxy0uYAy Xhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPHoCE2G3pXKSinLr9xJZDzRINpUKTk4Rti GZQJo/PDvO/0vezbE53PnUgJUmfANykRHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8Li qG12W0OfvrSdsyaGOx9/5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaH Za0zKcQvidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHLOdAG alNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaCNYGu+HuB5ur+rPQa m3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f46Fq9mDU5zXNysRojddxyNMkM3Ox bPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCBUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDi xzgHcgplwLa7JSnaFp6LNYth7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/ BAQDAgGGMB0GA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWBbj2ITY1x0kbB bkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6xXCX5145v9Ydkn+0UjrgEjihL j6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98TPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbU wp4wLh/vx3rEUMfqe9pQy3omywC0Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7 XwgiG/W9mR4U9s70WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH 59yLGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm7JFe3VE/ 23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4Snr8PyQUQ3nqjsTzyP6Wq J3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VNvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyA HmBR3NdUIR7KYndP+tiPsys6DXhyyWhBWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/gi uMod89a2GQ+fYWVq6nTIfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuW l8PVP3wbI+2ksx0WckNLIOFZfsLorSa/ovc= -----END CERTIFICATE----- CA Disig Root R1 ================ -----BEGIN CERTIFICATE----- MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAlNLMRMw EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp ZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQyMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sx EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp c2lnIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy 3QRkD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/oOI7bm+V8 u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3AfQ+lekLZWnDZv6fXARz2 m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJeIgpFy4QxTaz+29FHuvlglzmxZcfe+5nk CiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTa YVKvJrT1cU/J19IG32PK/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6 vpmumwKjrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD3AjL LhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE7cderVC6xkGbrPAX ZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkCyC2fg69naQanMVXVz0tv/wQFx1is XxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLdqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNV HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ 04IwDQYJKoZIhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaASfX8MPWbTx9B LxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXoHqJPYNcHKfyyo6SdbhWSVhlM CrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpBemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5Gfb VSUZP/3oNn6z4eGBrxEWi1CXYBmCAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85 YmLLW1AL14FABZyb7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKS ds+xDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvkF7mGnjix lAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqFa3qdnom2piiZk4hA9z7N UaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsTQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJ a7+h89n07eLw4+1knj0vllJPgFOL -----END CERTIFICATE----- CA Disig Root R2 ================ -----BEGIN CERTIFICATE----- MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa 5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV 7+ZtsH8tZ/3zbBt1RqPlShfppNcL -----END CERTIFICATE----- ACCVRAIZ1 ========= -----BEGIN CERTIFICATE----- MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ 0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR 5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J 9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd 3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p EfbRD0tVNEYqi4Y7 -----END CERTIFICATE----- TWCA Global Root CA =================== -----BEGIN CERTIFICATE----- MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M 8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg /eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= -----END CERTIFICATE----- TeliaSonera Root CA v1 ====================== -----BEGIN CERTIFICATE----- MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ 6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA 3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx 0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- E-Tugra Certification Authority =============================== -----BEGIN CERTIFICATE----- MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB /wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G C7TbO6Orb1wdtn7os4I07QZcJA== -----END CERTIFICATE----- T-TeleSec GlobalRoot Class 2 ============================ -----BEGIN CERTIFICATE----- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR 3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN 9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== -----END CERTIFICATE----- Atos TrustedRoot 2011 ===================== -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr 54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G 3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed -----END CERTIFICATE----- QuoVadis Root CA 1 G3 ===================== -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV 7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX 9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP +V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh 3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV hMJKzRwuJIczYOXD -----END CERTIFICATE----- QuoVadis Root CA 2 G3 ===================== -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD 6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr O3jtZsSOeWmD3n+M -----END CERTIFICATE----- QuoVadis Root CA 3 G3 ===================== -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe 6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX 0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 PpxxVJkES/1Y+Zj0 -----END CERTIFICATE----- DigiCert Assured ID Root G2 =========================== -----BEGIN CERTIFICATE----- MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH 35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv 0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo IhNzbM8m9Yop5w== -----END CERTIFICATE----- DigiCert Assured ID Root G3 =========================== -----BEGIN CERTIFICATE----- MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy 1vUhZscv6pZjamVFkpUBtA== -----END CERTIFICATE----- DigiCert Global Root G2 ======================= -----BEGIN CERTIFICATE----- MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO 3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu 5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl MrY= -----END CERTIFICATE----- DigiCert Global Root G3 ======================= -----BEGIN CERTIFICATE----- MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y 3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 VOKa5Vt8sycX -----END CERTIFICATE----- DigiCert Trusted Root G4 ======================== -----BEGIN CERTIFICATE----- MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy 7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN 5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb /UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa 5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP 82Z+ -----END CERTIFICATE----- WoSign ====== -----BEGIN CERTIFICATE----- MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNVBAMTIUNlcnRpZmljYXRpb24g QXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJ BgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA vcqNrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1UfcIiePyO CbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcSccf+Hb0v1naMQFXQoOXXDX 2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2ZjC1vt7tj/id07sBMOby8w7gLJKA84X5 KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4Mx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR +ScPewavVIMYe+HdVHpRaG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ez EC8wQjchzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDaruHqk lWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221KmYo0SLwX3OSACCK2 8jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvASh0JWzko/amrzgD5LkhLJuYwTKVY yrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWvHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0C AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R 8bNLtwYgFP6HEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1 LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJMuYhOZO9sxXq T2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2eJXLOC62qx1ViC777Y7NhRCOj y+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VNg64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC 2nz4SNAzqfkHx5Xh9T71XXG68pWpdIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes 5cVAWubXbHssw1abR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/ EaEQPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGcexGATVdVh mVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+J7x6v+Db9NpSvd4MVHAx kUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMlOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGi kpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWTee5Ehr7XHuQe+w== -----END CERTIFICATE----- WoSign China ============ -----BEGIN CERTIFICATE----- MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQG EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMMEkNBIOayg+mAmuagueiv geS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYD VQQKExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjAN BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k 8H/rD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld19AXbbQs5 uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExfv5RxadmWPgxDT74wwJ85 dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnkUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5 Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+LNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFy b7Ao65vh4YOhn0pdr8yb+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc 76DbT52VqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6KyX2m +Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0GAbQOXDBGVWCvOGU6 yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaKJ/kR8slC/k7e3x9cxKSGhxYzoacX GKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud EwEB/wQFMAMBAf8wHQYDVR0OBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUA A4ICAQBqinA4WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6 yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj/feTZU7n85iY r83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6jBAyvd0zaziGfjk9DgNyp115 j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0A kLppRQjbbpCBhqcqBT/mhDn4t/lXX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97 qA4bLJyuQHCH2u2nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Y jj4Du9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10lO1Hm13ZB ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO kI26oQ== -----END CERTIFICATE----- COMODO RSA Certification Authority ================================== -----BEGIN CERTIFICATE----- MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ 5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX 2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I LaZRfyHBNVOFBkpdn627G190 -----END CERTIFICATE----- USERTrust RSA Certification Authority ===================================== -----BEGIN CERTIFICATE----- MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz 0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O +T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq /nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ 7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM 8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 -----END CERTIFICATE----- USERTrust ECC Certification Authority ===================================== -----BEGIN CERTIFICATE----- MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu 9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= -----END CERTIFICATE----- GlobalSign ECC Root CA - R4 =========================== -----BEGIN CERTIFICATE----- MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q= -----END CERTIFICATE----- GlobalSign ECC Root CA - R5 =========================== -----BEGIN CERTIFICATE----- MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- Staat der Nederlanden Root CA - G3 ================================== -----BEGIN CERTIFICATE----- MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5 1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp 07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE 41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1 v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA 8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b 8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq 1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk= -----END CERTIFICATE----- Staat der Nederlanden EV Root CA ================================ -----BEGIN CERTIFICATE----- MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r 0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr 08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV 0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd 74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq 5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi 5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== -----END CERTIFICATE----- IdenTrust Commercial Root CA 1 ============================== -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi 1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl 3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH 6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe 2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R cGzM7vRX+Bi6hG6H -----END CERTIFICATE----- IdenTrust Public Sector Root CA 1 ================================= -----BEGIN CERTIFICATE----- MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL 4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ 3Wl9af0AVqW3rLatt8o+Ae+c -----END CERTIFICATE----- Entrust Root Certification Authority - G2 ========================================= -----BEGIN CERTIFICATE----- MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP /vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO e4pIb4tF9g== -----END CERTIFICATE----- Entrust Root Certification Authority - EC1 ========================================== -----BEGIN CERTIFICATE----- MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef 9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G -----END CERTIFICATE----- CFCA EV ROOT ============ -----BEGIN CERTIFICATE----- MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD 7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB /wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua 4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su -----END CERTIFICATE----- TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 ==================================================== -----BEGIN CERTIFICATE----- MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537 jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP 9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV 4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8 B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU= -----END CERTIFICATE----- TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 ==================================================== -----BEGIN CERTIFICATE----- MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQGEwJUUjEPMA0G A1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5 MDQxMFoXDTIzMTIxNjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBL BgNVBAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSf aSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlm aWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQCdsGjW6L0UlqMACprx9MfMkU1xeHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a 2uqsxgbPJQ1BgfbBOCK9+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EED wnS3/faAz1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0pu5Fb HH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6plVxiSvgNZ1GpryHV +DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMBAAGjQjBAMB0GA1UdDgQWBBTdVRcT 9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG 9w0BAQsFAAOCAQEAb1gNl0OqFlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3R fdCaqaXKGDsCQC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKIDgI6tflEATseW hvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm9ocJV612ph1jmv3XZch4gyt1 O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsGtAuYSyher4hYyw== -----END CERTIFICATE----- Certinomis - Root CA ==================== -----BEGIN CERTIFICATE----- MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00 8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE 6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I 6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9 Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr hkIGuUE= -----END CERTIFICATE----- OISTE WISeKey Global Root GB CA =============================== -----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk 9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB /zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= -----END CERTIFICATE----- Certification Authority of WoSign G2 ==================================== -----BEGIN CERTIFICATE----- MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9 5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3 TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu +sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+ 7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg= -----END CERTIFICATE----- CA WoSign ECC Root ================== -----BEGIN CERTIFICATE----- MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0 Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu a/GRspBl9JrmkO5K -----END CERTIFICATE----- SZAFIR ROOT CA2 =============== -----BEGIN CERTIFICATE----- MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE 2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul 4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 +/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== -----END CERTIFICATE----- Certum Trusted Network CA 2 =========================== -----BEGIN CERTIFICATE----- MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ 9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 zAYspsbiDrW5viSP -----END CERTIFICATE----- Hellenic Academic and Research Institutions RootCA 2015 ======================================================= -----BEGIN CERTIFICATE----- MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ 6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn 82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q p/UsQu0yrbYhnr68 -----END CERTIFICATE----- Hellenic Academic and Research Institutions ECC RootCA 2015 =========================================================== -----BEGIN CERTIFICATE----- MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR -----END CERTIFICATE----- Certplus Root CA G1 =================== -----BEGIN CERTIFICATE----- MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2 z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc 4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd 4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+ ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh 66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/ 2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F 6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/ +mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+ qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= -----END CERTIFICATE----- Certplus Root CA G2 =================== -----BEGIN CERTIFICATE----- MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0 cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw== -----END CERTIFICATE----- OpenTrust Root CA G1 ==================== -----BEGIN CERTIFICATE----- MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87 ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9 xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO 9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq 3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9 URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB /zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80 nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/ bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o 4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx -----END CERTIFICATE----- OpenTrust Root CA G2 ==================== -----BEGIN CERTIFICATE----- MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+ Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz 4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz 3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj 3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz 9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0 0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB /zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59 M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ 6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0 YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK -----END CERTIFICATE----- OpenTrust Root CA G3 ==================== -----BEGIN CERTIFICATE----- MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB /wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta 3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB -----END CERTIFICATE----- ISRG Root X1 ============ -----BEGIN CERTIFICATE----- MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ 4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf 1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY 9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV 0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ m+kXQ99b21/+jh5Xos1AnX5iItreGCc= -----END CERTIFICATE----- PK!"",system/tgeoip/vendor/composer/installed.jsonnu[[ { "name": "composer/ca-bundle", "version": "1.0.6", "version_normalized": "1.0.6.0", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", "reference": "a795611394b3c05164fd0eb291b492b39339cba4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/ca-bundle/zipball/a795611394b3c05164fd0eb291b492b39339cba4", "reference": "a795611394b3c05164fd0eb291b492b39339cba4", "shasum": "" }, "require": { "ext-openssl": "*", "ext-pcre": "*", "php": "^5.3.2 || ^7.0" }, "require-dev": { "psr/log": "^1.0", "symfony/process": "^2.5 || ^3.0" }, "suggest": { "symfony/process": "This is necessary to reliably check whether openssl_x509_parse is vulnerable on older php versions, but can be ignored on PHP 5.5.6+" }, "time": "2016-11-02T18:11:27+00:00", "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { "Composer\\CaBundle\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be" } ], "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", "keywords": [ "cabundle", "cacert", "certificate", "ssl", "tls" ] }, { "name": "geoip2/geoip2", "version": "v2.4.5", "version_normalized": "2.4.5.0", "source": { "type": "git", "url": "https://github.com/maxmind/GeoIP2-php.git", "reference": "b28a0ed0190cd76c878ed7002a5d1bb8c5f4c175" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/b28a0ed0190cd76c878ed7002a5d1bb8c5f4c175", "reference": "b28a0ed0190cd76c878ed7002a5d1bb8c5f4c175", "shasum": "" }, "require": { "maxmind-db/reader": "~1.0", "maxmind/web-service-common": "~0.3", "php": ">=5.3.1" }, "require-dev": { "phpunit/phpunit": "4.2.*", "squizlabs/php_codesniffer": "2.*" }, "time": "2017-01-31T17:28:48+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "GeoIp2\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "authors": [ { "name": "Gregory J. Oschwald", "email": "goschwald@maxmind.com", "homepage": "http://www.maxmind.com/" } ], "description": "MaxMind GeoIP2 PHP API", "homepage": "https://github.com/maxmind/GeoIP2-php", "keywords": [ "IP", "geoip", "geoip2", "geolocation", "maxmind" ] }, { "name": "maxmind-db/reader", "version": "v1.1.3", "version_normalized": "1.1.3.0", "source": { "type": "git", "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", "reference": "7eeccf61b078bb23bb07b1a151a7e5db52871e65" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/7eeccf61b078bb23bb07b1a151a7e5db52871e65", "reference": "7eeccf61b078bb23bb07b1a151a7e5db52871e65", "shasum": "" }, "require": { "php": ">=5.3.1" }, "require-dev": { "phpunit/phpunit": "4.2.*", "satooshi/php-coveralls": "1.0.*", "squizlabs/php_codesniffer": "2.*" }, "suggest": { "ext-bcmath": "bcmath or gmp is requred for decoding larger integers with the pure PHP decoder", "ext-gmp": "bcmath or gmp is requred for decoding larger integers with the pure PHP decoder", "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups" }, "time": "2017-01-19T23:49:38+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "MaxMind\\Db\\": "src/MaxMind/Db" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "authors": [ { "name": "Gregory J. Oschwald", "email": "goschwald@maxmind.com", "homepage": "http://www.maxmind.com/" } ], "description": "MaxMind DB Reader API", "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php", "keywords": [ "database", "geoip", "geoip2", "geolocation", "maxmind" ] }, { "name": "maxmind/web-service-common", "version": "v0.3.1", "version_normalized": "0.3.1.0", "source": { "type": "git", "url": "https://github.com/maxmind/web-service-common-php.git", "reference": "1fe780bcd6a9038b7e36b13fa0aeeeeca4cdb0a4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/1fe780bcd6a9038b7e36b13fa0aeeeeca4cdb0a4", "reference": "1fe780bcd6a9038b7e36b13fa0aeeeeca4cdb0a4", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0.3", "ext-curl": "*", "ext-json": "*", "php": ">=5.3" }, "require-dev": { "phpunit/phpunit": "4.*", "squizlabs/php_codesniffer": "2.*" }, "time": "2016-08-18T16:36:52+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "MaxMind\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "authors": [ { "name": "Gregory Oschwald", "email": "goschwald@maxmind.com" } ], "description": "Internal MaxMind Web Service API", "homepage": "https://github.com/maxmind/mm-web-service-api-php" }, { "name": "splitbrain/php-archive", "version": "1.1.1", "version_normalized": "1.1.1.0", "source": { "type": "git", "url": "https://github.com/splitbrain/php-archive.git", "reference": "10d89013572ba1f4d4ad7fcb74860242f4c3860b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/splitbrain/php-archive/zipball/10d89013572ba1f4d4ad7fcb74860242f4c3860b", "reference": "10d89013572ba1f4d4ad7fcb74860242f4c3860b", "shasum": "" }, "require": { "php": ">=5.4" }, "require-dev": { "ext-bz2": "*", "ext-zip": "*", "mikey179/vfsstream": "^1.6", "phpunit/phpunit": "^4.8" }, "suggest": { "ext-iconv": "Used for proper filename encode handling", "ext-mbstring": "Can be used alternatively for handling filename encoding" }, "time": "2018-09-09T12:13:53+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "splitbrain\\PHPArchive\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Andreas Gohr", "email": "andi@splitbrain.org" } ], "description": "Pure-PHP implementation to read and write TAR and ZIP archives", "keywords": [ "archive", "extract", "tar", "unpack", "unzip", "zip" ] } ] PK!`/system/tgeoip/vendor/composer/autoload_real.phpnu[= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInit2994eebabe3e6b260b60cab24a9b085e::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { $loader->set($namespace, $path); } $map = require __DIR__ . '/autoload_psr4.php'; foreach ($map as $namespace => $path) { $loader->setPsr4($namespace, $path); } $classMap = require __DIR__ . '/autoload_classmap.php'; if ($classMap) { $loader->addClassMap($classMap); } } $loader->register(true); return $loader; } } PK!t!ו5system/tgeoip/vendor/composer/autoload_namespaces.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; require_once __DIR__ . '/script.install.helper.php'; class PlgSystemTGeoIPInstallerScript extends PlgSystemTGeoIPInstallerScriptHelper { public $name = 'TGEOIP'; public $alias = 'tgeoip'; public $extension_type = 'plugin'; public $show_message = false; } PK!ı'system/tgeoip/tgeoip.xmlnu[ plg_system_tgeoip PLG_SYSTEM_TGEOIP_DESC 2.2.1 06 Mar 2017 Tassos Marinos Copyright © 2020 Tassos Marinos All Rights Reserved http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL info@tassos.gr http://www.tassos.gr script.install.php tgeoip.php script.install.helper.php db field helper language vendor
PK!PF11system/tgeoip/helper/tgeoip.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; use GeoIp2\Database\Reader; use splitbrain\PHPArchive\Tar; use NRFramework\User; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class TGeoIP { /** * The MaxMind GeoLite database reader * * @var Reader */ private $reader = null; /** * Records for IP addresses already looked up * * @var array * */ private $lookups = array(); /** * Max Age Database before it needs an update * * @var integer */ private $maxAge = 30; /** * Database File name * * @var string */ private $DBFileName = 'GeoLite2-City'; /** * Database Remote URL * * @var string */ private $DBUpdateURL = 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=USER_LICENSE_KEY&suffix=tar.gz'; /** * GeoIP Enable Geolocations Documentation URL * * @var string */ private $TGeoIPEnableDocURL = 'https://www.tassos.gr/kb/general/how-to-enable-geolocation-features-in-tassos-gr-extensions'; /** * The IP address to look up * * @var string */ private $ip; /** * The License Key * * @var string */ private $key; /** * Public constructor. Loads up the GeoLite2 database. */ public function __construct($ip = null) { if (!function_exists('bcadd') || !function_exists('bcmul') || !function_exists('bcpow')) { require_once __DIR__ . '/fakebcmath.php'; } // Check we have a valid GeoLite2 database $filePath = $this->getDBPath(); if (!JFile::exists($filePath)) { $this->reader = null; } try { $this->reader = new Reader($filePath); } // If anything goes wrong, MaxMind will raise an exception, resulting in a WSOD. Let's be sure to catch everything. catch(\Exception $e) { $this->reader = null; } // Setup IP $this->ip = $ip ?: User::getIP(); if (in_array($this->ip, array('127.0.0.1', '::1'))) { $this->ip = ''; } } /** * Sets the license key * * @param string * * @return mixed */ public function setKey($key) { $this->key = $key; } /** * Retrieves the key * * @return string */ private function getKey() { if ($this->key) { return $this->key; } $plugin = JPluginHelper::getPlugin('system', 'tgeoip'); $params = new JRegistry($plugin->params); return $params->get('license_key', ''); } /** * Set the IP to look up * * @param string $ip The IP to look up */ public function setIP($ip) { $this->ip = $ip; return $this; } /** * Gets the ISO country code from an IP address * * @return mixed A string with the country ISO code if found, false if the IP address is not found, null if the db can't be loaded */ public function getCountryCode() { $record = $this->getRecord(); if ($record === false || is_null($record)) { return false; } return $record->country->isoCode; } /** * Gets the country name from an IP address * * @param string $locale The locale of the country name, e.g 'de' to return the country names in German. If not specified the English (US) names are returned. * * @return mixed A string with the country name if found, false if the IP address is not found, null if the db can't be loaded */ public function getCountryName($locale = null) { $record = $this->getRecord(); if ($record === false || is_null($record)) { return false; } if (empty($locale)) { return $record->country->name; } return $record->country->names[$locale]; } /** * Gets the continent ISO code from an IP address * * @return mixed A string with the country name if found, false if the IP address is not found, null if the db can't be loaded */ public function getContinentCode($locale = null) { $record = $this->getRecord(); if ($record === false || is_null($record)) { return false; } return $record->continent->code; } /** * Gets the continent name from an IP address * * @param string $locale The locale of the continent name, e.g 'de' to return the country names in German. If not specified the English (US) names are returned. * * @return mixed A string with the country name if found, false if the IP address is not found, null if the db can't be loaded */ public function getContinentName($locale = null) { $record = $this->getRecord(); if ($record === false || is_null($record)) { return false; } if (empty($locale)) { return $record->continent; } return $record->continent->names[$locale]; } /** * Gets a raw record from an IP address * * @return mixed A \GeoIp2\Model\City record if found, false if the IP address is not found, null if the db can't be loaded */ public function getRecord() { if (empty($this->ip)) { return false; } $ip = $this->ip; $needsToLoad = !array_key_exists($ip, $this->lookups); if ($needsToLoad) { try { if (!is_null($this->reader)) { $this->lookups[$ip] = $this->reader->city($ip); } else { $this->lookups[$ip] = null; } } catch (\GeoIp2\Exception\AddressNotFoundException $e) { $this->lookups[$ip] = false; } catch (\Exception $e) { // GeoIp2 could throw several different types of exceptions. Let's be sure that we're going to catch them all $this->lookups[$ip] = null; } } return $this->lookups[$ip]; } /** * Gets the city's name from an IP address * * @param string $locale The locale of the city's name, e.g 'de' to return the city names in German. If not specified the English (US) names are returned. * @return mixed A string with the city name if found, false if the IP address is not found, null if the db can't be loaded */ public function getCity($locale = null) { $record = $this->getRecord(); if ($record === false || is_null($record)) { return false; } if (empty($locale)) { return $record->city->name; } return $record->city->names[$locale]; } /** * Gets a geographical region's (i.e. a country's province/state) name from an IP address * * @param string $locale The locale of the regions's name, e.g 'de' to return region names in German. If not specified the English (US) names are returned. * @return mixed A string with the region's name if found, false if the IP address is not found, null if the db can't be loaded */ public function getRegionName($locale = null) { $record = $this->getRecord(); if ($record === false || is_null($record)) { return false; } // MaxMind stores region information in a 'Subdivision' object (also found in $record->city->subdivision) // http://maxmind.github.io/GeoIP2-php/doc/v2.9.0/class-GeoIp2.Record.Subdivision.html if (empty($locale)) { return $record->mostSpecificSubdivision->name; } return $record->mostSpecificSubdivision->names[$locale]; } /** * Gets a geographical region's (i.e. a country's province/state) ISO 3611-2 (alpha-2) code from an IP address * * @return mixed A string with the region's code if found, false if the IP address is not found, null if the db can't be loaded */ public function getRegionCode() { $record = $this->getRecord(); if ($record === false || is_null($record)) { return false; } // MaxMind stores region information in a 'Subdivision' object // http://maxmind.github.io/GeoIP2-php/doc/v2.9.0/class-GeoIp2.Record.Subdivision.html return $record->mostSpecificSubdivision->isoCode; } /** * Downloads and installs a fresh copy of the GeoLite2 City database * * @return mixed True on success, error string on failure */ public function updateDatabase() { // Try to download the package, if I get any exception I'll simply stop here and display the error try { $compressed = $this->downloadDatabase(); } catch (\Exception $e) { return $e->getMessage(); } // Write the downloaded file to a temporary location $target = $this->getTempFolder() . $this->DBFileName . '.tar.gz'; if (JFile::write($target, $compressed) === false) { return JText::_('PLG_SYSTEM_TGEOIP_ERR_WRITEFAILED'); } // Unzip database to the same temporary location $tar = new Tar; $tar->open($target); $extracted_files = $tar->extract($this->getTempFolder()); $database_file = ''; $extracted_folder = ''; // Loop through extracted files to find the name of the extracted folder and the name of the database file foreach ($extracted_files as $key => $extracted_file) { if ($extracted_file->getIsdir()) { $extracted_folder = $extracted_file->getPath(); } if (strpos($extracted_file->getPath(), '.mmdb') === false) { continue; } $database_file = $extracted_file->getPath(); } // Move database file to the correct location if (!JFile::move($this->getTempFolder() . $database_file, $this->getDBPath())) { return JText::sprintf('PLG_SYSTEM_TGEOIP_ERR_CANTWRITE', $this->getDBPath()); } // Make sure the database is readable if (!$this->dbIsValid()) { return JText::_('PLG_SYSTEM_TGEOIP_ERR_INVALIDDB'); } // Delete leftovers JFile::delete($target); JFolder::delete($this->getTempFolder() . $extracted_folder); return true; } /** * Double check if MaxMind can actually read and validate the downloaded database * * @return bool */ private function dbIsValid() { try { $reader = new Reader($this->getDBPath()); } catch (\Exception $e) { return false; } return true; } /** * Download the compressed database for the provider * * @return string The compressed data * * @throws Exception */ private function downloadDatabase() { // Make sure we have enough memory limit ini_set('memory_limit', '-1'); $license_key = $this->getKey(); if (empty($license_key)) { throw new \Exception(JText::_('PLG_SYSTEM_TGEOIP_LICENSE_KEY_EMPTY') . ' ' . JText::_('PLG_SYSTEM_TGEOIP_ENABLE_DOC_LINK_LABEL') . ''); } $http = JHttpFactory::getHttp(); $this->DBUpdateURL = str_replace('USER_LICENSE_KEY', $license_key, $this->DBUpdateURL); // Let's bubble up the exception, we will take care in the caller $response = $http->get($this->DBUpdateURL); $compressed = $response->body; // 401 is thrown if you have incorrect credentials or wrong license key if ($response->code == 401) { throw new \Exception(JText::_('PLG_SYSTEM_TGEOIP_ERR_WRONG_LICENSE_KEY')); } // Generic check on valid HTTP code if ($response->code > 299) { throw new \Exception(JText::_('PLG_SYSTEM_TGEOIP_ERR_MAXMIND_GENERIC')); } // An empty file indicates a problem with MaxMind's servers if (empty($compressed)) { throw new \Exception(JText::_('PLG_SYSTEM_TGEOIP_ERR_EMPTYDOWNLOAD')); } // Sometimes you get a rate limit exceeded if (stristr($compressed, 'Rate limited exceeded') !== false) { throw new \Exception(JText::_('PLG_SYSTEM_TGEOIP_ERR_MAXMINDRATELIMIT')); } return $compressed; } /** * Reads (and checks) the temp Joomla folder * * @return string */ private function getTempFolder() { $ds = DIRECTORY_SEPARATOR; $tmpdir = JFactory::getConfig()->get('tmp_path'); if (realpath($tmpdir) == $ds . 'tmp') { $tmpdir = JPATH_SITE . $ds . 'tmp'; } elseif (!JFolder::exists($tmpdir)) { $tmpdir = JPATH_SITE . $ds . 'tmp'; } return JPath::clean(trim($tmpdir) . $ds); } /** * Returns Database local file path * * @return string */ private function getDBPath() { return JPATH_ROOT . '/plugins/system/tgeoip/db/' . $this->DBFileName . '.mmdb'; } /** * Does the GeoIP database need update? * * @return boolean */ public function needsUpdate() { // Get the modification time of the database file $modTime = @filemtime($this->getDBPath()); // This is now $now = time(); // Minimum time difference $threshold = $this->maxAge * 24 * 3600; // Do we need an update? $needsUpdate = ($now - $modTime) > $threshold; return $needsUpdate; } }PK!@@#system/tgeoip/helper/fakebcmath.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die; if (!function_exists('bcadd')) { function bcadd($Num1,$Num2,$Scale=null) { // check if they're valid positive numbers, extract the whole numbers and decimals if(!preg_match("/^\+?(\d+)(\.\d+)?$/",$Num1,$Tmp1)|| !preg_match("/^\+?(\d+)(\.\d+)?$/",$Num2,$Tmp2)) return('0'); // this is where the result is stored $Output=array(); // remove ending zeroes from decimals and remove point $Dec1=isset($Tmp1[2])?rtrim(substr($Tmp1[2],1),'0'):''; $Dec2=isset($Tmp2[2])?rtrim(substr($Tmp2[2],1),'0'):''; // calculate the longest length of decimals $DLen=max(strlen($Dec1),strlen($Dec2)); // if $Scale is null, automatically set it to the amount of decimal places for accuracy if($Scale==null) $Scale=$DLen; // remove leading zeroes and reverse the whole numbers, then append padded decimals on the end $Num1=strrev(ltrim($Tmp1[1],'0').str_pad($Dec1,$DLen,'0')); $Num2=strrev(ltrim($Tmp2[1],'0').str_pad($Dec2,$DLen,'0')); // calculate the longest length we need to process $MLen=max(strlen($Num1),strlen($Num2)); // pad the two numbers so they are of equal length (both equal to $MLen) $Num1=str_pad($Num1,$MLen,'0'); $Num2=str_pad($Num2,$MLen,'0'); // process each digit, keep the ones, carry the tens (remainders) for($i=0;$i<$MLen;$i++) { $Sum=((int)$Num1[$i]+(int)$Num2[$i]); if(isset($Output[$i])) $Sum+=$Output[$i]; $Output[$i]=$Sum%10; if($Sum>9) $Output[$i+1]=1; } // convert the array to string and reverse it $Output=strrev(implode($Output)); // substring the decimal digits from the result, pad if necessary (if $Scale > amount of actual decimals) // next, since actual zero values can cause a problem with the substring values, if so, just simply give '0' // next, append the decimal value, if $Scale is defined, and return result $Decimal=str_pad(substr($Output,-$DLen,$Scale),$Scale,'0'); $Output=(($MLen-$DLen<1)?'0':substr($Output,0,-$DLen)); $Output.=(($Scale>0)?".{$Decimal}":''); return($Output); } } if (!function_exists('bcmul')) { function bcmul($Num1='0',$Num2='0') { // check if they're both plain numbers if(!preg_match("/^\d+$/",$Num1)||!preg_match("/^\d+$/",$Num2)) return(0); // remove zeroes from beginning of numbers for($i=0;$i1&&$Rema2[0]=='0') $Rema2=substr($Rema2,1); return($Rema2); } } if (!function_exists('bcpow')) { function bcpow($num, $power) { $answer = "1"; while ($power) { $answer = bcmul($answer, $num, 100); $power--; } return rtrim($answer, '0.'); } }PK!9#TTsystem/fields/fields.xmlnu[ plg_system_fields Joomla! Project 2016-03 (C) 2016 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.7.0 PLG_SYSTEM_FIELDS_XML_DESCRIPTION Joomla\Plugin\System\Fields services src language/en-GB/plg_system_fields.ini language/en-GB/plg_system_fields.sys.ini PK!2*Ʀ#system/fields/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\User\UserFactoryInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\Fields\Extension\Fields; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Fields( $dispatcher, (array) PluginHelper::getPlugin('system', 'fields') ); $plugin->setApplication(Factory::getApplication()); $plugin->setUserFactory($container->get(UserFactoryInterface::class)); return $plugin; } ); } }; PK!pֈo8o8&system/fields/src/Extension/Fields.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Fields\Extension; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\User\UserFactoryAwareTrait; use Joomla\Component\Fields\Administrator\Helper\FieldsHelper; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Fields Plugin * * @since 3.7 */ final class Fields extends CMSPlugin { use UserFactoryAwareTrait; /** * Load the language file on instantiation. * * @var boolean * @since 3.7.0 */ protected $autoloadLanguage = true; /** * Normalizes the request data. * * @param string $context The context * @param object $data The object * @param Form $form The form * * @return void * * @since 3.8.7 */ public function onContentNormaliseRequestData($context, $data, Form $form) { if (!FieldsHelper::extract($context, $data)) { return; } // Loop over all fields foreach ($form->getGroup('com_fields') as $field) { if ($field->disabled === true) { /** * Disabled fields should NEVER be added to the request as * they should NEVER be added by the browser anyway so nothing to check against * as "disabled" means no interaction at all. */ // Make sure the data object has an entry before delete it if (isset($data->com_fields[$field->fieldname])) { unset($data->com_fields[$field->fieldname]); } continue; } // Make sure the data object has an entry if (isset($data->com_fields[$field->fieldname])) { continue; } // Set a default value for the field $data->com_fields[$field->fieldname] = false; } } /** * The save event. * * @param string $context The context * @param \Joomla\CMS\Table\Table $item The table * @param boolean $isNew Is new item * @param array $data The validated data * * @return void * * @since 3.7.0 */ public function onContentAfterSave($context, $item, $isNew, $data = []): void { // Check if data is an array and the item has an id if (!is_array($data) || empty($item->id) || empty($data['com_fields'])) { return; } // Create correct context for category if ($context === 'com_categories.category') { $context = $item->extension . '.categories'; // Set the catid on the category to get only the fields which belong to this category $item->catid = $item->id; } // Check the context $parts = FieldsHelper::extract($context, $item); if (!$parts) { return; } // Compile the right context for the fields $context = $parts[0] . '.' . $parts[1]; // Loading the fields $fields = FieldsHelper::getFields($context, $item); if (!$fields) { return; } // Loading the model /** @var \Joomla\Component\Fields\Administrator\Model\FieldModel $model */ $model = $this->getApplication()->bootComponent('com_fields')->getMVCFactory() ->createModel('Field', 'Administrator', ['ignore_request' => true]); // Loop over the fields foreach ($fields as $field) { // Determine the value if it is (un)available from the data if (array_key_exists($field->name, $data['com_fields'])) { $value = $data['com_fields'][$field->name] === false ? null : $data['com_fields'][$field->name]; } else { // Field not available on form, use stored value $value = $field->rawvalue; } // If no value set (empty) remove value from database if (is_array($value) ? !count($value) : !strlen($value)) { $value = null; } // JSON encode value for complex fields if (is_array($value) && (count($value, COUNT_NORMAL) !== count($value, COUNT_RECURSIVE) || !count(array_filter(array_keys($value), 'is_numeric')))) { $value = json_encode($value); } // Setting the value for the field and the item $model->setFieldValue($field->id, $item->id, $value); } } /** * The save event. * * @param array $userData The date * @param boolean $isNew Is new * @param boolean $success Is success * @param string $msg The message * * @return void * * @since 3.7.0 */ public function onUserAfterSave($userData, $isNew, $success, $msg): void { // It is not possible to manipulate the user during save events // Check if data is valid or we are in a recursion if (!$userData['id'] || !$success) { return; } $user = $this->getUserFactory()->loadUserById($userData['id']); $task = $this->getApplication()->getInput()->getCmd('task'); // Skip fields save when we activate a user, because we will lose the saved data if (in_array($task, ['activate', 'block', 'unblock'])) { return; } // Trigger the events with a real user $this->onContentAfterSave('com_users.user', $user, false, $userData); } /** * The delete event. * * @param string $context The context * @param \stdClass $item The item * * @return void * * @since 3.7.0 */ public function onContentAfterDelete($context, $item): void { // Set correct context for category if ($context === 'com_categories.category') { $context = $item->extension . '.categories'; } $parts = FieldsHelper::extract($context, $item); if (!$parts || empty($item->id)) { return; } $context = $parts[0] . '.' . $parts[1]; /** @var \Joomla\Component\Fields\Administrator\Model\FieldModel $model */ $model = $this->getApplication()->bootComponent('com_fields')->getMVCFactory() ->createModel('Field', 'Administrator', ['ignore_request' => true]); $model->cleanupValues($context, $item->id); } /** * The user delete event. * * @param \stdClass $user The context * @param boolean $success Is success * @param string $msg The message * * @return void * * @since 3.7.0 */ public function onUserAfterDelete($user, $success, $msg): void { $item = new \stdClass(); $item->id = $user['id']; $this->onContentAfterDelete('com_users.user', $item); } /** * The form event. * * @param Form $form The form * @param \stdClass $data The data * * @return boolean * * @since 3.7.0 */ public function onContentPrepareForm(Form $form, $data) { $context = $form->getName(); // When a category is edited, the context is com_categories.categorycom_content if (strpos($context, 'com_categories.category') === 0) { $context = str_replace('com_categories.category', '', $context) . '.categories'; $data = $data ?: $this->getApplication()->getInput()->get('jform', [], 'array'); // Set the catid on the category to get only the fields which belong to this category if (is_array($data) && array_key_exists('id', $data)) { $data['catid'] = $data['id']; } if (is_object($data) && isset($data->id)) { $data->catid = $data->id; } } $parts = FieldsHelper::extract($context, $form); if (!$parts) { return true; } $input = $this->getApplication()->getInput(); // If we are on the save command we need the actual data $jformData = $input->get('jform', [], 'array'); if ($jformData && !$data) { $data = $jformData; } if (is_array($data)) { $data = (object) $data; } FieldsHelper::prepareForm($parts[0] . '.' . $parts[1], $form, $data); return true; } /** * The display event. * * @param string $context The context * @param \stdClass $item The item * @param Registry $params The params * @param integer $limitstart The start * * @return string * * @since 3.7.0 */ public function onContentAfterTitle($context, $item, $params, $limitstart = 0) { return $this->display($context, $item, $params, 1); } /** * The display event. * * @param string $context The context * @param \stdClass $item The item * @param Registry $params The params * @param integer $limitstart The start * * @return string * * @since 3.7.0 */ public function onContentBeforeDisplay($context, $item, $params, $limitstart = 0) { return $this->display($context, $item, $params, 2); } /** * The display event. * * @param string $context The context * @param \stdClass $item The item * @param Registry $params The params * @param integer $limitstart The start * * @return string * * @since 3.7.0 */ public function onContentAfterDisplay($context, $item, $params, $limitstart = 0) { return $this->display($context, $item, $params, 3); } /** * Performs the display event. * * @param string $context The context * @param \stdClass $item The item * @param Registry $params The params * @param integer $displayType The type * * @return string * * @since 3.7.0 */ private function display($context, $item, $params, $displayType) { $parts = FieldsHelper::extract($context, $item); if (!$parts) { return ''; } // If we have a category, set the catid field to fetch only the fields which belong to it if ($parts[1] === 'categories' && !isset($item->catid)) { $item->catid = $item->id; } $context = $parts[0] . '.' . $parts[1]; // Convert tags if ($context == 'com_tags.tag' && !empty($item->type_alias)) { // Set the context $context = $item->type_alias; $item = $this->prepareTagItem($item); } if (is_string($params) || !$params) { $params = new Registry($params); } $fields = FieldsHelper::getFields($context, $item, $displayType); if ($fields) { if ($this->getApplication()->isClient('site') && Multilanguage::isEnabled() && isset($item->language) && $item->language === '*') { $lang = $this->getApplication()->getLanguage()->getTag(); foreach ($fields as $key => $field) { if ($field->language === '*' || $field->language == $lang) { continue; } unset($fields[$key]); } } } if ($fields) { foreach ($fields as $key => $field) { $fieldDisplayType = $field->params->get('display', '2'); if ($fieldDisplayType == $displayType) { continue; } unset($fields[$key]); } } if ($fields) { return FieldsHelper::render( $context, 'fields.render', [ 'item' => $item, 'context' => $context, 'fields' => $fields, ] ); } return ''; } /** * Performs the display event. * * @param string $context The context * @param \stdClass $item The item * * @return void * * @since 3.7.0 */ public function onContentPrepare($context, $item) { // Check property exists (avoid costly & useless recreation), if need to recreate them, just unset the property! if (isset($item->jcfields)) { return; } $parts = FieldsHelper::extract($context, $item); if (!$parts) { return; } $context = $parts[0] . '.' . $parts[1]; // Convert tags if ($context == 'com_tags.tag' && !empty($item->type_alias)) { // Set the context $context = $item->type_alias; $item = $this->prepareTagItem($item); } // Get item's fields, also preparing their value property for manual display // (calling plugins events and loading layouts to get their HTML display) $fields = FieldsHelper::getFields($context, $item, true); // Adding the fields to the object $item->jcfields = []; foreach ($fields as $key => $field) { $item->jcfields[$field->id] = $field; } } /** * Prepares a tag item to be ready for com_fields. * * @param \stdClass $item The item * * @return object * * @since 3.8.4 */ private function prepareTagItem($item) { // Map core fields $item->id = $item->content_item_id; $item->language = $item->core_language; // Also handle the catid if (!empty($item->core_catid)) { $item->catid = $item->core_catid; } return $item; } } PK!A%system/redirect/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\Redirect\Extension\Redirect; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Redirect( $dispatcher, (array) PluginHelper::getPlugin('system', 'redirect') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!//system/redirect/redirect.xmlnu[ plg_system_redirect Joomla! Project 2009-04 (C) 2009 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_SYSTEM_REDIRECT_XML_DESCRIPTION Joomla\Plugin\System\Redirect form services src language/en-GB/plg_system_redirect.ini language/en-GB/plg_system_redirect.sys.ini
PK!%|$$*system/redirect/src/Extension/Redirect.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Redirect\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Event\ErrorEvent; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use Joomla\Event\SubscriberInterface; use Joomla\String\StringHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Plugin class for redirect handling. * * @since 1.6 */ final class Redirect extends CMSPlugin implements SubscriberInterface { use DatabaseAwareTrait; /** * Affects constructor behavior. If true, language files will be loaded automatically. * * @var boolean * @since 3.4 */ protected $autoloadLanguage = false; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.0.0 */ public static function getSubscribedEvents(): array { return ['onError' => 'handleError']; } /** * Internal processor for all error handlers * * @param ErrorEvent $event The event object * * @return void * * @since 3.5 */ public function handleError(ErrorEvent $event) { /** @var \Joomla\CMS\Application\CMSApplication $app */ $app = $event->getApplication(); if ($app->isClient('administrator') || ((int) $event->getError()->getCode() !== 404)) { return; } $uri = Uri::getInstance(); // These are the original URLs $orgurl = rawurldecode($uri->toString(['scheme', 'host', 'port', 'path', 'query', 'fragment'])); $orgurlRel = rawurldecode($uri->toString(['path', 'query', 'fragment'])); // The above doesn't work for sub directories, so do this $orgurlRootRel = str_replace(Uri::root(), '', $orgurl); // For when users have added / to the url $orgurlRootRelSlash = str_replace(Uri::root(), '/', $orgurl); $orgurlWithoutQuery = rawurldecode($uri->toString(['scheme', 'host', 'port', 'path', 'fragment'])); $orgurlRelWithoutQuery = rawurldecode($uri->toString(['path', 'fragment'])); // These are the URLs we save and use $url = StringHelper::strtolower(rawurldecode($uri->toString(['scheme', 'host', 'port', 'path', 'query', 'fragment']))); $urlRel = StringHelper::strtolower(rawurldecode($uri->toString(['path', 'query', 'fragment']))); // The above doesn't work for sub directories, so do this $urlRootRel = str_replace(Uri::root(), '', $url); // For when users have added / to the url $urlRootRelSlash = str_replace(Uri::root(), '/', $url); $urlWithoutQuery = StringHelper::strtolower(rawurldecode($uri->toString(['scheme', 'host', 'port', 'path', 'fragment']))); $urlRelWithoutQuery = StringHelper::strtolower(rawurldecode($uri->toString(['path', 'fragment']))); $excludes = (array) $this->params->get('exclude_urls'); $skipUrl = false; foreach ($excludes as $exclude) { if (empty($exclude->term)) { continue; } if (!empty($exclude->regexp)) { // Only check $url, because it includes all other sub urls if (preg_match('/' . $exclude->term . '/i', $orgurlRel)) { $skipUrl = true; break; } } else { if (StringHelper::strpos($orgurlRel, $exclude->term) !== false) { $skipUrl = true; break; } } } /** * Why is this (still) here? * Because hackers still try urls with mosConfig_* and Url Injection with =http[s]:// and we dont want to log/redirect these requests */ if ($skipUrl || (strpos($url, 'mosConfig_') !== false) || (strpos($url, '=http') !== false)) { return; } $query = $this->getDatabase()->getQuery(true); $query->select('*') ->from($this->getDatabase()->quoteName('#__redirect_links')) ->whereIn( $this->getDatabase()->quoteName('old_url'), [ $url, $urlRel, $urlRootRel, $urlRootRelSlash, $urlWithoutQuery, $urlRelWithoutQuery, $orgurl, $orgurlRel, $orgurlRootRel, $orgurlRootRelSlash, $orgurlWithoutQuery, $orgurlRelWithoutQuery, ], ParameterType::STRING ); $this->getDatabase()->setQuery($query); $redirect = null; try { $redirects = $this->getDatabase()->loadAssocList(); } catch (\Exception $e) { $event->setError(new \Exception($this->getApplication()->getLanguage()->_('PLG_SYSTEM_REDIRECT_ERROR_UPDATING_DATABASE'), 500, $e)); return; } $possibleMatches = array_unique( [ $url, $urlRel, $urlRootRel, $urlRootRelSlash, $urlWithoutQuery, $urlRelWithoutQuery, $orgurl, $orgurlRel, $orgurlRootRel, $orgurlRootRelSlash, $orgurlWithoutQuery, $orgurlRelWithoutQuery, ] ); foreach ($possibleMatches as $match) { if (($index = array_search($match, array_column($redirects, 'old_url'))) !== false) { $redirect = (object) $redirects[$index]; if ((int) $redirect->published === 1) { break; } } } // A redirect object was found and, if published, will be used if ($redirect !== null && ((int) $redirect->published === 1)) { if (!$redirect->header || (bool) ComponentHelper::getParams('com_redirect')->get('mode', false) === false) { $redirect->header = 301; } if ($redirect->header < 400 && $redirect->header >= 300) { $urlQuery = $uri->getQuery(); $oldUrlParts = parse_url($redirect->old_url); $newUrl = $redirect->new_url; if ($urlQuery !== '' && empty($oldUrlParts['query'])) { $newUrl .= '?' . $urlQuery; } $dest = Uri::isInternal($newUrl) || strpos($newUrl, 'http') === false ? Route::_($newUrl) : $newUrl; // In case the url contains double // lets remove it $destination = str_replace(Uri::root() . '/', Uri::root(), $dest); // Always count redirect hits $redirect->hits++; try { $this->getDatabase()->updateObject('#__redirect_links', $redirect, 'id'); } catch (\Exception $e) { // We don't log issues for now } $app->redirect($destination, (int) $redirect->header); } $event->setError(new \RuntimeException($event->getError()->getMessage(), $redirect->header, $event->getError())); } elseif ($redirect === null) { // No redirect object was found so we create an entry in the redirect table if ((bool) $this->params->get('collect_urls', 1)) { if (!$this->params->get('includeUrl', 1)) { $url = $urlRel; } $nowDate = Factory::getDate()->toSql(); $data = (object) [ 'id' => 0, 'old_url' => $url, 'referer' => $app->getInput()->server->getString('HTTP_REFERER', ''), 'hits' => 1, 'published' => 0, 'created_date' => $nowDate, 'modified_date' => $nowDate, ]; try { $this->getDatabase()->insertObject('#__redirect_links', $data, 'id'); } catch (\Exception $e) { $event->setError(new \Exception($this->getApplication()->getLanguage()->_('PLG_SYSTEM_REDIRECT_ERROR_UPDATING_DATABASE'), 500, $e)); return; } } } else { // We have an unpublished redirect object, increment the hit counter $redirect->hits++; try { $this->getDatabase()->updateObject('#__redirect_links', $redirect, ['id']); } catch (\Exception $e) { $event->setError(new \Exception($this->getApplication()->getLanguage()->_('PLG_SYSTEM_REDIRECT_ERROR_UPDATING_DATABASE'), 500, $e)); return; } } } } PK!.!system/redirect/form/excludes.xmlnu[
PK!TT@system/helixultimate/language/en-GB.plg_system_helixultimate.ininu[;Basic Tab HELIX_ULTIMATE_BASIC="Basic" HELIX_ULTIMATE_GROUP_GLOBAL="Global" HELIX_ULTIMATE_GROUP_LOGO="Logo" HELIX_ULTIMATE_GROUP_HEADER="Header" HELIX_ULTIMATE_GROUP_BODY="Body" HELIX_ULTIMATE_GROUP_FOOTER="Footer" HELIX_ULTIMATE_GROUP_SOCIAL_ICONS="Social Icons" HELIX_ULTIMATE_GROUP_CONTACT_INFO="Contact Info" HELIX_ULTIMATE_GROUP_COMINGSOON="Coming Soon" HELIX_ULTIMATE_GROUP_ERRORPAGE="Error Page" HELIX_ULTIMATE_MODULE_POSITIONS="Module Position" HELIX_ULTIMATE_MODULE_POSITIONS_DESC="Select a module position from the following list." HELIX_ULTIMATE_FEATURE_POSITION="Feature Position" HELIX_ULTIMATE_FEATURE_POSITION_DESC="Set the position of this feature from the following list." HELIX_ULTIMATE_FEATURE_POSITION_DEFAULT="Default" HELIX_ULTIMATE_FEATURE_POSITION_BEFORE="Before Module" HELIX_ULTIMATE_FEATURE_POSITION_AFTER="After Module" HELIX_ULTIMATE_GROUP_OTHERS="Others" HELIX_ULTIMATE_LOGO_TYPE="Logo Type" HELIX_ULTIMATE_LOGO_TYPE_IMAGE="Image" HELIX_ULTIMATE_LOGO_TYPE_TEXT="Text" HELIX_ULTIMATE_LOGO="Logo" HELIX_ULTIMATE_LOGO_HEIGHT="Logo Height" HELIX_ULTIMATE_LOGO_HEIGHT_SM="Logo Height (Tablet)" HELIX_ULTIMATE_LOGO_HEIGHT_XS="Logo Height (Mobile)" HELIX_ULTIMATE_MOBILE_LOGO="Mobile Logo" HELIX_ULTIMATE_MOBILE_LOGO_DESC="This logo will be shown in mobile view instead of default logo. Leave blank if you do not want to show different logo for mobile devices." HELIX_ULTIMATE_MOBILE_LOGO_RETINA="Retina Logo" HELIX_ULTIMATE_MOBILE_LOGO_RETINA_DESC="This logo will be shown on the retina display. The retina logo should be twice the size of the default logo. Say if the default logo is 100x100 then the retina logo should be 200x200." HELIX_ULTIMATE_LOGO_ALT_TEXT="Logo Alt Text" HELIX_ULTIMATE_LOGO_ALT_TEXT_DESC="Logo Alt Text can enhance your SEO performance. Use concise but brief (as possible) alt text for your site logo." HELIX_ULTIMATE_LOGO_CUSTOM_LINK="Logo Custom Link" HELIX_ULTIMATE_LOGO_CUSTOM_LINK_DESC="Custom Logo link if you want to reditect to other page rather then the root URL" HELIX_ULTIMATE_LOGO_TYPE_TEXT="Text" HELIX_ULTIMATE_LOGO_SLOGAN="logo Slogan" HELIX_ULTIMATE_PREDEFINED_HEADER="Predefined Header" HELIX_ULTIMATE_PREDEFINED_HEADER_DESC="Enable this option to use a predefined header provided by Helix Ultimate." HELIX_ULTIMATE_HEADER_HEIGHT="Header Height" HELIX_ULTIMATE_HEADER_HEIGHT_SM="Header Height (Tablet)" HELIX_ULTIMATE_HEADER_HEIGHT_XS="Header Height (Mobile)" HELIX_ULTIMATE_STICKY_HEADER_MD="Sticky Header" HELIX_ULTIMATE_STICKY_HEADER_SM="Sticky Header (Tablet)" HELIX_ULTIMATE_STICKY_HEADER_XS="Sticky Header (Mobile)" HELIX_ULTIMATE_ENABLE_SEARCH="Enable Search" HELIX_ULTIMATE_ENABLE_SEARCH_DESC="Enable search and show it to the header." HELIX_ULTIMATE_ENABLE_LOGIN="Enable Login" HELIX_ULTIMATE_ENABLE_LOGIN_DESC="Enable login and show it to the header." HELIX_ULTIMATE_HEADER_STYLE_1="Top Bar" HELIX_ULTIMATE_HEADER_STYLE_2="Classic Layout" HELIX_ULTIMATE_HEADER_STYLE_FULL_MODAL="Full Modal" HELIX_ULTIMATE_HEADER_STYLE_CENTER_MODAL="Center Modal" HELIX_ULTIMATE_HEADER_STYLE_LEFT_MODAL="Left Modal" HELIX_ULTIMATE_HEADER_STYLE_MULTI_ROWS="Multi Rows" HELIX_ULTIMATE_HEADER_STYLE_FULLWIDTH_CENTER="Fullwidth Center" HELIX_ULTIMATE_HEADER_STYLE_FULLWIDTH_LEFT="Fullwidth Left" HELIX_ULTIMATE_HEADER_STYLE_MINIMAL_LAYOUT="Minimal Layout" HELIX_ULTIMATE_TOPBAR_MSG_DRAFTING="Drafting..." HELIX_ULTIMATE_TOPBAR_MSG_RESET_DRAFT="Reset" HELIX_ULTIMATE_TOPBAR_MSG_DRAFTED="Drafted" HELIX_ULTIMATE_ENABLE_OFFCANVAS_SEARCH="Enable Search" HELIX_ULTIMATE_ENABLE_OFFCANVAS_SEARCH_DESC="Enable search field to render at off-canvas." HELIX_ULTIMATE_ENABLE_OFFCANVAS_LOGIN="Enable Login" HELIX_ULTIMATE_ENABLE_OFFCANVAS_LOGIN_DESC="Enable login field to render at off-canvas." HELIX_ULTIMATE_ENABLE_OFFCANVAS_SOCIALS="Show Social Links" HELIX_ULTIMATE_ENABLE_OFFCANVAS_SOCIALS_DESC="Enable to show the social links to the off-canvas." HELIX_ULTIMATE_ENABLE_OFFCANVAS_CONTACTS="Show Contact" HELIX_ULTIMATE_ENABLE_OFFCANVAS_CONTACTS_DESC="Enable to show the contact information to the off-canvas." HELIX_ULTIMATE_COMINGSOON_COUNTDOWN="Countdown" ; Basics HELIX_ULTIMATE_FAVICON="Favicon" HELIX_ULTIMATE_FAVICON_DESC="Upload a 16x16 .png or .gif image that will be your favicon." HELIX_ULTIMATE_PRELOADER="Preloader" HELIX_ULTIMATE_PRELOADER_LOADER_TYPE="Loader Type" HELIX_ULTIMATE_PRELOADER_LOADER_TYPE_DESC="Select a preloader animation." HELIX_ULTIMATE_LOADER_CIRCLE="Circle" HELIX_ULTIMATE_LOADER_BUBBLE_LOOP="Bubble Loops" HELIX_ULTIMATE_LOADER_WAVE_TWO="Two Waves" HELIX_ULTIMATE_LOADER_AUDIO_WAVE="Audio Wave" HELIX_ULTIMATE_LOADER_CIRCLE_TWO="Two Circles" HELIX_ULTIMATE_LOADER_CLOCK="Clock" HELIX_ULTIMATE_LOADER_LOGO="Logo" HELIX_ULTIMATE_ENABLE_BOXED_LAYOUT="Boxed Layout" HELIX_ULTIMATE_BODY_BACKGROUND_IMAGE="Background Image" HELIX_ULTIMATE_COPYRIGHT="Copyright" HELIX_ULTIMATE_GO_TO_TOP="Go to Top" HELIX_ULTIMATE_GROUP_COOKIE_CONSENT="Cookie Consent" HELIX_ULTIMATE_ENABLE_COOKIE_CONSENT="Enable" HELIX_ULTIMATE_ENABLE_COOKIE_CONTENT="Content" HELIX_ULTIMATE_ENABLE_COOKIE_BG_COLOR="Background Color" HELIX_ULTIMATE_ENABLE_COOKIE_TEXT_COLOR="Text Color" HELIX_ULTIMATE_ENABLE_COOKIE_ALLOW="Allow Cookies" HELIX_ULTIMATE_GROUP_ANALYTICS="Analytics" HELIX_ULTIMATE_GOOGLE_ANALYTICS_CODE="Google Analytics 4 Tracking ID" HELIX_ULTIMATE_GOOGLE_ANALYTICS_CODE_DESC="Google Analytics Tracking Code" HELIX_ULTIMATE_GOOGLE_ANALYTICS_TRACKING_METHOD="Tracking Method" HELIX_ULTIMATE_GOOGLE_ANALYTICS_TRACKING_METHOD_DESC="Google analytics tracking method." HELIX_ULTIMATE_GOOGLE_ANALYTICS_UNIVERSAL_ANALYTICS="Universal Analytics" HELIX_ULTIMATE_GOOGLE_ANALYTICS_GOOGLE_SITE_TAGS="Global Site Tag" HELIX_ULTIMATE_GOOGLE_ANALYTICS_SELECT_TRACKING_METHOD="-- Select a Tracking Method --" ;Megamenu HELIX_ULTIMATE_MEGAMENU_ADD_NEW_ROW="Add New Row" HELIX_ULTIMATE_MENU=" Mega Menu" HELIX_ULTIMATE_SUB_MENU="Helix Menu Options" HELIX_ULTIMATE_MENU_SHOW_TITLE="Show Menu Title" HELIX_ULTIMATE_MENU_SHOW_TITLE_DESC="Disable this option to hide menu title." HELIX_ULTIMATE_MENU_ICON="Menu Icon" HELIX_ULTIMATE_MENU_ICON_DESC="Select any icon from the list to display just before this menu item title." HELIX_ULTIMATE_MENU_CLASS="Custom CSS Class" HELIX_ULTIMATE_MENU_CLASS_DESC="Add custom css class to this menu item." HELIX_ULTIMATE_MENU_MANAGE_LAYOUT="Manage Layout" HELIX_ULTIMATE_GLOBAL_LEFT="Left" HELIX_ULTIMATE_GLOBAL_CENTER="Center" HELIX_ULTIMATE_GLOBAL_RIGHT="Right" HELIX_ULTIMATE_GLOBAL_FULL="Full" HELIX_ULTIMATE_GLOBAL_RESET="Reset" HELIX_ULTIMATE_MENU_SUB_WIDTH="Width" HELIX_ULTIMATE_MENU_ENABLED="Mega Menu" HELIX_ULTIMATE_MENU_MODULE_LIST="Module List" HELIX_ULTIMATE_SEARCH_MODULE_HINT="Search For Module" HELIX_ULTIMATE_MODULE_INSERT="Insert" HELIX_ULTIMATE_MENU_CHOOSE_LAYOUT="Choose Layout" HELIX_ULTIMATE_YES="Yes" HELIX_ULTIMATE_NO="NO" HELIX_ULTIMATE_MENU_DROPDOWN_POSITION="Dropdown Position" HELIX_ULTIMATE_MENU_DROPDOWN_POSITION_DESC="Set the position of the dropdown under this menu item." HELIX_ULTIMATE_MENU_SUB_ALIGNMENT="Alignment" HELIX_ULTIMATE_MENU_SHOW_TITLE="Show Menu Title" HELIX_ULTIMATE_MENU_ICON="Icon" HELIX_ULTIMATE_GLOBAL_SELECT="Select" HELIX_ULTIMATE_MENU_CUSTOM_CLASS="Custom Class" HELIX_ULTIMATE_MENU_BADGE_TEXT="Badge" HELIX_ULTIMATE_MENU_BADGE_POSITION="Badge Position" HELIX_ULTIMATE_MENU_BADGE_BACKGROUND="Badge Background" HELIX_ULTIMATE_MENU_BADGE_COLOR="Badge Text Color" HELIX_ULTIMATE_PAGE_TITLE_HEADING="Heading H1 or H2" HELIX_ULTIMATE_PAGE_TITLE_HEADING_DESC="Set the page title to be either an <h1> or <h2> element." HELIX_ULTIMATE_SELECT_OFFCANVAS="Select Off-canvas" HELIX_ULTIMATE_SELECT_OFFCANVAS_DESC="Select an off-canvas for mobile menu." ;Page Title HELIX_ULTIMATE_PAGE_TITLE="Page Title" HELIX_ULTIMATE_ENABLE_PAGE_TITLE="Enable Page Title" HELIX_ULTIMATE_ENABLE_PAGE_TITLE_DESC="Enable this option show page title after just below the header." HELIX_ULTIMATE_PAGE_TITLE_ALT="Alternative Title" HELIX_ULTIMATE_PAGE_TITLE_ALT_DESC="Alternative title will override Joomla default menu title." HELIX_ULTIMATE_PAGE_SUBTITLE="Page Subtitle" HELIX_ULTIMATE_PAGE_SUBTITLE_DESC="Add a brief description about the page as page subtitle." HELIX_ULTIMATE_PAGE_TITLE_BACKGROUND_COLOR="Background Color" HELIX_ULTIMATE_PAGE_TITLE_BACKGROUND_COLOR_DESC="Background color for the title area." HELIX_ULTIMATE_PAGE_TITLE_BACKGROUND_IMAGE="Background Image" HELIX_ULTIMATE_PAGE_TITLE_BACKGROUND_IMAGE_DESC="Add background image for the title area." ;Blog HELIX_ULTIMATE_BLOG_OPTIONS=" Blog Media" HELIX_ULTIMATE_UPLOAD_IMAGE="Upload Image" HELIX_ULTIMATE_REMOVE_IMAGE="Remove Image" HELIX_ULTIMATE_UPLOAD_IMAGES="Upload Images" HELIX_ULTIMATE_REMOVE_GALLERY_IMAGE="Remove" HELIX_ULTIMATE_BLOG_ARTICLE_FORMAT="Article Format" HELIX_ULTIMATE_BLOG_FEATURED_IMAGE="Featured Image" HELIX_ULTIMATE_BLOG_POST_FORMAT_STANDARD=" Standard" HELIX_ULTIMATE_BLOG_POST_FORMAT_VIDEO=" Video" HELIX_ULTIMATE_BLOG_POST_FORMAT_GALLERY=" Gallery" HELIX_ULTIMATE_BLOG_POST_FORMAT_AUDIO=" Audio" HELIX_ULTIMATE_BLOG_POST_FORMAT_GALLERY_LABEL="Upload Gallery Images" HELIX_ULTIMATE_BLOG_POST_FORMAT_GALLERY_DESCRIPTION="Select one or more images" HELIX_ULTIMATE_BLOG_POST_FORMAT_AUDIO_LABEL="Audio Embed Code" HELIX_ULTIMATE_BLOG_POST_FORMAT_AUDIO_DESCRIPTION="Write Your Audio Embed Code Here" HELIX_ULTIMATE_BLOG_POST_FORMAT_VIDEO_LABEL="Video URL" HELIX_ULTIMATE_BLOG_POST_FORMAT_VIDEO_DESCRIPTION="Add YouTube or Vimeo full URL." HELIX_ULTIMATE_IMAGE_LARGE_CROP_QUALITY="Quality" HELIX_ULTIMATE_IMAGE_LARGE_CROP_QUALITY_DESC="Set image quality for better compressions. Applicable for JPG images only." HELIX_ULTIMATE_BLOG_DETAILS_REMOVE_CONTAINER="Full-width Layout" ;Layout HELIX_ULTIMATE_SECTION_TITLE="Section" ;Menu Builder HELIX_ULTIMATE_MENU_EXTRA_CLASS="Custom Class" HELIX_ULTIMATE_MENU_EXTRA_CLASS_PLACEHOLDER="Add custom classes" HELIX_ULTIMATE_MENU_ICON="Icon" HELIX_ULTIMATE_MENU_ICON_PLACEHOLDER="Add an Icon." HELIX_ULTIMATE_MENU_CAPTION="Caption" HELIX_ULTIMATE_MENU_CAPTION_PLACEHOLDER="Add a caption." HELIX_ULTIMATE_ENABLE_MEGA_MENU="Mega Menu" HELIX_ULTIMATE_ENABLE_MEGA_MENU_DESC="Enable mega menu for the menu item: '%s'" HELIX_ULTIMATE_MEGA_MENU_WIDTH="Menu Width" HELIX_ULTIMATE_SHOW_MENU_TITLE="Show Menu Title" HELIX_ULTIMATE_MEGA_MENU_CUSTOM_CLASSES="Custom Classes" HELIX_ULTIMATE_MEGA_MENU_ALIGNMENT="Alignment" HELIX_ULTIMATE_MEGA_MENU_ALIGNMENT_DESC="Set menu alignment" HELIX_ULTIMATE_MEGA_ROW_SETTINGS_GROUP_GENERAL="General Settings" HELIX_ULTIMATE_MEGA_ROW_LABEL="Label" HELIX_ULTIMATE_MEGA_ROW_LABEL_DESC="Define a label for identifying the row." HELIX_ULTIMATE_MEGA_ROW_ENABLE_TITLE="Enable Title" HELIX_ULTIMATE_MEGA_ROW_ENABLE_TITLE_DESC="Enable row title to show on your site." HELIX_ULTIMATE_MEGA_ROW_TITLE="Title" HELIX_ULTIMATE_MEGA_ROW_TITLE_DESC="The title to show." HELIX_ULTIMATE_MEGA_ROW_SELECTOR_ID="ID" HELIX_ULTIMATE_MEGA_ROW_SELECTOR_ID_DESC="Row ID selector" HELIX_ULTIMATE_MEGA_ROW_SELECTOR_CLASS="Class" HELIX_ULTIMATE_MEGA_ROW_SELECTOR_CLASS_DESC="Row class selector." HELIX_ULTIMATE_MEGA_ROW_SETTINGS_GROUP_STYLES="Styles" HELIX_ULTIMATE_MEGA_ROW_MARGIN="Margin" HELIX_ULTIMATE_MEGA_ROW_MARGIN_DESC="Set the margin values with space separation (Top Right Bottom Left). The default unit is px. You can specify your own unit with the value." HELIX_ULTIMATE_MEGA_ROW_PADDING="Padding" HELIX_ULTIMATE_MEGA_ROW_PADDING_DESC="Set the padding values with space separation (Top Right Bottom Left). The default unit is px. You can specify your own unit with the value." HELIX_ULTIMATE_MEGA_ROW_SETTINGS_GROUP_RESPONSIVE="Responsive" HELIX_ULTIMATE_MEGA_ROW_HIDE_PHONE="Hide on Phone" HELIX_ULTIMATE_MEGA_ROW_HIDE_PHONE_DESC="Hide this row in phone." HELIX_ULTIMATE_MEGA_ROW_HIDE_LARGE_PHONE="Hide on Large Phone" HELIX_ULTIMATE_MEGA_ROW_HIDE_LARGE_PHONE_DESC="Hide this row in large phone." HELIX_ULTIMATE_MEGA_ROW_HIDE_TABLET="Hide on Tablet" HELIX_ULTIMATE_MEGA_ROW_HIDE_TABLET_DESC="Hide this row in tablet devices." HELIX_ULTIMATE_MEGA_ROW_HIDE_SMALL_DESKTOP="Hide on Smaller Desktop" HELIX_ULTIMATE_MEGA_ROW_HIDE_SMALL_DESKTOP_DESC="Hide this row in smaller desktop devices." HELIX_ULTIMATE_MEGA_ROW_HIDE_DESKTOP="Hide on Desktop" HELIX_ULTIMATE_MEGA_ROW_HIDE_DESKTOP_DESC="Hide this row in desktop devices." HELIX_ULTIMATE_MEGA_COL_LABEL="Colum Label" HELIX_ULTIMATE_MEGA_COL_LABEL_DESC="Add a label for identifying the column." HELIX_ULTIMATE_MEGA_COL_TYPE="Column Type" HELIX_ULTIMATE_MEGA_COL_TYPE_DESC="Select a type for this column." HELIX_ULTIMATE_MEGA_MODULE_STYLE="Module Style" HELIX_ULTIMATE_MEGA_MODULE_STYLE_DESC="Select a module style." HELIX_ULTIMATE_MEGA_MODULE_POSITIONS="Module Position" HELIX_ULTIMATE_MEGA_MODULE_POSITIONS_DESC="Select a module position" HELIX_ULTIMATE_MEGA_MODULE_CUSTOM_POSITIONS="Custom Module Position" HELIX_ULTIMATE_MEGA_MODULE_CUSTOM_POSITIONS_DESC="Create a new custom module position." HELIX_ULTIMATE_MEGA_MODULE="Module" HELIX_ULTIMATE_MEGA_MODULE_DESC="Select a module" HELIX_ULTIMATE_MENU_HIERARCHY_SELECT_ALL="Select All Items" HELIX_ULTIMATE_COLUMN_SETTINGS_MODULE_POSITION="Module Position" HELIX_ULTIMATE_COLUMN_SETTINGS_MODULE="Module" HELIX_ULTIMATE_COLUMN_SETTINGS_MENU_ITEMS="Menu Items" HELIX_ULTIMATE_MEGA_ENABLE_COL_TITLE="Enable Column Title" HELIX_ULTIMATE_MEGA_ENABLE_COL_TITLE_DESC="Enable column title for displaying." HELIX_ULTIMATE_MEGA_COL_TITLE="Column Title" HELIX_ULTIMATE_MEGA_COL_TITLE_DESC="Enter a title for the column." HELIX_ULTIMATE_MEGA_COL_SELECTOR_ID="Column ID" HELIX_ULTIMATE_MEGA_COL_SELECTOR_ID_DESC="Enter a custom unique CSS ID for the column." HELIX_ULTIMATE_MEGA_COL_SELECTOR_CLASS="Column Class" HELIX_ULTIMATE_MEGA_COL_SELECTOR_CLASS_DESC="Enter a custom CSS class for the column." HELIX_ULTIMATE_MEGA_COL_MARGIN="Margin" HELIX_ULTIMATE_MEGA_COL_MARGIN_DESC="Set the margin values with space separation (Top Right Bottom Left). The default unit is px. You can specify your own unit with the value." HELIX_ULTIMATE_MEGA_COL_PADDING="Padding" HELIX_ULTIMATE_MEGA_COL_PADDING_DESC="Set the padding values with space separation (Top Right Bottom Left). The default unit is px. You can specify your own unit with the value." HELIX_ULTIMATE_MEGA_COL_HIDE_PHONE="Hide on Phone" HELIX_ULTIMATE_MEGA_COL_HIDE_PHONE_DESC="Hide this column on phone." HELIX_ULTIMATE_MEGA_COL_HIDE_LARGE_PHONE="Hide on Large Phone" HELIX_ULTIMATE_MEGA_COL_HIDE_LARGE_PHONE_DESC="Hide this column on large phone." HELIX_ULTIMATE_MEGA_COL_HIDE_TABLET="Hide on Tablet" HELIX_ULTIMATE_MEGA_COL_HIDE_TABLET_DESC="Hide this column on tablet." HELIX_ULTIMATE_MEGA_COL_HIDE_SMALL_DESKTOP="Hide on Small Desktop" HELIX_ULTIMATE_MEGA_COL_HIDE_SMALL_DESKTOP_DESC="Hide this column on small desktop." HELIX_ULTIMATE_MEGA_COL_HIDE_DESKTOP="Hide on Desktop" HELIX_ULTIMATE_MEGA_COL_HIDE_DESKTOP_DESC="Hide this colun on desktop." HELIX_ULTIMATE_MENU_BADGE="Badge" HELIX_ULTIMATE_MENU_BADGE_PLACEHOLDER="Badge" HELIX_ULTIMATE_MENU_BADGE_POSITION="Left" HELIX_ULTIMATE_MENU_EDIT="Edit" HELIX_ULTIMATE_MENU_DELETE="Delete" HELIX_ULTIMATE_MENU_MEGAMENU="Mega Menu" HELIX_ULTIMATE_MENU_OPTIONS="Settings" HELIX_ULTIMATE_CUSTOM_LAYOUT_TEXT="Custom" HELIX_ULTIMATE_CUSTOM_LAYOUT_LABEL="Custom Layout" HELIX_ULTIMATE_MEGAMENU_APPLY_TEXT="Apply" ;Custom Code HELIX_ULTIMATE_CUSTOM_CODE="Custom Code" HELIX_ULTIMATE_BEFORE_HEAD="Before </head>" HELIX_ULTIMATE_BEFORE_HEAD_DESC="Any code you place here will appear in the head section of every page of your site. This feature is useful when you need to add verification code, JavaScript or CSS links to all pages." HELIX_ULTIMATE_AFTER_BODY="After <body>" HELIX_ULTIMATE_AFTER_BODY_DESC="Any code you place here will be appeared just after the opening body tag." HELIX_ULTIMATE_BEFORE_BODY="Before </body>" HELIX_ULTIMATE_BEFORE_BODY_DESC="Any code you place here will appear at the bottom of the body section of all pages of your site. This feature is useful if you need to input a tracking code for a state counter such as Google Analytics or Clicky." HELIX_ULTIMATE_CUSTOM_CSS="Custom CSS" HELIX_ULTIMATE_CUSTOM_CSS_DESC="You can use custom CSS to add your styles or overwrite default CSS to a template or extension. This option is useful for small changes in the stylesheets. For more extensive changes (more than 10 lines of code) we suggest to use the custom.css file." HELIX_ULTIMATE_CUSTOM_JS="Custom Javascript" HELIX_ULTIMATE_CUSTOM_JS_DESC="You can add custom JavaScript code. It loads your custom Javascript file after all other JavaScript files (except special hardcoded occasions), allowing you to be the last one who will affect your website." ; Missings HELIX_ULTIMATE_PREDEFINED_HEADER="Predefined Header" HELIX_ULTIMATE_PREDEFINED_HEADER_DESC="Enable this option to use a predefined header provided by Helix Ultimate." HELIX_ULTIMATE_LOGO_ALT_TEXT="Logo Alt Text" HELIX_ULTIMATE_LOGO_ALT_TEXT_DESC="Logo Alt Text can enhance your SEO performance. Use concise but brief (as possible) alt text for your site logo." HELIX_ULTIMATE_LOGO_TYPE_TEXT="Text" HELIX_ULTIMATE_LOGO_SLOGAN="logo Slogan" HELIX_ULTIMATE_STICKY_HEADER_MD="Sticky Header" HELIX_ULTIMATE_STICKY_HEADER_SM="Sticky Header (Tablet)" HELIX_ULTIMATE_STICKY_HEADER_XS="Sticky Header (Mobile)" HELIX_ULTIMATE_PREDEFINED_PRESETS="Pre-defined Presets" HELIX_ULTIMATE_GROUP_MENUBUILDER="Menu Builder" HELIX_ULTIMATE_FONT_COLOR="Color" HELIX_ULTIMATE_FONT_LETTER_SPACING="Spacing" HELIX_ULTIMATE_FONT_ALIGNMENT="Alignment" HELIX_ULTIMATE_FONT_LINE_HEIGHT="Line Height" HELIX_ULTIMATE_FONT_DECORATION="Decoration" HELIX_ULTIMATE_GROUP_IMAGE="Image" HELIX_ULTIMATE_ENABLE_IMAGE_LAZY_LOADING="Lazy Loading" HELIX_ULTIMATE_ENABLE_IMAGE_LAZY_LOADING_DESC="Enable this option will allow you to load all of your images in a lazy mode. This will defer all the offscreen images." HELIX_ULTIMATE_GROUP_ANALYTICS="Analytics" HELIX_ULTIMATE_GOOGLE_ANALYTICS_CODE="Google Analytics 4 Tracking ID" HELIX_ULTIMATE_GOOGLE_ANALYTICS_CODE_DESC="Google Analytics Tracking Code" HELIX_ULTIMATE_GOOGLE_ANALYTICS_TRACKING_METHOD="Tracking Method" HELIX_ULTIMATE_GOOGLE_ANALYTICS_TRACKING_METHOD_DESC="Google analytics tracking method." HELIX_ULTIMATE_GOOGLE_ANALYTICS_UNIVERSAL_ANALYTICS="Universal Analytics" HELIX_ULTIMATE_GOOGLE_ANALYTICS_GOOGLE_SITE_TAGS="Global Site Tag" HELIX_ULTIMATE_SAVE_CHANGES="Save" HELIX_ULTIMATE_PURGE_CSS_TEXT="Purge CSS" HELIX_ULTIMATE_PURGE_CSS_DESC="Remove cache css and sass files from the system." HELIX_ULTIMATE_SELECT_ICON_LABEL="--Select Icon--" HELIX_ULTIMATE_ADD_NEW_MENU_ITEM="Add new Item" ; Advanced settings HELIX_ULTIMATE_FIELDSET_ADVANCED="Advanced" HELIX_ULTIMATE_GROUP_FONTS="Font Settings" HELIX_ULTIMATE_GROUP_COMPRESSION="Compression" HELIX_ULTIMATE_ENABLE_FONT_AWESOME="Enable Font Awesome" HELIX_ULTIMATE_ENABLE_FONT_AWESOME_DESC="You can enable/disable the Font Awesome icons to load your site." HELIX_ULTIMATE_GROUP_SCSS="SCSS" HELIX_ULTIMATE_GROUP_IMPORTEXPORT="Import & Export" HELIX_ULTIMATE_CSS_COMPRESS="Compress CSS Files" HELIX_ULTIMATE_CSS_COMPRESS_DESC="Enable this option to compress and combine all CSS files to increase website performance by reducing loading time. Note: In case of problems please disable this option" HELIX_ULTIMATE_JS_COMPRESS="Compress Javascript Files" HELIX_ULTIMATE_JS_COMPRESS_DESC="Enable this option to compress and combine all Javascript files to increase website performance by reducing loading time. Note: In case of problems please disable this option" HELIX_ULTIMATE_PURGE_CSS_TEXT=" Purge CSS" HELIX_ULTIMATE_PURGE_CSS_DESC="Remove cache css and sass files from the system." HELIX_ULTIMATE_EXCLUDE_JS="Exclude Javascript Files" HELIX_ULTIMATE_EXCLUDE_JS_DESC="Enter the names of Javascript files separated by a comma that you don't want to compress. e.g., jquery.min.js, main.js" HELIX_ULTIMATE_ENABLE_SCSS="Compile SCSS to CSS" HELIX_ULTIMATE_ENABLE_SCSS_DESC="Enable this option will compile all the SCSS files during each load of your website if the SCSS file has been changed or edited. Turn off this option if your site is in production mode." HELIX_ULTIMATE_SETTINGS_EXPORT="Export Settings" HELIX_ULTIMATE_SETTINGS_IMPORT="Import Settings" COM_FINDER_ADVANCED_TIPS="

Entering this and that into the search form will return results containing both "this" and "that".

Here are a few examples of how you can use the search feature:

Entering this not that into the search form will return results containing "this" and not "that".

Entering this or that into the search form will return results containing either "this" or "that".

Search results can also be filtered using a variety of criteria. Select one or more filters below to get started.

Entering "this and that" (with quotes) into the search form will return results containing the exact phrase "this and that".

" HELIX_ULTIMATE_HEADER_STICKY_OFFSET="Sticky Offset" HELIX_ULTIMATE_HEADER_STICKY_OFFSET_DESC="After which scroll offset the header being sticky." HELIX_ULTIMATE_BLOG_IMAGE_ALT_TEXT="Image Alt Text" HELIX_ULTIMATE_BLOG_IMAGE_ALT_TEXT_DESCRIPTION="This field isn't required. So, if you leave this field then alt text will get from title."PK!-ڜܠ(system/helixultimate/params/megamenu.xmlnu[
PK!,system/helixultimate/params/blog-options.xmlnu[
PK!-8system/helixultimate/overrides/plg_content_vote/vote.phpnu[system/helixultimate/overrides/com_tags/tags/default_items.phpnu[document->getWebAssetManager(); $wa->useScript('com_tags.tag-default'); } // Get the user object. $user = Factory::getUser(); // Check if user is allowed to add/edit based on tags permissions. $canEdit = $user->authorise('core.edit', 'com_tags'); $canCreate = $user->authorise('core.create', 'com_tags'); $canEditState = $user->authorise('core.edit.state', 'com_tags'); $columns = $this->params->get('tag_columns', 1); // Avoid division by 0 and negative columns. if ($columns < 1) { $columns = 1; } $bsspans = floor(12 / $columns); if ($bsspans < 1) { $bsspans = 1; } $bscolumns = min($columns, floor(12 / $bsspans)); $n = count($this->items); Factory::getDocument()->addScriptDeclaration(" var resetFilter = function() { document.getElementById('filter-search').value = ''; } "); ?>
params->get('filter_field') || $this->params->get('show_pagination_limit')) : ?>
params->get('filter_field')) : ?>
params->get('show_pagination_limit')) : ?>
pagination->getLimitBox(); ?>
items == false || $n === 0) : ?>

items as $i => $item) : ?>
  • access)) && in_array($item->access, $this->user->getAuthorisedViewLevels())) : ?>

    escape($item->title); ?>

    params->get('all_tags_show_tag_image') && !empty($item->images)) : ?> images); ?> image_intro)) : ?> float_intro) ? $this->params->get('float_intro') : $images->float_intro; ?>
    image_intro_caption) : ?> image_intro_caption) . '"'; ?> src="image_intro; ?>" alt="image_intro_alt); ?>">
    params->get('all_tags_show_tag_description', 1)) : ?> description, $this->params->get('all_tags_tag_maximum_characters')); ?> params->get('all_tags_show_tag_hits')) : ?> hits); ?>
items)) : ?> params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?> PK!R5!8system/helixultimate/overrides/com_tags/tags/default.phpnu[params->get('all_tags_description'); $descriptionImage = $this->params->get('all_tags_description_image'); ?>
params->get('show_page_heading')) : ?>

escape($this->params->get('page_heading')); ?>

params->get('all_tags_show_description_image') && !empty($descriptionImage)) : ?> params->get('all_tags_description_image_alt')) && empty($this->params->get('all_tags_description_image_alt_empty')) ? '' : 'alt="' . htmlspecialchars($this->params->get('all_tags_description_image_alt'), ENT_COMPAT, 'UTF-8') . '"'; ?>
>
loadTemplate('items'); ?>
PK!m& & 4system/helixultimate/overrides/com_tags/tag/list.phpnu[items); ?>
params->get('show_page_heading')) : ?>

escape($this->params->get('page_heading')); ?>

params->get('show_tag_title', 1)) : ?>

tags_title, '', 'com_tag.tag'); ?>

item) === 1 && ($this->params->get('tag_list_show_tag_image', 1) || $this->params->get('tag_list_show_tag_description', 1))) : ?>
item[0]->images); ?> params->get('tag_list_show_tag_image', 1) == 1 && !empty($images->image_fulltext)) : ?> params->get('tag_list_show_tag_description') == 1 && $this->item[0]->description) : ?> item[0]->description, '', 'com_tags.tag'); ?>
params->get('tag_list_show_tag_description', 1) || $this->params->get('show_description_image', 1)) : ?> params->get('show_description_image', 1) == 1 && $this->params->get('tag_list_image')) : ?> params->get('tag_list_description', '') > '') : ?> params->get('tag_list_description'), '', 'com_tags.tag'); ?> loadTemplate('items'); ?>
PK!k=system/helixultimate/overrides/com_tags/tag/default_items.phpnu[authorise('core.edit', 'com_tags'); $canCreate = $user->authorise('core.create', 'com_tags'); $canEditState = $user->authorise('core.edit.state', 'com_tags'); $items = $this->items; $n = count($this->items); Factory::getDocument()->addScriptDeclaration(" var resetFilter = function() { document.getElementById('filter-search').value = ''; } "); ?>
params->get('filter_field') || $this->params->get('show_pagination_limit')) : ?> params->get('filter_field')) : ?>
params->get('show_pagination_limit')) : ?>
pagination->getLimitBox(); ?>
items)) : ?>
    items as $i => $item) : ?> core_state == 0) : ?>
  • type_alias === 'com_users.category') || ($item->type_alias === 'com_banners.category')) : ?> escape($item->core_title); ?> escape($item->core_title); ?> event->afterDisplayTitle; ?> core_images); ?> params->get('tag_list_show_item_image', 1) == 1 && !empty($images->image_intro)) : ?> <?php echo htmlspecialchars($images->image_intro_alt); ?> params->get('tag_list_show_item_description', 1)) : ?> event->beforeDisplayContent; ?> core_body, $this->params->get('tag_list_item_maximum_characters')); ?> event->afterDisplayContent; ?>
PK!׃D D 7system/helixultimate/overrides/com_tags/tag/default.phpnu[item) === 1; ?>
params->get('show_page_heading')) : ?>

escape($this->params->get('page_heading')); ?>

params->get('show_tag_title', 1)) : ?>

tags_title, '', 'com_tag.tag'); ?>

item) === 1 && ($this->params->get('tag_list_show_tag_image', 1) || $this->params->get('tag_list_show_tag_description', 1))) : ?>
item[0]->images); ?> params->get('tag_list_show_tag_image', 1) == 1 && !empty($images->image_fulltext)) : ?> <?php echo htmlspecialchars($images->image_fulltext_alt); ?> params->get('tag_list_show_tag_description') == 1 && $this->item[0]->description) : ?> item[0]->description, '', 'com_tags.tag'); ?>
params->get('tag_list_show_tag_description', 1) || $this->params->get('show_description_image', 1)) : ?> params->get('show_description_image', 1) == 1 && $this->params->get('tag_list_image')) : ?> params->get('tag_list_description', '') > '') : ?> params->get('tag_list_description'), '', 'com_tags.tag'); ?> loadTemplate('items'); ?> params->def('show_pagination', 1) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?>
params->def('show_pagination_results', 1)) : ?>

pagination->getPagesCounter(); ?>

pagination->getPagesLinks(); ?>
PK!}:system/helixultimate/overrides/com_tags/tag/list_items.phpnu[items); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); Factory::getDocument()->addScriptDeclaration(" var resetFilter = function() { document.getElementById('filter-search').value = ''; } "); ?>
params->get('filter_field') || $this->params->get('show_pagination_limit')) : ?>
params->get('filter_field')) : ?>
params->get('show_pagination_limit')) : ?>
pagination->getLimitBox(); ?>
items === false || $n === 0) : ?>

params->get('show_headings')) : ?> params->get('tag_list_show_date')) : ?> items as $i => $item) : ?> items[$i]->core_state == 0) : ?> params->get('tag_list_show_date')) : ?>
params->get('show_headings')) echo "headers=\"categorylist_header_title\""; ?> class="list-title"> escape($item->core_title); ?> core_state == 0) : ?> displayDate, $this->escape($this->params->get('date_format', Text::_('DATE_FORMAT_LC3'))) ); ?>
items)) : ?> params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?> PK!>3=system/helixultimate/overrides/mod_menu/default_component.phpnu[get('hu_offcanvas', 0, 'INT') === 1; $maxLevel = $params->get('endLevel', 0, 'INT'); $showToggler = $maxLevel === 0 || $item->level < $maxLevel; if ($item->anchor_title) { $attributes['title'] = $item->anchor_title; } if ($item->anchor_css) { $attributes['class'] = $item->anchor_css; } if ($item->anchor_rel) { $attributes['rel'] = $item->anchor_rel; } $linktype = $item->title; if ($item->menu_image) { if ($item->menu_image_css) { $image_attributes['class'] = $item->menu_image_css; $linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes); } else { $linktype = HTMLHelper::_('image', $item->menu_image, $item->title); } if ($item->getParams()->get('menu_text', 1)) { $linktype .= '' . $item->title . ''; } } if ($item->parent && $showToggler) { $linktype .= ''; } if ($item->browserNav == 1) { $attributes['target'] = '_blank'; } elseif ($item->browserNav == 2) { $options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes'; $attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;"; } echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes); PK!q3system/helixultimate/overrides/mod_menu/default.phpnu[get('tag_id', '')) { $id = ' id="' . $tagId . '"'; } // The menu class is deprecated. Use nav instead ?> PK!@/ۀ$$;system/helixultimate/overrides/mod_menu/default_heading.phpnu[anchor_title ? ' title="' . $item->anchor_title . '"' : ''; $anchor_css = $item->anchor_css ?: ''; $rel = $item->anchor_rel ? ' rel="' . $item->anchor_rel . '" ' : ''; $linktype = $item->title; $isOffcanvasMenu = $params->get('hu_offcanvas', 0, 'INT') === 1; $maxLevel = $params->get('endLevel', 0, 'INT'); $showToggler = $maxLevel === 0 || $item->level < $maxLevel; if ($item->menu_image) { if ($item->menu_image_css) { $image_attributes['class'] = $item->menu_image_css; $linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes); } else { $linktype = HTMLHelper::_('image', $item->menu_image, $item->title); } if ($item->getParams->get('menu_text', 1)) { $linktype .= '' . $item->title . ''; } } if ($item->parent && $showToggler) { $linktype .= ''; } ?> >PK!w=system/helixultimate/overrides/mod_menu/default_separator.phpnu[anchor_title ? ' title="' . $item->anchor_title . '"' : ''; $anchor_css = $item->anchor_css ?: ''; $rel = $item->anchor_rel ? ' rel="' . $item->anchor_rel . '" ' : ''; $isOffcanvasMenu = $params->get('hu_offcanvas', 0, 'INT') === 1; $maxLevel = $params->get('endLevel', 0, 'INT'); $showToggler = $maxLevel === 0 || $item->level < $maxLevel; $linktype = $item->title; if ($item->menu_image) { if ($item->menu_image_css) { $image_attributes['class'] = $item->menu_image_css; $linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes); } else { $linktype = HTMLHelper::_('image', $item->menu_image, $item->title); } $linktype .= '' . $item->title . ''; } if ($item->parent && $showToggler) { $linktype .= ''; } ?> > PK!sa7system/helixultimate/overrides/mod_menu/default_url.phpnu[get('hu_offcanvas', 0, 'INT') === 1; $maxLevel = $params->get('endLevel', 0, 'INT'); $showToggler = $maxLevel === 0 || $item->level < $maxLevel; if ($item->anchor_title) { $attributes['title'] = $item->anchor_title; } if ($item->anchor_css) { $attributes['class'] = $item->anchor_css; } if ($item->anchor_rel) { $attributes['rel'] = $item->anchor_rel; } $linktype = $item->title; if ($item->menu_image) { if ($item->menu_image_css) { $image_attributes['class'] = $item->menu_image_css; $linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes); } else { $linktype = HTMLHelper::_('image', $item->menu_image, $item->title); } if ($item->getParams()->get('menu_text', 1)) { $linktype .= '' . $item->title . ''; } } if ($item->parent && $showToggler) { $linktype .= ''; } if ($item->browserNav == 1) { $attributes['target'] = '_blank'; $attributes['rel'] = 'noopener noreferrer'; } elseif ($item->browserNav == 2) { $options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open'); $attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;"; } echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes); PK!ʒuܑ*system/helixultimate/overrides/modules.phpnu[get('module_tag', 'div'), ENT_QUOTES, 'UTF-8'); $bootstrapSize = (int) $params->get('bootstrap_size', 0); $moduleClass = $bootstrapSize !== 0 ? ' span' . $bootstrapSize : ''; $headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_QUOTES, 'UTF-8'); $headerClass = htmlspecialchars($params->get('header_class', 'sp-module-title'), ENT_COMPAT, 'UTF-8'); if ($module->content) { echo '<' . $moduleTag . ' class="sp-module ' . htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8') . $moduleClass . '">'; if ($module->showtitle) { echo '<' . $headerTag . ' class="' . $headerClass . '">' . $module->title . ''; } echo '
'; echo $module->content; echo '
'; echo ''; } }PK!F5system/helixultimate/overrides/mod_search/default.phpnu[ PK! {w<system/helixultimate/overrides/com_finder/search/default.phpnu[ 'auto', 'relative' => true)); HTMLHelper::_('stylesheet', 'vendor/awesomplete/awesomplete.css', array('version' => 'auto', 'relative' => true)); Text::script('MOD_FINDER_SEARCH_VALUE', true); HTMLHelper::_('script', 'com_finder/finder.js', array('version' => 'auto', 'relative' => true)); } else { $this->document->getWebAssetManager() ->useStyle('com_finder.finder') ->useScript('com_finder.finder'); } ?>
params->get('show_page_heading')) : ?>

escape($this->params->get('page_heading'))) : ?> escape($this->params->get('page_heading')); ?> escape($this->params->get('page_title')); ?>

params->get('show_search_form', 1)) : ?>
loadTemplate('form'); ?>
query->search === true) : ?>
loadTemplate('results'); ?>
PK!3='ffDsystem/helixultimate/overrides/com_finder/search/default_results.phpnu[ suggested && $this->params->get('show_suggested_query', 1)) || ($this->explained && $this->params->get('show_explained_query', 1))) : ?>
suggested && $this->params->get('show_suggested_query', 1)) : ?> query->toUri()); ?> setVar('q', $this->suggested); ?> toString(array('path', 'query'))); ?> ' . $this->escape($this->suggested) . ''; ?> explained && $this->params->get('show_explained_query', 1)) : ?> explained; ?>
total === 0) || ($this->total === null)) : ?>

getLanguageFilter() ? '_MULTILANG' : ''; ?>

escape($this->query->input)); ?>

query->highlight) && $this->params->get('highlight_terms', 1)) : ?> query->highlight); } else { $this->document->getWebAssetManager()->useScript('highlight'); $this->document->addScriptOptions( 'highlight', [[ 'class' => 'js-highlight', 'highLight' => $this->query->highlight, ]] ); } ?>
    baseUrl = Uri::getInstance()->toString(array('scheme', 'host', 'port')); ?> results as $result) : ?> result = &$result; ?> getLayoutFile($this->result->layout); ?> loadTemplate($layout); ?>

pagination->getPagesLinks(); ?>
pagination->limitstart + 1; ?> pagination->total; ?> pagination->limit * $this->pagination->pagesCurrent; ?> $total ? $total : $limit); ?>
PK!M0``Asystem/helixultimate/overrides/com_finder/search/default_form.phpnu[params->get('show_advanced', 1) || $this->params->get('show_autosuggest', 1)) { HTMLHelper::_('jquery.framework'); $script = " jQuery(function() {"; if ($this->params->get('show_advanced', 1)) { /* * This segment of code disables select boxes that have no value when the * form is submitted so that the URL doesn't get blown up with null values. */ $script .= " jQuery('#finder-search').on('submit', function(e){ e.stopPropagation(); // Disable select boxes with no value selected. jQuery('#advancedSearch').find('select').each(function(index, el) { var el = jQuery(el); if(!el.val()){ el.attr('disabled', 'disabled'); } }); });"; } /* * This segment of code sets up the autocompleter. */ if ($this->params->get('show_autosuggest', 1)) { HTMLHelper::_('script', 'jui/jquery.autocomplete.min.js', array('version' => 'auto', 'relative' => true)); $script .= " var suggest = jQuery('#q').autocomplete({ serviceUrl: '" . Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component') . "', paramName: 'q', minChars: 1, maxHeight: 400, width: 300, zIndex: 9999, deferRequestBy: 500 });"; } $script .= " });"; Factory::getDocument()->addScriptDeclaration($script); } } else { HTMLHelper::_('jquery.framework'); $script = " jQuery(function() {"; $script .= " jQuery('.ads').on('click', function(e){ if(jQuery('#advancedSearch').hasClass('hide')) { jQuery('#advancedSearch').removeClass('hide'); jQuery('#advancedSearch').slideDown(300); } else { jQuery('#advancedSearch').addClass('hide'); jQuery('#advancedSearch').slideUp(300); } });"; $script .= " });"; Factory::getDocument()->addScriptDeclaration($script); if ($this->params->get('show_autosuggest', 1)) { $this->document->getWebAssetManager()->usePreset('awesomplete'); $this->document->addScriptOptions('finder-search', array('url' => Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component'))); } } ?> PK!VVCsystem/helixultimate/overrides/com_finder/search/default_result.phpnu[result->mime) ? 'mime-' . $this->result->mime : null; $show_description = $this->params->get('show_description', 1); if ($show_description) { // Calculate number of characters to display around the result $term_length = StringHelper::strlen($this->query->input); $desc_length = $this->params->get('description_length', 255); $pad_length = $term_length < $desc_length ? (int) floor(($desc_length - $term_length) / 2) : 0; // Find the position of the search term $pos = $term_length ? StringHelper::strpos(StringHelper::strtolower($this->result->description), StringHelper::strtolower($this->query->input)) : false; // Find a potential start point $start = ($pos && $pos > $pad_length) ? $pos - $pad_length : 0; // Find a space between $start and $pos, start right after it. $space = StringHelper::strpos($this->result->description, ' ', $start > 0 ? $start - 1 : 0); $start = ($space && $space < $pos) ? $space + 1 : $start; $description = HTMLHelper::_('string.truncate', StringHelper::substr($this->result->description, $start), $desc_length, true); } $route = $this->result->route; // Get the route with highlighting information. if (!empty($this->query->highlight) && empty($this->result->mime) && $this->params->get('highlight_terms', 1) && PluginHelper::isEnabled('system', 'highlight')) { $route .= '&highlight=' . base64_encode(json_encode($this->query->highlight)); } ?>
  • result->title; ?>

  • PK!@~ <system/helixultimate/overrides/layouts/joomla/modal/main.phpnu[= 4) { return; } // Load bootstrap-tooltip-extended plugin for additional tooltip positions in modal HTMLHelper::_('bootstrap.tooltipExtended'); extract($displayData); /** * Layout variables * ------------------ * @param string $selector Unique DOM identifier for the modal. CSS id without # * @param array $params Modal parameters. Default supported parameters: * - title string The modal title * - backdrop mixed A boolean select if a modal-backdrop element should be included (default = true) * The string 'static' includes a backdrop which doesn't close the modal on click. * - keyboard boolean Closes the modal when escape key is pressed (default = true) * - closeButton boolean Display modal close button (default = true) * - animation boolean Fade in from the top of the page (default = true) * - url string URL of a resource to be inserted as an
    get('comment_facebook_app_id') != '' ) { $doc = Factory::getDocument(); if(!defined('HELIX_ULTIMATE_COMMENTS_FACEBOOK_COUNT')) { $doc->addScript( 'https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.11&appId=' . $displayData['params']->get('comment_facebook_app_id') . '&autoLogAppEvents=1' ); define('HELIX_ULTIMATE_COMMENTS_FACEBOOK_COUNT', 1); } ?> () get('comment_disqus_subdomain') != '' ) { $doc = Factory::getDocument(); if(!defined('HELIX_ULTIMATE_COMMENTS_DISQUS_COUNT')) { ob_start(); $devmode = $displayData['params']->get('comment_disqus_devmode'); if ($devmode) { echo 'var disqus_developer = 1;'; } ?> var disqus_shortname = 'get("comment_disqus_subdomain"); ?>'; (function() { var d = document, s = d.createElement('script'); s.src = 'https://' + disqus_shortname + '.disqus.com/count.js'; s.setAttribute('data-timestamp', +new Date()); (d.head || d.body).appendChild(s); })(); addScriptdeclaration( $output ); define('HELIX_ULTIMATE_COMMENTS_DISQUS_COUNT', 1); } ?> get('comment_intensedebate_acc') != '' ) : ?> PK![Psystem/helixultimate/overrides/layouts/joomla/content/blog/comments/comments.phpnu[params; if( $params->get('comment') != 'disabled' ) { $comment_categories = $params->get('comment_categories'); if(is_array($comment_categories) && count($comment_categories)) { if(in_array($displayData->catid, $comment_categories)) { $url = Route::_(\ContentHelperRoute::getArticleRoute($displayData->id . ':' . $displayData->alias, $displayData->catid, $displayData->language)); $root = Uri::base(); $root = new Uri($root); $url = $root->getScheme() . '://' . $root->getHost() . $url; echo '
    '; echo LayoutHelper::render( 'joomla.content.blog.comments.comments.' . $params->get('comment'), array( 'item'=>$displayData, 'params'=>$params, 'url'=>$url ) ); echo '
    '; } } } PK!uaGMsystem/helixultimate/overrides/layouts/joomla/content/blog/comments/count.phpnu[params; if( ( $params->get('comment') != 'disabled' ) && ( $params->get('comments_count') ) ) { $comment_categories = $params->get('comment_categories'); if(is_array($comment_categories) && count($comment_categories)) { if(in_array($displayData['item']->catid, $comment_categories)) { $url = Route::_(ContentHelperRoute::getArticleRoute($displayData['item']->id . ':' . $displayData['item']->alias, $displayData['item']->catid, $displayData['item']->language)); $root = Uri::base(); $root = new Uri($root); $url = $root->getScheme() . '://' . $root->getHost() . $url; ?> get('comment'), array( 'item' => $displayData, 'params' => $params, 'url' => $url)); ?> get('comment_facebook_width') == 100 ) ? '100%' : (int) $displayData['params']->get('comment_facebook_width'); ?> get('comment_facebook_app_id') != '' ) : ?>
    PK!*~Wsystem/helixultimate/overrides/layouts/joomla/content/blog/comments/comments/disqus.phpnu[get('comment_disqus_subdomain') != '' ) { ?>
    get('comment_intensedebate_acc') != '' ) : ?> PK!2IuuHsystem/helixultimate/overrides/layouts/joomla/editors/buttons/button.phpnu[ * Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined ('JPATH_BASE') or die(); $button = $displayData; if ($button->get('name')) : $class = 'btn btn-secondary'; $class .= ($button->get('class')) ? ' ' . $button->get('class') : null; $class .= ($button->get('modal')) ? ' modal-button' : null; $target = '#' . $button->get('text', ''); $onclick = ($button->get('onclick')) ? ' onclick="' . $button->get('onclick') . '"' : ''; $title = ($button->get('title')) ? $button->get('title') : $button->get('text'); $href = ' href="' . $target . '"'; $toggle = ''; if ($button->get('modal', 0)) { $toggle = ' data-bs-toggle="modal"'; $href = ' href="' . $target . 'Modal"'; } ?> title="" > get('text'); ?> PK!GAAGsystem/helixultimate/overrides/layouts/joomla/editors/buttons/modal.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use HelixUltimate\Framework\Platform\Helper; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; $button = $displayData; if (!$button->get('modal')) { return; } $class = ($button->get('class')) ? $button->get('class') : null; $class .= ($button->get('modal')) ? ' modal-button' : null; $href = '#' . str_replace(' ', '', $button->get('text')) . 'Modal'; $link = ($button->get('link')) ? Uri::base() . $button->get('link') : null; $onclick = ($button->get('onclick')) ? ' onclick="' . $button->get('onclick') . '"' : ''; $title = ($button->get('title')) ? $button->get('title') : $button->get('text'); $options = is_array($button->get('options')) ? $button->get('options') : array(); $confirm = ''; if (is_array($button->get('options')) && isset($options['confirmText']) && isset($options['confirmCallback'])) { $confirm = ''; } if (null !== $button->get('id')) { $id = str_replace(' ', '', $button->get('id')); } else { $id = str_replace(' ', '', $button->get('text')) . 'Modal'; } // Create the modal echo HTMLHelper::_( 'bootstrap.renderModal', $id, array( 'url' => $link, 'title' => $title, 'height' => array_key_exists('height', $options) ? $options['height'] : '400px', 'width' => array_key_exists('width', $options) ? $options['width'] : '800px', 'bodyHeight' => array_key_exists('bodyHeight', $options) ? $options['bodyHeight'] : '70', 'modalWidth' => array_key_exists('modalWidth', $options) ? $options['modalWidth'] : '80', 'footer' => $confirm . '' ) ); PK!gbAsystem/helixultimate/overrides/layouts/joomla/editors/buttons.phpnu[ PK!:> : : Csystem/helixultimate/overrides/layouts/joomla/form/field/hidden.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. */ // Initialize some field attributes. $class = !empty($class) ? ' class="' . $class . '"' : ''; $disabled = $disabled ? ' disabled' : ''; $onchange = $onchange ? ' onchange="' . $onchange . '"' : ''; ?> > PK!LGٸBsystem/helixultimate/overrides/layouts/joomla/form/field/media.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var string $accept File types that are accepted. * @var integer $maxLength The maximum length that the field shall accept. */ // Including fallback code for HTML5 non supported browsers. HTMLHelper::_('jquery.framework'); HTMLHelper::_('script', 'system/html5fallback.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); $autocomplete = !$autocomplete ? ' autocomplete="off"' : ' autocomplete="' . $autocomplete . '"'; $autocomplete = $autocomplete == ' autocomplete="on"' ? '' : $autocomplete; $attributes = array( !empty($size) ? 'size="' . $size . '"' : '', $disabled ? 'disabled' : '', $readonly ? 'readonly' : '', strlen(Helper::CheckNull($hint)) ? 'placeholder="' . htmlspecialchars(Helper::CheckNull($hint), ENT_COMPAT, 'UTF-8') . '"' : '', $autocomplete, $autofocus ? ' autofocus' : '', $spellcheck ? '' : 'spellcheck="false"', $onchange ? ' onchange="' . $onchange . '"' : '', !empty($maxLength) ? $maxLength : '', $required ? 'required aria-required="true"' : '', ); ?> id="" value="" > PK!  Esystem/helixultimate/overrides/layouts/joomla/form/field/textarea.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var string $accept File types that are accepted. */ // Initialize some field attributes. $autocomplete = !$autocomplete ? 'autocomplete="off"' : 'autocomplete="' . $autocomplete . '"'; $autocomplete = $autocomplete == 'autocomplete="on"' ? '' : $autocomplete; $attributes = array( $columns ?: '', $rows ?: '', !empty($class) ? 'class="form-control ' . $class . '"' : 'class="form-control"', strlen(Helper::CheckNull($hint)) ? 'placeholder="' . htmlspecialchars(Helper::CheckNull($hint), ENT_COMPAT, 'UTF-8') . '"' : '', $disabled ? 'disabled' : '', $readonly ? 'readonly' : '', $onchange ? 'onchange="' . $onchange . '"' : '', $onclick ? 'onclick="' . $onclick . '"' : '', $required ? 'required aria-required="true"' : '', $autocomplete, $autofocus ? 'autofocus' : '', $spellcheck ? '' : 'spellcheck="false"', $maxlength ? $maxlength: '' ); ?> PK!ya @system/helixultimate/overrides/layouts/joomla/form/field/url.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var string $accept File types that are accepted. */ $autocomplete = !$autocomplete ? ' autocomplete="off"' : ' autocomplete="' . $autocomplete . '"'; $autocomplete = $autocomplete === ' autocomplete="on"' ? '' : $autocomplete; $attributes = array( !empty($size) ? ' size="' . $size . '"' : '', $disabled ? ' disabled' : '', $readonly ? ' readonly' : '', strlen(Helper::CheckNull($hint)) ? ' placeholder="' . htmlspecialchars(Helper::CheckNull($hint), ENT_COMPAT, 'UTF-8') . '"' : '', $autocomplete, $autofocus ? ' autofocus' : '', $spellcheck ? '' : ' spellcheck="false"', $onchange ? ' onchange="' . $onchange . '"' : '', !empty($maxLength) ? $maxLength : '', $required ? ' required aria-required="true"' : '', ); ?> name="" id="" value="" > PK!},)Ksystem/helixultimate/overrides/layouts/joomla/form/field/color/advanced.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellchec Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $checked Is this field checked? * @var array $position Is this field checked? * @var array $control Is this field checked? */ if ($validate !== 'color' && in_array($format, array('rgb', 'rgba'), true)) { $alpha = ($format === 'rgba'); $placeholder = $alpha ? 'rgba(0, 0, 0, 0.5)' : 'rgb(0, 0, 0)'; } else { $placeholder = '#rrggbb'; } $inputclass = ($keywords && ! in_array($format, array('rgb', 'rgba'), true)) ? ' keywords' : ' ' . $format; $class = ' class="form-control ' . trim('minicolors ' . $class) . ($validate === 'color' ? 'form-control ' : $inputclass) . '"'; $control = $control ? ' data-control="' . $control . '"' : ''; $format = $format ? ' data-format="' . $format . '"' : ''; $keywords = $keywords ? ' data-keywords="' . $keywords . '"' : ''; $validate = $validate ? ' data-validate="' . $validate . '"' : ''; $disabled = $disabled ? ' disabled' : ''; $readonly = $readonly ? ' readonly' : ''; $hint = strlen($hint) ? ' placeholder="' . htmlspecialchars($hint, ENT_COMPAT, 'UTF-8') . '"' : ' placeholder="' . $placeholder . '"'; $autocomplete = ! $autocomplete ? ' autocomplete="off"' : ''; // Force LTR input value in RTL, due to display issues with rgba/hex colors $direction = $lang->isRtl() ? ' dir="ltr" style="text-align:right"' : ''; HTMLHelper::_('jquery.framework'); HTMLHelper::_('script', 'vendor/minicolors/jquery.minicolors.min.js', array('version' => 'auto', 'relative' => true)); HTMLHelper::_('stylesheet', 'vendor/minicolors/jquery.minicolors.css', array('version' => 'auto', 'relative' => true)); HTMLHelper::_('script', 'system/fields/color-field-adv-init.min.js', array('version' => 'auto', 'relative' => true)); ?> > PK!PhzC C Isystem/helixultimate/overrides/layouts/joomla/form/field/color/simple.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellchec Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $checked Is this field checked? * @var array $position Is this field checked? * @var array $control Is this field checked? */ $class = ' class="form-select ' . trim('simplecolors chzn-done ' . $class) . '"'; $disabled = $disabled ? ' disabled' : ''; $readonly = $readonly ? ' readonly' : ''; // Include jQuery HTMLHelper::_('jquery.framework'); HTMLHelper::_('script', 'system/fields/simplecolors.min.js', array('version' => 'auto', 'relative' => true)); HTMLHelper::_('stylesheet', 'system/simplecolors.css', array('version' => 'auto', 'relative' => true)); HTMLHelper::_('script', 'system/fields/color-field-init.min.js', array('version' => 'auto', 'relative' => true)); ?> PK!$``Gsystem/helixultimate/overrides/layouts/joomla/form/field/radiobasic.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $options Options available for this field. */ // Including fallback code for HTML5 non supported browsers. HTMLHelper::_('jquery.framework'); /** * The format of the input tag to be filled in using sprintf. * %1 - id * %2 - name * %3 - value * %4 = any other attributes */ $format = ''; $alt = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $name); ?>
    > $option) : ?> value == $value) ? 'checked="checked"' : ''; $optionClass = !empty($option->class) ? 'class="' . $option->class . '"' : ''; $disabled = !empty($option->disable) || ($disabled && !$checked) ? 'disabled' : ''; // Initialize some JavaScript option attributes. $onclick = !empty($option->onclick) ? 'onclick="' . $option->onclick . '"' : ''; $onchange = !empty($option->onchange) ? 'onchange="' . $option->onchange . '"' : ''; $oid = $id . $i; $ovalue = htmlspecialchars(Helper::CheckNull($option->value), ENT_COMPAT, 'UTF-8'); $attributes = array_filter(array($checked, $optionClass, $disabled, $onchange, $onclick)); ?>
    PK!VcAsystem/helixultimate/overrides/layouts/joomla/form/field/text.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var string $accept File types that are accepted. */ $list = ''; if ($options) { $list = 'list="' . $id . '_datalist"'; } $autocomplete = !$autocomplete ? ' autocomplete="off"' : ' autocomplete="' . $autocomplete . '"'; $autocomplete = $autocomplete === ' autocomplete="on"' ? '' : $autocomplete; $attributes = array( !empty($class) ? 'class="form-control ' . $class . '"' : 'class="form-control"', !empty($size) ? 'size="' . $size . '"' : '', !empty($description) ? 'title="' . $description . '"' : '', $disabled ? 'disabled' : '', $readonly ? 'readonly' : '', $list, strlen(Helper::CheckNull($hint)) ? 'placeholder="' . htmlspecialchars(Helper::CheckNull($hint), ENT_COMPAT, 'UTF-8') . '"' : '', $onchange ? ' onchange="' . $onchange . '"' : '', !empty($maxLength) ? $maxLength : '', $required ? 'required aria-required="true"' : '', $autocomplete, $autofocus ? ' autofocus' : '', $spellcheck ? '' : 'spellcheck="false"', !empty($inputmode) ? 'inputmode="' . $inputmode . '"' : '', !empty($pattern) ? 'pattern="' . $pattern . '"' : '', // @TODO add a proper string here!!! !empty($validationtext) ? 'data-validation-text="' . $validationtext . '"' : '', ); if(isset($addonBefore) && $addonBefore) { $addonBeforeHtml = '' . $addonBefore . ''; } if(isset($addonBefore) && $addonBefore) { $addonAfterHtml = '' . $addonAfter . ''; } ?>
    >
    value) : ?> PK!Gsystem/helixultimate/overrides/layouts/joomla/form/field/checkboxes.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. */ /** * The format of the input tag to be filled in using sprintf. * %1 - id * %2 - name * %3 - value * %4 = any other attributes */ $format = ''; // The alt option for JText::alt $alt = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $name); ?>
    > $option) : ?> value, $checkedOptions, true) ? 'checked' : ''; // In case there is no stored value, use the option's default state. $checked = (!$hasValue && $option->checked) ? 'checked' : $checked; $optionClass = !empty($option->class) ? 'class="form-check-input ' . $option->class . '"' : ' class="form-check-input"'; $optionDisabled = !empty($option->disable) || $disabled ? 'disabled' : ''; // Initialize some JavaScript option attributes. $onclick = !empty($option->onclick) ? 'onclick="' . $option->onclick . '"' : ''; $onchange = !empty($option->onchange) ? 'onchange="' . $option->onchange . '"' : ''; $oid = $id . $i; $value = htmlspecialchars($option->value, ENT_COMPAT, 'UTF-8'); $attributes = array_filter(array($checked, $optionClass, $optionDisabled, $onchange, $onclick)); ?>
    PK!g, Csystem/helixultimate/overrides/layouts/joomla/form/field/number.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var array $spellcheck Options available for this field. * @var string $accept File types that are accepted. */ $autocomplete = !$autocomplete ? ' autocomplete="off"' : ' autocomplete="' . $autocomplete . '"'; $autocomplete = $autocomplete == ' autocomplete="on"' ? '' : $autocomplete; $attributes = array( !empty($class) ? 'class="form-control ' . $class . '"' : 'class="form-control"', !empty($size) ? 'size="' . $size . '"' : '', $disabled ? 'disabled' : '', $readonly ? 'readonly' : '', strlen(Helper::CheckNull($hint)) ? 'placeholder="' . htmlspecialchars(Helper::CheckNull($hint), ENT_COMPAT, 'UTF-8') . '"' : '', !empty($onchange) ? 'onchange="' . $onchange . '"' : '', isset($max) ? 'max="' . $max . '"' : '', !empty($step) ? 'step="' . $step . '"' : '', isset($min) ? 'min="' . $min . '"' : '', $required ? 'required aria-required="true"' : '', $autocomplete, $autofocus ? 'autofocus' : '' ); if (is_numeric($value)) { $value = (float) $value; } else { $value = ''; $value = ($required && isset($min)) ? $min : $value; } ?> > PK!Ćc c Esystem/helixultimate/overrides/layouts/joomla/form/field/password.phpnu[ 'auto', 'relative' => true)); $class = 'js-password-strength ' . $class; if ($forcePassword) { $class = $class . ' meteredPassword'; } } HTMLHelper::_('script', 'system/fields/passwordview.min.js', array('version' => 'auto', 'relative' => true)); Text::script('JFIELD_PASSWORD_INDICATE_INCOMPLETE'); Text::script('JFIELD_PASSWORD_INDICATE_COMPLETE'); Text::script('JSHOW'); Text::script('JHIDE'); $attributes = array( strlen(Helper::CheckNull($hint)) ? 'placeholder="' . htmlspecialchars(Helper::CheckNull($hint), ENT_COMPAT, 'UTF-8') . '"' : '', !empty($autocomplete) ? 'autocomplete="off"' : '', !empty($class) ? 'class="form-control ' . $class . '"' : 'class="form-control"', $readonly ? 'readonly' : '', $disabled ? 'disabled' : '', !empty($size) ? 'size="' . $size . '"' : '', !empty($maxLength) ? 'maxlength="' . $maxLength . '"' : '', $required ? 'required aria-required="true"' : '', $autofocus ? 'autofocus' : '', !empty($minLength) ? 'data-min-length="' . $minLength . '"' : '', !empty($minIntegers) ? 'data-min-integers="' . $minIntegers . '"' : '', !empty($minSymbols) ? 'data-min-symbols="' . $minSymbols . '"' : '', !empty($minUppercase) ? 'data-min-uppercase="' . $minUppercase . '"' : '', !empty($minLowercase) ? 'data-min-lowercase="' . $minLowercase . '"' : '', !empty($forcePassword) ? 'data-min-force="' . $forcePassword . '"' : '', ); ?>
    > = 4) :?>
    PK!;Bsystem/helixultimate/overrides/layouts/joomla/form/field/radio.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $options Options available for this field. */ // Including fallback code for HTML5 non supported browsers. HTMLHelper::_('jquery.framework'); HTMLHelper::_('script', 'system/html5fallback.js', array('version' => 'auto', 'relative' => true)); /** * The format of the input tag to be filled in using sprintf. * %1 - id * %2 - name * %3 - value * %4 = any other attributes */ $format = ''; $alt = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $name); ?>
    > $option) : ?> value === $value) ? 'checked="checked"' : ''; $optionClass = !empty($option->class) ? 'class="form-check-input ' . $option->class . '"' : 'class="form-check-input"'; $labelClass = !empty($option->class) ? 'class="form-check-label ' . $option->class . '"' : 'class="form-check-label btn"'; $disabled = !empty($option->disable) || ($disabled && !$checked) ? 'disabled' : ''; // Initialize some JavaScript option attributes. $onclick = !empty($option->onclick) ? 'onclick="' . $option->onclick . '"' : ''; $onchange = !empty($option->onchange) ? 'onchange="' . $option->onchange . '"' : ''; $oid = $id . $i; $ovalue = htmlspecialchars($option->value, ENT_COMPAT, 'UTF-8'); $attributes = array_filter(array($checked, $optionClass, $disabled, $onchange, $onclick)); ?>
    PK!ے Bsystem/helixultimate/overrides/layouts/joomla/form/field/range.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var string $accept File types that are accepted. */ // Initialize some field attributes. $attributes = array( $class ? 'class="form-control ' . $class . '"' : 'class="form-control"', $disabled ? 'disabled' : '', $readonly ? 'readonly' : '', !empty($onchange) ? 'onchange="' . $onchange . '"' : '', !empty($max) ? 'max="' . $max . '"' : '', !empty($step) ? 'step="' . $step . '"' : '', !empty($min) ? 'min="' . $min . '"' : '', $autofocus ? 'autofocus' : '', ); $value = (float) $value; $value = empty($value) ? $min : $value; ?> > PK!8Esystem/helixultimate/overrides/layouts/joomla/form/field/calendar.phpnu[format('Y-m-d H:i:s'); } $readonly = isset($attributes['readonly']) && $attributes['readonly'] == 'readonly'; $disabled = isset($attributes['disabled']) && $attributes['disabled'] == 'disabled'; if (is_array($attributes)) { $attributes = ArrayHelper::toString($attributes); } $cssFileExt = ($direction === 'rtl') ? '-rtl.css' : '.css'; $localesPath = $localesPath ?? ''; $helperPath = $helperPath ?? ''; if (JVERSION < 4) { // The static assets for the calendar HTMLHelper::_('script', Helper::CheckNull($localesPath), false, true, false, false, true); HTMLHelper::_('script', Helper::CheckNull($helperPath), false, true, false, false, true); HTMLHelper::_('script', 'system/fields/calendar.min.js', false, true, false, false, true); HTMLHelper::_('stylesheet', 'system/fields/calendar' . Helper::CheckNull($cssFileExt), array(), true); } // Redefine locale/helper assets to use correct path, and load calendar assets if (JVERSION >= 4) { $document->getWebAssetManager() ->registerAndUseScript('field.calendar.locale', $localesPath, [], ['defer' => true]) ->registerAndUseScript('field.calendar.helper', $helperPath, [], ['defer' => true]) ->useStyle('field.calendar' . ($direction === 'rtl' ? '-rtl' : '')) ->useScript('field.calendar'); } ?>
    data-alt-value="" autocomplete="off">
    PK!Ѽ[ [ Bsystem/helixultimate/overrides/layouts/joomla/form/field/email.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var array $spellcheck Options available for this field. * @var string $accept File types that are accepted. */ $autocomplete = !$autocomplete ? 'autocomplete="off"' : 'autocomplete="' . $autocomplete . '"'; $autocomplete = $autocomplete == 'autocomplete="on"' ? '' : $autocomplete; $attributes = array( $spellcheck ? '' : 'spellcheck="false"', !empty($size) ? 'size="' . $size . '"' : '', $disabled ? 'disabled' : '', $readonly ? 'readonly' : '', $onchange ? 'onchange="' . $onchange . '"' : '', $autocomplete, $multiple ? 'multiple' : '', !empty($maxLength) ? 'maxlength="' . $maxLength . '"' : '', strlen($hint) ? 'placeholder="' . htmlspecialchars($hint, ENT_COMPAT, 'UTF-8') . '"' : '', $required ? 'required aria-required="true"' : '', $autofocus ? 'autofocus' : '', ); ?> id="" value="" > PK!x* Hsystem/helixultimate/overrides/layouts/joomla/form/field/moduleorder.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var array $spellcheck Options available for this field. * @var string $accept File types that are accepted. */ $attr = ''; // Initialize some field attributes. $attr .= !empty($class) ? ' class="module-ajax-ordering ' . $class . '"' : 'class="module-ajax-ordering"'; $attr .= $disabled ? ' disabled' : ''; $attr .= !empty($size) ? ' size="' . $size . '"' : ''; // Initialize JavaScript field attributes. $attr .= !empty($onchange) ? ' onchange="' . $onchange . '"' : ''; HTMLHelper::_('script', 'system/fields/moduleorder.js', array('version' => 'auto', 'relative' => true)); ?>
    data-url="" data-element="" data-ordering="" data-position-element="" data-client-id="" data-name="" data-attr="">
    PK!Fc\ Ksystem/helixultimate/overrides/layouts/joomla/form/field/contenthistory.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * * @var string $link The link for the content history page * @var string $label The label text */ extract($displayData); ?>
    PK!I Bsystem/helixultimate/overrides/layouts/joomla/form/field/meter.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var string $accept File types that are accepted. * @var string $animated Is it animated. * @var string $active Is it active. * @var string $max The maximum value. */ // Initialize some field attributes. $class = 'progress-bar ' . $class; $class .= $animated ? ' progress-bar-striped progress-bar-animated' : ''; $class .= $active ? ' active' : ''; $class = 'class="' . $class . '"'; $value = (float) $value; $value = $value < $min ? $min : $value; $value = $value > $max ? $max : $value; $data = ''; $data .= 'aria-valuemax="' . $max . '"'; $data .= ' aria-valuemin="' . $min . '"'; $data .= ' aria-valuenow="' . $value . '"'; $attributes = array( $class, !empty($width) ? ' style="width:' . $width . ';"' : '', $data ); $value = ((float) ($value - $min) * 100) / ($max - $min); ?>
    style="width:%;">
    PK!C8  Asystem/helixultimate/overrides/layouts/joomla/form/field/file.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $inputType Options available for this field. * @var array $spellcheck Options available for this field. * @var string $accept File types that are accepted. */ $maxSize = HTMLHelper::_('number.bytes', Utility::getMaxUploadSize()); ?> >
    PK!-Asystem/helixultimate/overrides/layouts/joomla/form/field/user.phpnu[ section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var string $userName The user name * @var mixed $groups The filtering groups (null means no filtering) * @var mixed $excluded The users to exclude from the list of users * @var string $dataAttribute Miscellaneous data attributes preprocessed for HTML output * @var array $dataAttributes Miscellaneous data attribute for eg, data-*. */ if (JVERSION >= 4) { $modalHTML = ''; $uri = new Uri('index.php?option=com_users&view=users&layout=modal&tmpl=component&required=0'); $uri->setVar('field', $this->escape($id)); if ($required) { $uri->setVar('required', 1); } if (!empty($groups)) { $uri->setVar('groups', base64_encode(json_encode($groups))); } if (!empty($excluded)) { $uri->setVar('excluded', base64_encode(json_encode($excluded))); } // Invalidate the input value if no user selected if ($this->escape($userName) === Text::_('JLIB_FORM_SELECT_USER')) { $userName = ''; } $inputAttributes = array( 'type' => 'text', 'id' => $id, 'class' => 'form-control field-user-input-name', 'value' => $this->escape($userName) ); if ($class) { $inputAttributes['class'] .= ' ' . $class; } if ($size) { $inputAttributes['size'] = (int) $size; } if ($required) { $inputAttributes['required'] = 'required'; } if (!$readonly) { $inputAttributes['placeholder'] = Text::_('JLIB_FORM_SELECT_USER'); } if (!$readonly) { $modalHTML = HTMLHelper::_( 'bootstrap.renderModal', 'userModal_' . $id, array( 'url' => $uri, 'title' => Text::_('JLIB_FORM_CHANGE_USER'), 'closeButton' => true, 'height' => '100%', 'width' => '100%', 'modalWidth' => 80, 'bodyHeight' => 60, 'footer' => '', ) ); Factory::getDocument()->getWebAssetManager() ->useScript('webcomponent.field-user'); } ?>
    readonly>
    'auto', 'relative' => true)); } $uri = new JUri('index.php?option=com_users&view=users&layout=modal&tmpl=component&required=0'); $uri->setVar('field', $this->escape($id)); if ($required) { $uri->setVar('required', 1); } if (!empty($groups)) { $uri->setVar('groups', base64_encode(json_encode($groups))); } if (!empty($excluded)) { $uri->setVar('excluded', base64_encode(json_encode($excluded))); } // Invalidate the input value if no user selected if ($this->escape($userName) === JText::_('JLIB_FORM_SELECT_USER')) { $userName = ''; } $inputAttributes = array( 'type' => 'text', 'id' => $id, 'value' => $this->escape($userName) ); if ($size) { $inputAttributes['size'] = (int) $size; } if ($required) { $inputAttributes['required'] = 'required'; } if (!$readonly) { $inputAttributes['placeholder'] = JText::_('JLIB_FORM_SELECT_USER'); } $anchorAttributes = array( 'class' => 'btn btn-primary modal_' . $id, 'title' => JText::_('JLIB_FORM_CHANGE_USER'), 'rel' => '{handler: \'iframe\', size: {x: 800, y: 500}}' ); ?>
    readonly /> ', $anchorAttributes); ?>
    PK!NABsystem/helixultimate/overrides/layouts/joomla/form/renderfield.phpnu[ 'auto', 'relative' => true)); } else { /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */ $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); $wa->useScript('showon'); } } $name = $name ?? ''; $class = empty($options['class']) ? '' : ' ' . $options['class']; $rel = empty($options['rel']) ? '' : ' ' . $options['rel']; $id = $name . '-desc'; $hideLabel = !empty($options['hiddenLabel']); $hideDescription = empty($options['hiddenDescription']) ? false : $options['hiddenDescription']; if (!empty($parentclass)) { $class .= ' ' . $parentclass; } ?>
    >
    PK!t5system/helixultimate/overrides/layouts/comingsoon.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later */ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; use HelixUltimate\Framework\Core\HelixUltimate; extract($displayData); $app = Factory::getApplication(); $doc = Factory::getDocument(); $title_status = $params->get('comingsoon_title_status'); $content_status = $params->get('comingsoon_content_status'); $countdown = $params->get('comingsoon_countdown'); /** * Load the bootstrap file for enabling the HelixUltimate\Framework namespacing. * * @since 2.0.0 */ $bootstrap_path = JPATH_PLUGINS . '/system/helixultimate/bootstrap.php'; if (file_exists($bootstrap_path)) { require_once $bootstrap_path; } else { die('Install and activate Helix Ultimate Framework.'); } $theme = new HelixUltimate; $site_title = $app->get('sitename'); ?> head(); $theme->add_js('jquery.countdown.min.js'); $theme->add_js('custom.js'); $theme->add_css('font-awesome.min.css, template.css'); $theme->add_css('presets/' . $params->get('preset', 'preset1') . '.css'); $theme->add_css('custom.css'); //Custom CSS if ($custom_css = $params->get('custom_css')) { $doc->addStyledeclaration($custom_css); } //Custom JS if ($custom_js = $params->get('custom_js')) { $doc->addScriptdeclaration($custom_js); } ?>
    get('comingsoon_logo')) : ?> get('comingsoon_title')) : ?>

    get('comingsoon_title')); ?>

    get('comingsoon_content')) : ?>
    get('comingsoon_content'); ?>
    get('display_offline_message', 1) == 1 && str_replace(' ', '', $app->get('offline_message')) != '') : ?>
    get('offline_message'); ?>
    get('display_offline_message', 1) == 2) : ?>
    get('comingsoon_date')) : ?> get("comingsoon_date")); ?>
    count_modules('comingsoon')) : ?>
    get('facebook'); $twitter = $params->get('twitter'); $pinterest = $params->get('pinterest'); $youtube = $params->get('youtube'); $linkedin = $params->get('linkedin'); $dribbble = $params->get('dribbble'); $behance = $params->get('behance'); $skype = $params->get('skype'); $flickr = $params->get('flickr'); $vk = $params->get('vk'); if( $params->get('comingsoon_social_icons') && ( $facebook || $twitter || $pinterest || $youtube || $linkedin || $dribbble || $behance || $skype || $flickr || $vk ) ) { $social_output = ''; echo $social_output; } ?> after_body(); ?>
    get('comingsoon_bg_image')) : ?> PK!^v--Nsystem/helixultimate/overrides/layouts/libraries/html/bootstrap/modal/main.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Layout\LayoutHelper; use Joomla\Utilities\ArrayHelper; extract($displayData); /** * Layout variables * ----------------- * @var string $selector Unique DOM identifier for the modal. CSS id without # * @var array $params Modal parameters. Default supported parameters: * - title string The modal title * - backdrop mixed A boolean select if a modal-backdrop element should be included (default = true) * The string 'static' includes a backdrop which doesn't close the modal on click. * - keyboard boolean Closes the modal when escape key is pressed (default = true) * - closeButton boolean Display modal close button (default = true) * - animation boolean Fade in from the top of the page (default = true) * - url string URL of a resource to be inserted as an ',r+="
    "),r+="
    ",r+="",r+='",r+="",r+="";const h=a("body").addClass("hu-modal-open");h.append(r),h.find(".hu-modal").fadeIn(300)},a.fn.helixUltimateModal=function(e){e=a.extend({target_type:"",target:""},e);a(".hu-modal-overlay, .hu-modal").remove();var s='
    ';s+='
    ',s+='
    ',s+='',s+='
    ',s+='
    ',s+=' Select',s+=' Cancel',s+=' Delete',s+="
    ",s+='
    ',s+=' Upload',s+=' New Folder',s+='',s+="
    ",s+="
    ",s+='
    ',s+='
    ',s+="
    ",s+="
    ",a("body").addClass("hu-modal-open").append(s)},a.fn.helixUltimateOptionsModal=function(e){e=a.extend({target:"",title:"Options",flag:"",class:"",applyBtnClass:"hu-settings-apply",footerButtons:[]},e);a(".hu-options-modal-overlay, .hu-options-modal").remove();var s='
    ';s+='
    ',s+='
    ',s+=''+e.title+"",s+='',s+="
    ",s+='
    ',s+='
    ',s+="
    ",s+="
    ",s+='",s+="
    ",a("body").addClass("hu-options-modal-open").append(s)}}));PK!Yrr4system/helixultimate/assets/js/admin/treeSortable.jsnu[/** * Tree sortable jQuery library using jQuery UI sortable. * * @package TreeSortable * @license MIT * @author Sajeeb Ahamed */ var $=jQuery,treeSortable={options:{depth:20,treeSelector:"#hu-menu-tree",branchSelector:".hu-menu-tree-branch",dragHandlerSelector:".hu-branch-drag-handler",placeholderName:"hu-sortable-placeholder",childrenBusSelector:".hu-menu-children-bus",levelPrefix:"hu-branch-level",maxLevel:10},run(){this.jQuerySupplements(),this.initSorting()},getTreeEdge:()=>$(treeSortable.options.treeSelector).offset().left,pxToNumber:e=>new RegExp("px$","i").test(e)?1*e.slice(0,-2):0,numberToPx:e=>`${e}px`,jQuerySupplements(){const{options:e}=treeSortable,{levelPrefix:t}=e;$.fn.extend({getBranchLevel(){if(0===$(this).length)return 0;const{depth:t}=e,r=$(this).css("margin-left");return/(px)|(em)|(rem)$/i.test(r)?Math.floor(r.slice(0,-2)/t)+1:Math.floor(r/t)+1},updateBranchLevel(e,r=null){return this.each((function(){r=r||$(this).getBranchLevel()||1,$(this).removeClass(t+"-"+r).addClass(t+"-"+e)}))},shiftBranchLevel(e){return this.each((function(){let r=$(this).getBranchLevel()||1,l=r+e;$(this).removeClass(t+"-"+r).addClass(t+"-"+l)}))},getParent(){const{options:{branchSelector:e}}=treeSortable,t=$(this).getBranchLevel()||1;let r=$(this).prev(e);for(;r.length&&r.getBranchLevel()>=t;)r=r.prev(e);return r},getRootChildren(){const{options:{branchSelector:e,treeSelector:t,levelPrefix:r}}=treeSortable;return $(t).children(`${e}.${r}-1`)},getChildren(){const{options:{branchSelector:e}}=treeSortable;let t=$();return this.each((function(){let r=$(this).getBranchLevel()||1,l=$(this).next(e);for(;l.length&&l.getBranchLevel()>r;)t=t.add(l),l=l.next(e)})),t},nextBranch(){return $(this).next()},prevBranch(){return $(this).prev()},nextSibling(){const{options:{branchSelector:e}}=treeSortable;let t=$(this).getBranchLevel()||1,r=$(this).next(e),l=r.getBranchLevel();for(;r.length&&l>t;)r=r.next(e),l=r.getBranchLevel();return+l==+t?r:$()},prevSibling(){const{options:{branchSelector:e}}=treeSortable;let t=$(this).getBranchLevel()||1,r=$(this).prev(e),l=r.getBranchLevel();for(;r.length&&l>t;)r=r.prev(e),l=r.getBranchLevel();return l===t?r:$()},getSiblings(e=null){const{options:{treeSelector:t,branchSelector:r}}=treeSortable;e=e||$(this).getBranchLevel();let l=[],a=$(`${t} > ${r}`),h=this;return a.length&&a.each((function(){+$(this).getBranchLevel()==+e&&h[0]!==$(this)[0]&&l.push($(this))})),l}})},updateBranchZIndex(){const{options:{treeSelector:e,branchSelector:t}}=treeSortable,r=$(`${e} > ${t}`),l=r.length;r.length&&r.each((function(e){$(this).css("z-index",Math.max(1,l-e))}))},initSorting(){const{options:e,pxToNumber:t,numberToPx:r,updateBranchZIndex:l}=treeSortable,{treeSelector:a,dragHandlerSelector:h,placeholderName:n,childrenBusSelector:o}=e;let c=1,i=1,s=null,p=0,g=0,d=!1;$(a).sortable({handle:h,placeholder:n,items:"> *",start(e,l){const a=l.item.getBranchLevel();l.placeholder.updateBranchLevel(a),g=l.item.index(),i=a,s=l.item.find(o),s.append(l.item.next().getChildren());let n=s.outerHeight(),d=l.placeholder.css("margin-top");n+=n>0?t(d):0,n+=l.helper.outerHeight(),p=n,n-=2;let u=l.helper.find(h).outerWidth()-2;l.placeholder.css({height:n,width:u});const v=l.placeholder.nextBranch();v.css("margin-top",r(p)),l.placeholder.detach(),$(this).sortable("refresh"),l.item.after(l.placeholder),v.css("margin-top",0),c=a,$(".hu-menu-tree-branch .hu-menu-branch-path").hide()},sort(e,t){const{options:r,getTreeEdge:l}=treeSortable,{depth:a,maxLevel:h}=r;let n=l(),o=t.helper.offset().left,i=1,s=h,g=t.placeholder.prevBranch();g=g[0]===t.item[0]?g.prevBranch():g;let u=g.getBranchLevel();s=Math.min(u+1,h);let v=1;if(t.placeholder.nextSibling().length)v=t.placeholder.getBranchLevel()||1;else{v=t.placeholder.nextBranch().getBranchLevel()||1}i=Math.max(1,v);let m=Math.max(0,o-n),b=Math.floor(m/a)+1;if(b=Math.max(i,Math.min(b,s)),(e=>{let t=e.helper.offset().top+p,r=e.placeholder.nextBranch(),l=r.offset()||0,a=r.outerHeight();return t>l.top+a/3})(t)){let e=t.placeholder.nextBranch();e.getChildren().length&&(b=e.getBranchLevel()+1),e.after(t.placeholder),$(this).sortable("refreshPositions")}let f=t.item.getSiblings(b);if(f.length>0){let e=t.item.data("alias");if(d=f.some((t=>t.data("alias")===e)),d)return}var B,x;B=t.placeholder,x=b,B.updateBranchLevel(x),c=x},change(e,t){let r=t.placeholder.prevBranch();r=r[0]===t.item[0]?r.prevBranch():r;let l=r.getBranchLevel()||1;if(r.length){t.placeholder.detach();let e=r.getChildren();e&&e.length&&(l+=1),t.placeholder.updateBranchLevel(l),r.after(t.placeholder)}},stop(e,t){$(".hu-menu-tree-branch:not(.hu-branch-level-1) .hu-menu-branch-path").show(),d&&Joomla.HelixToaster.error(`Can't set the same alias ${t.item.data("alias")} in the same menu level!`,"Error");const r=s.children().insertAfter(t.item);s.empty(),t.item.updateBranchLevel(c),r.shiftBranchLevel(c-i);t.item.find(".hu-branch-tools-list-megamenu").html(c>1?'':''),c===i&&g===t.item.index()||$(document).trigger("sortCompleted",[t]),Joomla.utils.calculateSiblingDistances()}})}};Joomla.sortable=treeSortable;PK!IV.u u /system/helixultimate/assets/js/admin/toaster.jsnu[const HelixToaster={options:{timeout:5e3,containerId:"hu-toaster-container",prefix:"hu-toaster",position:"hu-toaster-bottom-right",titleClass:"",messageClass:"",target:"body"},toasts:[],toastIndex:0,elementTimeout:null,success(t,e,s){this.createToaster({type:"success",message:t,title:e,options:s})},error(t,e,s){this.createToaster({type:"error",message:t,title:e,options:s})},info(t,e,s){this.createToaster({type:"info",message:t,title:e,options:s})},warning(t,e,s){this.createToaster({type:"warning",message:t,title:e,options:s})},getTypeClass:t=>`hu-toast-${t}`,createContainer(){const t=document.createElement("div");return t.setAttribute("id",this.options.containerId),t.setAttribute("class",this.options.position),document.querySelector(this.options.target).appendChild(t),t},createToaster({type:t,message:e,title:s,options:i}){const o=document.createElement("div");o.setAttribute("class",this.options.prefix+" "+this.getTypeClass(t));let a=`\n\t\t\t
    \n\t\t\t
    \n\t\t\t\t
    ${s}
    \n\t\t\t\t
    ${e}
    \n\t\t\t
    \n\t\t\t
    \n\n\t\t`;o.innerHTML=a,o.style.animationName="huFadeInUp",o.style.animationDuration=".35s",this.toasts.push(o),this.toastIndex++,this.getContainer().appendChild(o),this.elementTimeout=setTimeout((()=>{o.style.animationName="huFadeInDown",o.style.animationDuration=".35s",o.style.opacity=0,setTimeout((()=>{o.parentNode.removeChild(o)}),450)}),this.options.timeout),o.addEventListener("click",(t=>{t.preventDefault(),this.elementTimeout&&clearTimeout(this.elementTimeout),o.style.animationName="huFadeInDown",o.style.animationDuration=".35s",o.style.opacity=0,setTimeout((()=>{o.parentNode.removeChild(o)}),450)}))},getContainer(){let t=document.querySelector(`#${this.options.containerId}`);return t||(t=this.createContainer()),t},displayToaster(){const t=this.getContainer();t.innerHTML="",this.toasts.forEach((e=>{t.appendChild(e)}))},delay:(t=1e3)=>new Promise((e=>setTimeout(e,t))),removeToaster(t){return new Promise((e=>{this.toasts.splice(t,1);const s=document.querySelector(`#${this.options.containerId}`);s.firstChild&&s.removeChild(s.firstChild),e({status:!0})}))}};Joomla.HelixToaster=HelixToaster;PK!Br-system/helixultimate/assets/js/admin/utils.jsnu[const asciiToHex=e=>"0x"+e.split("").map((e=>e.charCodeAt(0).toString(16))).join(""),getCurrentTimeString=()=>{const e=new Date;return e.getFullYear()+"-"+(e.getMonth()+1)+"-"+e.getDate()+"-"+e.getHours()+":"+e.getMinutes()+":"+e.getSeconds()+":"+e.getMinutes()},helixHash=e=>{let t=0;const{length:n}=e;if(0===n)return t;for(let i=0;i{if(document.createEvent&&e){const n=document.createEvent("HTMLEvents");n.initEvent(t,!1,!1),e.dispatchEvent(n)}},setCookie=(e,t="",n=1)=>{let i="";if(n){let e=new Date;e.setTime(e.getTime()+24*n*60*60*1e3),i="; expires="+e.toUTCString()}document.cookie=e+"="+t+i+"; path=/"},getCookie=e=>{e+="=";let t=document.cookie.split(";");for(let n=0;n{document.cookie=e+"=; Max-Age=-99999999;"},debounce=(e,t)=>{let n;return function(){let i=this,o=arguments,s=function(){n=null,e.apply(i,o)};clearTimeout(n),n=setTimeout(s,t||200)}},getCenterPosition=e=>{const{top:t,left:n,width:i,height:o}=e.getBoundingClientRect();return{x:n+i/2,y:t+o/2}},getDistance=(e,t)=>{const n=getCenterPosition(e),i=getCenterPosition(t);return{distanceX:Math.floor(Math.abs(n.x-i.x)),distanceY:Math.floor(Math.abs(n.y-i.y))}};function calculateSiblingDistances(){const e=".hu-menu-tree-branch";$(e).each((function(){const t=$(this).getBranchLevel()||1;if($(this).find(".hu-menu-branch-path").show(),"function"==typeof $(this).nextSibling)if(t>1){const n=$(this).nextSibling();if(n.length){const e=getDistance($(this).get(0),n.get(0));n.find(".hu-menu-branch-path").css("height",`${Math.max(e.distanceY+8,55)}px`)}else{const n=$(this).next(e),i=n.getBranchLevel()||1;n.length>0&&i>t&&n.find(".hu-menu-branch-path").css("height","55px")}}else $(this).find(".hu-menu-branch-path").hide()}))}Joomla.utils={asciiToHex:asciiToHex,getCurrentTimeString:getCurrentTimeString,helixHash:helixHash,triggerEvent:triggerEvent,setCookie:setCookie,getCookie:getCookie,deleteCookie:deleteCookie,debounce:debounce,getDistance:getDistance,calculateSiblingDistances:calculateSiblingDistances};PK!F7+7+.system/helixultimate/assets/js/admin/layout.jsnu[/** * @package Helix Ultimate Framework * @author JoomShaper https://www.joomshaper.com * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ jQuery((function(t){function e(){let e=-1,n=-1;t("#hu-layout-builder").sortable({placeholder:"ui-state-highlight",forcePlaceholderSize:!0,axis:"y",opacity:1,tolerance:"pointer",start(t,o){e=o.item.index()},stop(t,a){n=a.item.index(),e!==n&&(o(),Joomla.HelixToaster.success("Rows position changed!","Layout Settings"))}}).disableSelection(),t(".hu-layout-section").find("[data-hu-layout-row]").rowSortable()}function o(){var e;t("#layout").val(JSON.stringify((e=[],t("#hu-layout-builder").find(".hu-layout-section").each((function(o){var n=t(this),a=o,i=n.data();delete i.sortableItem;var l=n.find(".hu-column-layout.active").data("layout"),s=12;12!=l&&(s=l.split(",").join("")),e[a]={type:"row",layout:s,settings:i,attr:[]},n.find(".hu-layout-column").each((function(o){var n=o,i=t(this).data();delete i.sortableItem,e[a].attr[n]={type:"sp_col",settings:i}}))})),e))).trigger("change")}t(document).on("click",".hu-add-columns",(function(e){e.preventDefault(),e.stopPropagation(),t(this).closest("li").find(".hu-column-list").slideToggle(300),console.log("click fired")})),t(document).on("click",".hu-column-layout:not(.hu-layout-custom-btn)",(function(){t(this).closest(".hu-column-list").slideUp(300)})),t.fn.rowSortable=function(){let e=-1,n=-1;t(this).sortable({placeholder:"ui-state-highlight",forcePlaceholderSize:!0,axis:"x",opacity:1,tolerance:"pointer",start(o,n){t(".hu-layout-section [data-hu-layout-row]").find(".ui-state-highlight").addClass(t(n.item).attr("class")),t(".hu-layout-section [data-hu-layout-row]").find(".ui-state-highlight").css("height",t(n.item).outerHeight()),e=n.item.index()},stop(t,a){n=a.item.index(),e!==n&&(o(),Joomla.HelixToaster.success("Columns position changed!","Layout Settings"))}}).disableSelection()},e(),t.fn.setInputValue=function(e){console.log(e),"checkbox"==this.attr("type")?"1"==e.field?this.attr("checked","checked"):this.removeAttr("checked"):this.hasClass("input-select")?(this.val(e.field),this.trigger("liszt:updated"),this.trigger("chosen:updated")):this.hasClass("input-media")?(e.field&&($imgParent=this.parent(".media"),$imgParent.find("img.media-preview").each((function(){t(this).attr("src",layoutbuilder_base+e.field)}))),this.val(e.field)):this.val(e.field),"column_type"==this.data("attrname")&&"component"==this.val()&&t(".form-group.name").hide()},t.fn.getInputValue=function(){return"checkbox"==this.attr("type")?this.prop("checked")?"1":"0":this.val()},t.fn.initColorPicker=function(){Joomla.initColorPicker(this.find(".minicolors"))},t(document).on("click",".hu-row-options",(function(e){e.preventDefault(),t(this).helixUltimateOptionsModal({flag:"row-setting",title:" Row Options",class:"hu-modal-small"}),t(".hu-layout-section").removeClass("row-active"),$parent=t(this).closest(".hu-layout-section"),$parent.addClass("row-active"),t("#hu-row-settings").find("select.hu-input").each((function(){t(this).chosen("destroy")}));var o=t("#hu-row-settings").clone(!0);o.find(".hu-input-color").each((function(){t(this).addClass("minicolors")})),o.find("select.hu-input").each((function(){t(this).chosen({width:"100%"})})),(o=t(".hu-options-modal-inner").html(o.removeAttr("id").addClass("hu-options-modal-content"))).find(".hu-input").each((function(){var e=t(this),o=$parent.data(e.data("attrname"));if(e.setInputValue({field:o}),e.hasClass("hu-input-media")&&o){e.prev(".hu-image-holder").html('');let t=e.siblings(".hu-media-clear");t.hasClass("hide")&&t.removeClass("hide")}})),o.initColorPicker()})),t(document).on("click",".hu-column-options",(function(e){e.preventDefault(),t(this).helixUltimateOptionsModal({flag:"column-setting",title:" Column Options",class:"hu-modal-small"}),t(".hu-layout-column").removeClass("column-active"),$parent=t(this).closest(".hu-layout-column"),$parent.addClass("column-active"),t("#hu-column-settings").find("select.hu-input").each((function(){t(this).chosen("destroy")}));var o=t("#hu-column-settings").clone(!0);o.find(".hu-input-color").each((function(){t(this).addClass("minicolors")})),(o=t(".hu-options-modal-inner").html(o.removeAttr("id").addClass("hu-options-modal-content"))).find(".hu-input").each((function(){var e=t(this),o=$parent.data(e.data("attrname"));e.setInputValue({field:o})})),o.find("select.hu-input").each((function(){t(this).chosen({width:"100%"})})),o.initColorPicker()})),t(".hu-input-column_type").change((function(e){var n=t(this).closest(".hu-modal-content"),a=!1;if(t("#hu-layout-builder").find(".hu-layout-column").not(".column-active").each((function(e,o){if("1"==t(this).data("column_type"))return a=!0,!1})),a)return alert("Component Area Taken"),t(this).prop("checked",!1),n.children(".control-group.name").slideDown("400"),!1;t(this).attr("checked")?(t(".hu-layout-column.column-active").find(".hu-column").addClass("hu-column-component"),n.children(".control-group.name").slideUp("400")):(t("#hu-layout-builder").find(".hu-column-component").removeClass("hu-column-component"),n.children(".control-group.name").slideDown("400")),o()})),t(document).on("click",".hu-settings-apply",(function(e){switch(e.preventDefault(),t(this).data("flag")){case"row-setting":t(".hu-options-modal-content").find(".hu-input").each((function(){var e=t(this),o=t(".row-active"),n=e.data("attrname");if(o.removeData(n),"name"==n){var a=e.val();""==a||null==a?t(".row-active .hu-section-title").text("Section Header"):t(".row-active .hu-section-title").text(e.val())}o.data(n,e.getInputValue())})),t(".hu-options-modal-overlay, .hu-options-modal").remove(),t("body").removeClass("hu-options-modal-open");break;case"column-setting":var n=!1;t(".hu-options-modal-content").find(".hu-input").each((function(){var e=t(this),o=t(".column-active"),a=e.data("attrname"),i=e.val();o.removeData(a),"column_type"==a&&t(this).attr("checked")?(n=!0,t(".column-active .hu-column-title").text("Component")):"name"==a&&1!=n&&(""!=i&&null!=i||(i="none"),t(".column-active .hu-column-title").text(i)),o.data(a,e.getInputValue())})),t(".hu-options-modal-overlay, .hu-options-modal").remove(),t("body").removeClass("hu-options-modal-open");break;case"menu-row-setting":case"menu-col-setting":t(".hu-options-modal-overlay, .hu-options-modal").remove(),t("body").removeClass("hu-options-modal-open");break;default:alert("You are doing somethings wrongs. Try again")}o(),Joomla.HelixToaster.success("Changes applied successfully!","Layout Settings")})),t(document).on("click",".hu-settings-cancel, .action-hu-options-modal-close",(function(e){e.preventDefault(),t(".hu-options-modal-overlay, .hu-options-modal").remove(),t("body").removeClass("hu-options-modal-open")})),t(document).on("click",".hu-column-layout",(function(n){n.preventDefault();var a=t(this),i=a.data("type");if((!a.hasClass("active")||"custom"==i)&&"custom"!==i){var l=a.closest(".hu-column-list"),s=a.closest(".hu-layout-section"),u=l.find(".active").data("layout"),c=a.data("layout"),h=["12"];12!=u&&u.split("+"),12!=c&&(h=c.split("+"));var r=[],d=[];s.find(".hu-layout-column").each((function(e,o){r[e]=t(this).html();var n=t(this).data();d[e]="object"==typeof n?t(this).data():""})),l.find(".active").removeClass("active"),a.addClass("active");for(var m="",p=0;p",r[p]?m+=r[p]:(m+='
    ',m+='none',m+='',m+="
    "),m+=""}$old_column=s.find(".hu-layout-column"),s.find("[data-hu-layout-row]").append(m),$old_column.remove(),e(),Joomla.HelixToaster.success("Grid pattern updated to "+h.join("+")+"","Layout Settings"),o()}})),t(document).on("click",".hu-layout-custom-btn",(function(e){e.preventDefault();t(this).closest(".hu-column-list").find(".hu-layout-custom").slideToggle(300)})),t(document).on("click",".hu-layout-custom-apply",(function(n){n.preventDefault();let a=t(this).closest(".hu-column-list").find(".hu-layout-custom-btn"),i=a.closest(".hu-column-list"),l=a.closest(".hu-layout-section"),s=i.find(".active").data("layout"),u=["12"],c=column=t(this).closest("div").find("input").val()||"12",h=["12"];12!=s&&(u=s.split("+")),12!=c&&(h=c.split("+"));var r=column.split("+");if(12!=r.reduce((function(t,e){return Number(t)+Number(e)})))return void alert("Invalid grid pattern!");h=r,a.data("layout",column).attr("data-layout",column);var d=[],m=[];l.find(".hu-layout-column").each((function(e,o){d[e]=t(this).html();var n=t(this).data();m[e]="object"==typeof n?t(this).data():""})),i.find(".active").removeClass("active"),a.addClass("active");let p="";for(let e=0;e",d[e]?p+=d[e]:(p+='
    ',p+='none',p+='',p+="
    "),p+=""}$old_column=l.find(".hu-layout-column"),l.find("[data-hu-layout-row]").append(p),$old_column.remove(),e(),Joomla.HelixToaster.success("Grid pattern updated to "+h.join("+")+"","Layout Settings"),o(),a.closest(".hu-column-list").slideUp(300)})),t(document).on("click",".hu-add-row",(function(n){n.preventDefault();var a=t(this).closest(".hu-layout-section"),i=t("#hu-layout-section").clone(!0);i.addClass("hu-layout-section").removeAttr("id"),t(i).insertAfter(a),e(),Joomla.HelixToaster.success("New row added!","Layout Settings"),o()})),t(document).on("click",".hu-remove-row",(function(e){e.preventDefault(),1==confirm("Click Ok button to delete Row, Cancel to leave.")&&t(this).closest(".hu-layout-section").slideUp(500,(function(){t(this).remove(),Joomla.HelixToaster.error("Row is removed!","Layout Settings"),o()}))})),t(document).on("click",".remove-media",(function(){t(this).parent(".media").find("img.media-preview").each((function(){t(this).attr("src",""),t(this).closest(".image-preview").css("display","none")})),o()}))}));PK!:770system/helixultimate/assets/js/admin/megamenu.jsnu[var megaMenu={run(){this.declareDOMVariables(),this.initMiniColors(),this.jQueryPluginExtension(),this.initChosen(),this.removeEventListeners(),this.handleMegaMenuToggle(),this.toggleSidebarSettings($megamenu.prop("checked")),this.handleSidebarSettings(),this.handleCloseModal(),this.rowSortable(".hu-megamenu-rows-container"),this.columnSortable(".hu-megamenu-columns-container"),this.itemSortable(".hu-megamenu-column-contents"),this.handleSaveMegaMenuSettings(),this.handleRemoveRow(),this.handleLoadSlots(),this.handleCustomLayoutDisplay(),this.handleLayoutOptionSelection(),this.handleCustomLayoutSelection(),this.handleRowWiseColumnLayoutSelection(),this.openModulePopover(),this.handleClosePopover(),this.handleAddNewCell(),this.handleRemoveCell(),this.toggleColumnsSlots(),this.handleModuleSearch()},jQueryPluginExtension(){$.fn.extend({test(){return this.css("color","#fff")}})},initChosen(){$("select[data-husearch]").chosen({width:"100%",allow_single_deselect:!0,placeholder_text_single:Joomla.Text._("HELIX_ULTIMATE_SELECT_ICON_LABEL")})},declareDOMVariables(){$megamenu=$(".hu-megamenu-builder-megamenu"),$settingsInput=$("#hu-megamenu-layout-settings"),$saveBtn=$(".hu-megamenu-save-btn"),$cancelBtn=$(".hu-megamenu-cancel-btn"),$rowsContainer=$(".hu-megamenu-rows-container"),$popover=$(".hu-megamenu-popover");itemId=$("#hu-menu-itemid").val(),settingsData=$settingsInput.val(),settingsData=settingsData&&JSON.parse(settingsData),settingsData=$.extend({badge:"",badge_bg_color:"",badge_position:"",badge_text_color:"",customclass:"",dropdown:"right",faicon:"",layout:[],megamenu:0,menualign:"full",showtitle:1,width:"600px"},settingsData),baseUrl=$("#hu-base-url").val()},handleRemoveCell(){$(document).on("click",".hu-megamenu-cell-remove",(function(){const e=$(this).closest(".hu-megamenu-cell").data("cellid")||1,t=$(this).closest(".hu-megamenu-col").data("columnid")||1,a=$(this).closest(".hu-megamenu-row-wrapper").data("rowid")||1;$(this).closest(".hu-megamenu-cell").slideUp((function(){$(this).remove();let o=settingsData.layout[a-1].attr[t-1],n=void 0!==o.items?o.items:[];n.length>0&&n.splice(e-1,1),settingsData.layout[a-1].attr[t-1].items=n}))}))},handleAddNewCell(){const e=this;$(document).on("click",".hu-megamenu-insert-module",(async function(){const t=$(this).data("module"),a="module",o=$popover.data("rowid"),n=$popover.data("columnid"),s=settingsData.layout[o-1].attr[n-1]||{items:[]};void 0===s.items&&(s.items=[]);const l={type:a,item_id:t,itemId:itemId,rowId:o,columnId:n,cellId:s.items.length+1},u=await e.addNewCell(l);u.status&&($(`.hu-megamenu-row-wrapper[data-rowid=${o}] .hu-megamenu-col[data-columnid=${n}] .hu-megamenu-column-contents`).append(u.html),e.closePopover(),s.items.push({type:a,item_id:t}),settingsData.layout[o-1].attr[n-1]=s)}))},addNewCell(e){let t=`${baseUrl}/administrator/index.php?option=com_ajax&helix=ultimate&request=task&action=generateNewCell&helix_id=${helixUltimateStyleId}`;return new Promise(((a,o)=>{$.ajax({method:"POST",url:t,data:e,success(e){e="string"==typeof e&&e.length>0&&JSON.parse(e),a(e)},error(e){o(e)}})}))},handleClosePopover(){const e=this;$(document).on("click",".hu-megamenu-popover-close",(function(){e.closePopover()}))},openPopover(){!$popover.hasClass("show")&&$popover.addClass("show"),$(".hu-megamenu-module-search").val("")},closePopover(){$popover.hasClass("show")&&$popover.removeClass("show")},openModulePopover(){const e=this;$(document).on("click",".hu-megamenu-add-new-item",(async function(t){const a=$(this).closest(".hu-megamenu-col").data("columnid")||1,o=$(this).closest(".hu-megamenu-row-wrapper").data("rowid")||1;$popover.data("rowid",o).data("columnid",a).attr("data-rowid",o).attr("data-columnid",a);const n=await e.getModulesContents();n.status&&$popover.find(".hu-megamenu-modules-container").html(n.html),e.openPopover()}))},handleModuleSearch(){let e=null,t=this;$(document).on("keyup",".hu-megamenu-module-search",(function(a){a.preventDefault(),e&&clearTimeout(e),e=setTimeout((async()=>{let{value:e}=a.target;const o=await t.getModulesContents(e);o.status&&$popover.find(".hu-megamenu-modules-container").html(o.html)}),100)}))},getModulesContents(e=""){const t=`${baseUrl}/administrator/index.php?option=com_ajax&helix=ultimate&request=task&action=getModuleList&keyword=${e}&helix_id=${helixUltimateStyleId}`;return new Promise(((e,a)=>{$.ajax({method:"GET",url:t,success(t){t="string"==typeof t&&t.length>0&&JSON.parse(t),e(t)},error(e){a(e)}})}))},initMiniColors(){$(".hu-input-color").each((function(){!$(this).hasClass("minicolors")&&$(this).addClass("minicolors")})),Joomla.initColorPicker(".hu-megamenu-container .minicolors")},handleMegaMenuToggle(){let e=this;$megamenu.on("change",(function(t){t.preventDefault(),e.toggleSidebarSettings($(this).prop("checked"))}))},toggleSidebarSettings(e){let t=$(".hu-megamenu-grid"),a=$(".hu-megamenu-settings"),o=$(".hu-megamenu-alignment"),n=$(".hu-menuitem-dropdown-position"),s=$(".hu-mega-menu-builder");e?(a.hasClass("show")||a.addClass("show"),t.hasClass("show")||t.addClass("show"),s.hasClass("collapsed")&&s.removeClass("collapsed"),o.show(),n.hide()):(a.hasClass("show")&&a.removeClass("show"),t.hasClass("show")&&t.removeClass("show"),s.hasClass("collapsed")||s.addClass("collapsed"),o.hide(),n.show())},handleCustomLayoutDisplay(){$(document).on("click",".hu-megamenu-custom",(function(){$(this).closest(".hu-megamenu-columns-layout").find(".hu-megamenu-custom-layout").slideToggle(100)}))},closeRowLayoutDisplay(){let e=$(".hu-megamenu-row-slots");e.hasClass("show")&&e.removeClass("show")},closeLayoutDisplay(){$(".hu-megamenu-add-slots").hide()},removeEventListeners(){$(document).off("click",".hu-megamenu-add-slots .hu-megamenu-custom-layout-apply"),$(document).off("click",".hu-megamenu-remove-row"),$(document).off("click",".hu-megamenu-add-row > a"),$(document).off("click",".hu-megamenu-custom"),$(document).off("click",".hu-megamenu-columns"),$(document).off("click",".hu-megamenu-add-new-item"),$(document).off("click",".hu-megamenu-cell-options-item"),$(document).off("click",".hu-megamenu-popover-close"),$(document).off("click",".hu-megamenu-insert-module"),$(document).off("click",".hu-megamenu-cell-remove"),$(document).off("click",".hu-megamenu-add-slots .hu-megamenu-column-layout:not(.hu-megamenu-custom)"),$(document).off("click",".hu-megamenu-row-slots .hu-megamenu-column-layout:not(.hu-megamenu-custom)"),$(document).off("click",".hu-megamenu-row-slots .hu-megamenu-custom-layout-apply"),$cancelBtn.off("click"),$saveBtn.off("click"),$megamenu.off("change")},handleRowWiseColumnLayoutSelection(){const e=this;$(document).on("click",".hu-megamenu-row-slots .hu-megamenu-column-layout:not(.hu-megamenu-custom)",(async function(){const t=$(this).closest(".hu-megamenu-row-wrapper").data("rowid")-1,a=$(this).data("layout")||"12";await e.changeRowsColumns({rowIndex:t,layout:a,$container:$(this).closest(".hu-megamenu-row-wrapper").find(".hu-megamenu-columns-container")})})),$(document).on("click",".hu-megamenu-row-slots .hu-megamenu-custom-layout-apply",(async function(){const t=$(this).closest(".hu-megamenu-row-wrapper").data("rowid")-1,a=$(this).parent().find(".hu-megamenu-custom-layout-field").val();await e.changeRowsColumns({rowIndex:t,layout:a,$container:$(this).closest(".hu-megamenu-row-wrapper").find(".hu-megamenu-columns-container")})}))},async changeRowsColumns({rowIndex:e,layout:t,$container:a}){const o=settingsData.layout[e],n=await this.updateRowLayout({layout:t,rowData:JSON.stringify(o),rowId:e+1,itemId:itemId});n.status&&(a.html(n.html),settingsData.layout[e]=n.data,this.closeRowLayoutDisplay(),this.refreshSortable(["item"]))},updateRowLayout:({layout:e,rowData:t,rowId:a,itemId:o})=>new Promise(((n,s)=>{const l=`${baseUrl}/administrator/index.php?option=com_ajax&helix=ultimate&request=task&action=updateRowLayout&helix_id=${helixUltimateStyleId}`,u={layout:e,data:t,rowId:a,itemId:o};$.ajax({method:"POST",url:l,data:u,success(e){e=!("string"!=typeof e||!e.length)&&JSON.parse(e),n(e)},error(e){s(e)}})})),handleLayoutOptionSelection(){let e=this;$(document).on("click",".hu-megamenu-add-slots .hu-megamenu-column-layout:not(.hu-megamenu-custom)",(async function(t){t.preventDefault();const a=$(this).data("layout")||"12",o=settingsData.layout.length+1,n=await e.generateRow(a,o,itemId);n.status&&($rowsContainer.append(n.data),e.closeLayoutDisplay(),settingsData.layout.push(n.row),e.refreshSortable(["column","item"]))}))},handleCustomLayoutSelection(){let e=this;$(document).on("click",".hu-megamenu-add-slots .hu-megamenu-custom-layout-apply",(async function(t){t.preventDefault();let a=$(".hu-megamenu-custom-layout-field").val(),o=settingsData.layout.length+1;if(""==a)return;const n=await e.generateRow(a,o,itemId);n.status&&($rowsContainer.append(n.data),e.closeLayoutDisplay(),settingsData.layout.push(n.row),e.refreshSortable())}))},toggleColumnsSlots(){$(document).on("click",".hu-megamenu-columns",(function(){$(this).closest(".hu-megamenu-row-toolbar-right").find(".hu-megamenu-row-slots").toggleClass("show")}))},generateRow:(e,t,a)=>new Promise(((o,n)=>{const s=`${baseUrl}/administrator/index.php?option=com_ajax&helix=ultimate&request=task&action=generateRow&helix_id=${helixUltimateStyleId}`,l={layout:e,rowId:t,itemId:a};$.ajax({method:"POST",url:s,data:l,success(e){e=!("string"!=typeof e||!e.length)&&JSON.parse(e),o(e)},error(e){n(e)}})})),handleSidebarSettings(){let e=this;[".hu-megamenu-sidebar [name=megamenu]",".hu-megamenu-sidebar [name=width]",".hu-megamenu-sidebar [name=dropdown]",".hu-megamenu-sidebar [name=showtitle]",".hu-megamenu-sidebar [name=menualign]",".hu-megamenu-sidebar [name=faicon]",".hu-megamenu-sidebar [name=customclass]",".hu-megamenu-sidebar [name=badge]",".hu-megamenu-sidebar [name=badge_position]",".hu-megamenu-sidebar [name=badge_bg_color]",".hu-megamenu-sidebar [name=badge_text_color]"].forEach((t=>{$(t).on("change",(function(t){t.preventDefault();let{name:a,value:o}=t.target;o="checkbox"===$(this).attr("type")?($(this).prop("checked")>>0).toString():o,e.updateSettingsField(a,o)}))}))},swapRow(e,t){let a=settingsData.layout,o=a.splice(e,1);a.splice(t,0,o[0]),settingsData.layout=a},swapColumn(e,t,a){let o=settingsData.layout[e].attr,n=o.splice(t,1);o.splice(a,0,n[0]),settingsData.layout[e].attr=o},swapItem({prevRowIndex:e,prevColIndex:t,prevItemIndex:a,currRowIndex:o,currColIndex:n,currItemIndex:s}){let l=[...settingsData.layout[e].attr[t].items],u=l.splice(a,1);settingsData.layout[e].attr[t].items=l;let i=settingsData.layout[o].attr[n];void 0===i.items&&(i.items=[]);let m=[...i.items];0===m.length?m.push(u[0]):m.splice(s,0,u[0]),i.items=m,settingsData.layout[o].attr[n]=i},updateSettings(){$settingsInput.val(JSON.stringify(settingsData))},updateSettingsField(e,t){settingsData[e]=t},handleRemoveRow(){$(document).on("click",".hu-megamenu-remove-row",(function(e){e.preventDefault();let t=$(this).closest(".hu-megamenu-row-wrapper"),a=t.index();t.slideUp(100,(function(){$(this).remove(),settingsData.layout.splice(a,1)}))}))},handleLoadSlots(){$(document).on("click",".hu-megamenu-add-row > a",(function(){$(this).closest(".hu-megamenu-grid").find(".hu-megamenu-add-slots").toggle()}))},handleCloseModal(){$cancelBtn.on("click",(function(){$(this).closeModal()}))},handleSaveMegaMenuSettings(){let e=this;$saveBtn.on("click",(function(){e.saveMegaMenuSettings()}))},saveMegaMenuSettings(){const e=`${baseUrl}/administrator/index.php?option=com_ajax&helix=ultimate&request=task&action=saveMegaMenuSettings&helix_id=${helixUltimateStyleId}`,t={settings:settingsData,id:itemId};$.ajax({method:"POST",url:e,data:t,success(e){(e="string"==typeof e&&e.length>0&&JSON.parse(e)).status&&Joomla.reloadPreview()},error(e){alert("Something went wrong!")},complete(){$(document).closeModal(),Joomla.HelixToaster.success("Saved mega menu settings!","Success")}})},refreshSortable(e){e||(e=["row","column","item"]),"string"==typeof e&&(e=[e]);const t={row:{selector:".hu-megamenu-rows-container",func:"rowSortable"},column:{selector:".hu-megamenu-columns-container",func:"columnSortable"},item:{selector:".hu-megamenu-column-contents",func:"itemSortable"}};for(let a=0;a *",tolerance:"pointer",scroll:!0,start(e,t){let o=t.helper.outerHeight();o-=2,t.placeholder.css({height:o}),a=t.item.index()},stop(e,n){o=n.item.index(),t.swapRow(a,o),t.updateRows()}}).disableSelection()},updateColumns(e){$(`.hu-megamenu-row-wrapper[data-rowid=${e+1}]`).find(".hu-megamenu-col").each((function(e){$(this).data("columnid",e+1).attr("data-columnid",e+1)}))},columnSortable(e){let t,a,o,n,s=this;$(e).sortable({handle:".hu-megamenu-column-drag-handler",placeholder:"hu-column-sortable-placeholder",containment:".hu-megamenu-grid",axis:"x",items:"> *",start(e,a){let s=a.helper.outerHeight(),l=a.helper.outerWidth();a.placeholder.css({height:s,width:l}),o=a.item.closest(".hu-megamenu-row-wrapper").data("rowid")-1,t=a.item.index(),n=a.item.closest(".hu-megamenu-columns-container"),n.addClass("hu-megamenu-column-dragging")},stop(e,l){a=l.item.index(),s.swapColumn(o,t,a),s.updateColumns(o),n.removeClass("hu-megamenu-column-dragging")}})},itemSortable(e){let t,a,o,n,s,l,u,i=this;$(e).sortable({connectWith:".hu-megamenu-column-contents",placeholder:"hu-item-sortable-placeholder",containment:".hu-megamenu-grid",items:"> .hu-megamenu-cell",start(e,t){let a=t.helper.outerHeight(),l=t.helper.outerWidth();t.placeholder.css({height:a,width:l}),n=(t.item.closest(".hu-megamenu-col").data("columnid")||1)-1,o=(t.item.closest(".hu-megamenu-row-wrapper").data("rowid")||1)-1,s=t.item.index(),u=t.item.find(".hu-megamenu-cell-remove"),u.css({opacity:0})},stop(e,m){a=(m.item.closest(".hu-megamenu-col").data("columnid")||1)-1,t=(m.item.closest(".hu-megamenu-row-wrapper").data("rowid")||1)-1,l=m.item.index(),i.swapItem({prevRowIndex:o,prevColIndex:n,prevItemIndex:s,currRowIndex:t,currColIndex:a,currItemIndex:l}),u.css({opacity:1})}}).disableSelection()}};Joomla.helixMegaMenu=megaMenu;PK!TVKK6system/helixultimate/assets/js/admin/helix-ultimate.jsnu[/** * @package Helix Ultimate Framework * @author JoomShaper https://www.joomshaper.com * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ window.addEventListener("DOMContentLoaded",(()=>{void 0!==Joomla.Showon&&void 0!==Joomla.Showon.initialise&&Joomla.Showon.initialise(document)})),jQuery((function(e){"use strict";var t=Joomla.getOptions("data")||{};let i=Joomla.getOptions("meta")||{};const a=localStorage||window.localStorage;let s=null;Joomla.initColorPicker=function(t,i={}){const a={animationSpeed:50,animationEasing:"swing",control:"hue",position:"bottom",theme:"bootstrap",keywords:"transparent, initial, inherit",letterCase:"uppercase"};e(t).each((function(){e(this).minicolors({...a,...i})}))},e(".form-select[multiple]").chosen({width:"100%"});const o=()=>{let t=a.getItem("toolbarPosition")||{};t="string"==typeof t&&t.length>0&&JSON.parse(t);let i=e(".hu-container"),s=e("#hu-options-panel"),o=i.width(),n=s.width();t.left+n>o?t.left=o-n-20:t.left<0&&(t.left=20),t&&e(".hu-options-core").css({left:t.left+"px",top:t.top+"px"}),e(".hu-options-core").show()};o(),window.addEventListener("resize",o);window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;let n=document.getElementById("hu-template-preview");function l(){const e=n.contentWindow.location.href;e.length&&"about:blank"!==e&&(n.src=n.getAttribute("src"))}function r(){e("#layout").val(JSON.stringify(m())),f(),e(".hu-input-preset").val(JSON.stringify(e(".hu-preset.active").data()));let t=e("#hu-style-form").find("input, select, textarea").not(".internal-use-only").serializeArray(),i=!1;e.ajax({type:"POST",url:"index.php?option=com_ajax&request=task&helix=ultimate&id="+helixUltimateStyleId+"&action=draft-tmpl-style&format=json&helix_id="+helixUltimateStyleId,data:t,beforeSend:function(){Joomla.helixLoading(!0,!1),i=!0},success:function(t){var a=e.parseJSON(t);if(a.status){let e=document.getElementById("hu-template-preview");l(),e.addEventListener("load",(function(){i&&Joomla.helixLoading(!1,a.isDrafted),i=!1}))}},error:function(e){console.error("error: Something went wrong!",e),Joomla.HelixToaster.error("Error:"+e.message,"Error")}})}function c(t){const i=e(".hu-topbar-save-spinner");t?i.hasClass("hidden")&&(i.removeClass("hidden"),i.closest(".action-save-template").find("svg").hide()):i.hasClass("hidden")||(i.addClass("hidden"),i.closest(".action-save-template").find("svg").show())}function h(e,t,i,a){a!=i&&(i=a,e.closest(".controls").attr("data-currpoint",i),e.closest(".controls").data("currpoint",i),e.closest(".controls").hasClass("helix-input-touched")||e.closest(".controls").addClass("helix-input-touched"),r()),a==t&&e.closest(".controls").hasClass("helix-input-touched")&&e.closest(".controls").removeClass("helix-input-touched")}function u({name:t,parent:i,map:a,device:s}){["","_sm","_xs"].forEach((a=>{const s=e(`input[name=${t}${a}]`).closest(i);s.hasClass("field-hidden")||s.addClass("field-hidden")}));const o=`input[name=${t}${"md"===a[s]?"":"_"+a[s]}]`;e(o).closest(i).removeClass("field-hidden")}function d(i){const a={desktop:"100%",tablet:`${t.breakpoints.tablet}px`,mobile:`${t.breakpoints.mobile}px`,md:"100%",sm:`${t.breakpoints.tablet}px`,xs:`${t.breakpoints.mobile}px`},s={md:"desktop",sm:"tablet",xs:"mobile",desktop:"desktop",tablet:"tablet",mobile:"mobile"},o={desktop:"md",tablet:"sm",mobile:"xs"},n=e("#hu-template-preview");e(`.hu-device[data-device=${s[i]}]`).parent().find(".active").removeClass("active"),e(`.hu-device[data-device=${s[i]}]`).addClass("active"),["","-sm","-xs"].forEach((t=>{e(`.hu-webfont-size-field${t}`).closest(".hu-webfont-unit").removeClass("active")})),e("input.hu-webfont-size-field"+("md"===o[i]?"":"-"+o[i])).closest(".hu-webfont-unit").addClass("active"),u({name:"header_height",parent:".group-style-header",map:o,device:i}),u({name:"logo_height",parent:".group-style-logo",map:o,device:i}),n.animate({width:a[i]},300,"linear")}function p(){let t=e(".hu-options-core"),i=e(".hu-edit-panel.active-panel"),a=e("#hu-options-panel"),s=e(".hu-container"),o=a.offset(),n=a.width(),l=i.width(),r=s.width();o.left+n+10+l>r?(t.hasClass("hu-panel-position-right")&&t.removeClass("hu-panel-position-right"),t.addClass("hu-panel-position-left")):(t.hasClass("hu-panel-position-left")&&t.removeClass("hu-panel-position-left"),t.addClass("hu-panel-position-right"))}function f(){e(".hu-field-webfont").each((function(){var t=e(this),i={fontFamily:t.find(".hu-webfont-list").val(),fontSize:t.find("[name=hu-webfont-size-field]").val(),fontSize_sm:t.find("[name=hu-webfont-size-field-sm]").val(),fontSize_xs:t.find("[name=hu-webfont-size-field-xs]").val(),fontWeight:t.find(".hu-webfont-weight-list").val(),fontStyle:t.find(".hu-webfont-style-list").val(),fontSubset:t.find(".hu-webfont-subset-list").val(),fontColor:t.find(".hu-font-color-input").val(),fontLineHeight:t.find(".hu-font-line-height-input").val(),fontLetterSpacing:t.find("[name=hu-font-letter-spacing-input]").val(),textDecoration:t.find(".hu-text-decoration").val(),textAlign:t.find(".hu-text-align").val()};t.find(".hu-webfont-input").val(JSON.stringify(i))}))}function m(){var t=[];return e("#hu-layout-builder").find(".hu-layout-section").each((function(i){var a=e(this),s=i,o=a.data();delete o.sortableItem;var n=a.find(".hu-column-layout.active").data("layout"),l=12;12!=n&&(l=n.split(",").join("")),t[s]={type:"row",layout:l,settings:o,attr:[]},a.find(".hu-layout-column").each((function(i){var a=i,o=e(this).data();delete o.sortableItem,t[s].attr[a]={type:"sp_col",settings:o}}))})),t}Joomla.reloadPreview=l,n.addEventListener("load",(function(){let e=n.contentWindow.document,i=e.querySelector(".body-innerwrapper");e.querySelectorAll("a").forEach((e=>{let t=e.getAttribute("href")||"";if("#"===t||""===t)return;let i=new URLSearchParams(new URL(e.href).search);if(i.has("helixMode"))return;i.append("helixMode","edit");let a=e.href.split("?");a[1]=i.toString(),e.setAttribute("href",a.join("?"))})),e.body.classList.add("back-panel"),i&&(i.style.marginTop=`${t.topbarHeight}px`)})),e(document).on("keyup",(function(t){if(27===t.which){if(e(".hu-megamenu-popover").hasClass("show"))return void e(".hu-megamenu-popover").removeClass("show");e("body").hasClass("hu-modal-open")&&e(document).closeModal()}})),e(document).off("keyup"),e(".reload-preview-iframe").on("click",(function(t){t.preventDefault();let i=this;l(),e(this).addClass("spin"),n.addEventListener("load",(function(){e(i).removeClass("spin")}))})),e(".hu-topbar").tooltip({classes:{"ui-tooltip":"ui-corner-all"},position:{my:"left top+8px"},hide:!1,show:!1}),e(".action-reset-drafts, .reload-preview-iframe").tooltip({classes:{"ui-tooltip":"ui-corner-all"},position:{my:"left top+10px"},hide:!1,show:!1}),Joomla.helixLoading=function(t,i){const a=e(".hu-loading-msg"),o=e(".hu-done-msg"),n=e(".action-reset-drafts");a.hide(),o.hide(),n.hide(),t?(n.hide(),o.hide(),a.show()):(a.hide(),n.hide(),o.show()),s&&clearTimeout(s),(async()=>{t||await function(e=500){return new Promise((t=>{s=setTimeout(t,e)}))}(2e3),o.hide(),i?n.show():n.hide()})()},e(".hu-menu-builder input[name=megamenu]").on("change",(function(t){t.preventDefault();const i=e(this).closest(".controls"),a=i.data("safepoint"),s=i.data("currpoint"),o=Joomla.utils.helixHash(e(this).val());h(e(this),a,s,o)})),e("form#hu-style-form").find('input[type="text"], input[type="email"], input[type="number"]').on("keydown",(function(e){13!==e.keyCode||e.preventDefault()})),e("form#hu-style-form").find('input[type="text"], input[type="email"], input[type="number"], textarea').on("blur",(function(t){t.preventDefault();let i=e(this).closest(".controls");if(!i.hasClass("field-reset")&&i.hasClass("trackable")){let t=e(this).closest(".controls").data("safepoint"),i=e(this).closest(".controls").data("currpoint"),a=e(this).val();h(e(this),t,i,a)}})),e("form#hu-style-form").find('input[type="checkbox"], input[type=color]').on("change",(function(t){t.preventDefault(),console.log("change fired!");let i=e(this).closest(".controls");if(!i.hasClass("field-reset")&&i.hasClass("trackable")){let t=e(this).closest(".controls").data("safepoint"),i=e(this).closest(".controls").data("currpoint"),a=e(this).prop("checked")?1:0;h(e(this),t,i,a)}})),e("form#hu-style-form").find('select, input[type="hidden"]').on("change",(function(t){t.preventDefault();let i=e(this).closest(".controls");if(!i.hasClass("field-reset")&&i.hasClass("trackable")){let t=e(this).closest(".controls").data("safepoint"),i=e(this).closest(".controls").data("currpoint"),a=e(this).val();h(e(this),t,i,a)}})),e(".action-reset-drafts").on("click",(function(t){t.preventDefault();e(this).hasClass("hide")||(!function(){let t=e("form#hu-style-form").find(".controls.helix-input-touched");t.length>0&&t.each(((t,i)=>{e(i).hasClass("field-reset")||e(i).addClass("field-reset")}))}(),window.confirm("Do you really want to reset your settings?")&&(e("#layout").val(JSON.stringify(m())),f(),e(".hu-input-preset").val(JSON.stringify(e(".hu-preset.active").data())),e.ajax({type:"GET",url:"index.php?option=com_ajax&request=task&helix=ultimate&id="+helixUltimateStyleId+"&action=reset-drafted-settings&format=json&helix_id="+helixUltimateStyleId,success:function(t){if(e.parseJSON(t).status){document.getElementById("hu-template-preview");l()}},error:function(e){console.error("error",e)},complete:function(){!function(){let t=e("form#hu-style-form").find(".controls.helix-input-touched.field-reset");t.length>0&&t.each((function(t,a){let s=e(a);if(s.length>0){let t=s.data("safepoint"),a=s.data("selector"),o=s.find(a);if(o.length>0){let i=void 0!==o.attr("type")&&o.attr("type").toLowerCase();if(i&&"checkbox"===i){let e=1==t;o.prop("checked",e)}"megamenu"===o.attr("name")&&e(".hu-megamenu-action-tracker").val("restore").trigger("change"),"megamenu"!==o.attr("name")&&(o.val(t),o.attr("value",t),o.change()),s.attr("data-currpoint",t),s.data("currpoint",t),"select"===o.prop("tagName").toLowerCase()&&s.find(a+"_chzn").length>0&&(o.trigger("liszt:updated"),o.trigger("chosen:updated"))}let n=s.find(".hu-image-holder img");n.length>0&&n.attr("src",`${i.base}/${t}`),s.find(".hu-header-item").each((function(){e(this).hasClass("active")&&e(this).removeClass("active"),e(this).data("style")===t&&e(this).addClass("active")})),s.removeClass("helix-input-touched"),s.removeClass("field-reset")}}))}(),Joomla.HelixToaster.success("Successfully rolled back to the previous state!","Success"),e(".hu-loading-msg").hide(),e(".hu-done-msg").hide(),e(".action-reset-drafts").hide()}})))})),e(".action-save-template").on("click",Joomla.utils.debounce((function(t){t.preventDefault();c(!0),s&&clearTimeout(s),e("#layout").val(JSON.stringify(m())),f(),e(".hu-input-preset").val(JSON.stringify(e(".hu-preset.active").data()));e(this).data("id"),e(this).data("view");const i=e("#hu-style-form").find("input, select, textarea").not(".internal-use-only").serializeArray();e.ajax({type:"POST",url:"index.php?option=com_ajax&request=task&helix=ultimate&id="+helixUltimateStyleId+"&action=save-tmpl-style&format=json&helix_id="+helixUltimateStyleId,data:i,success:function(t){if(e.parseJSON(t).status){document.getElementById("hu-template-preview").contentWindow.location.reload(!0)}!function(){let t=e("form#hu-style-form").find(".controls.helix-input-touched");t.length>0&&t.each((function(t,i){let a=e(i);if(a.length>0){let e=a.data("selector"),t=a.find(e);t.length>0&&t.attr("value",t.val()),a.attr("data-setvalue",t.val()),a.data("setvalue",t.val()),a.removeClass("helix-input-touched")}}))}()},complete(){Joomla.HelixToaster.success("Changes have been successfully saved!","Success"),e(".hu-loading-msg").hide(),e(".hu-done-msg").hide(),e(".action-reset-drafts").hide(),c(!1)},error:function(e){console.error("error",e),Joomla.HelixToaster.error("Error: "+e.message,"Error"),c(!1)}})}),500)),e(".hu-device").on("click",(function(t){t.preventDefault();const i=e(this).data("device");e(this).parent().find(".active").removeClass("active"),e(this).addClass("active"),d(i)})),u({name:"logo_height",parent:".group-style-logo",map:{desktop:"md",tablet:"sm",mobile:"xs"},device:"desktop"}),e("#hu-style-form").find('input[type="checkbox"]:not(.hu-menu-item-selector)').each((function(){e(this).closest(".control-group").addClass("control-group-checkbox")})),e(".hu-options-core").draggable({iframeFix:!0,cursor:"grabbing",handle:".hu-panel-handle",containment:"#helix-ultimate",drag:function(e,t){a.setItem("toolbarPosition",JSON.stringify(t.position)),p()}}),e(".hu-fieldset-header").on("click",(function(t){t.preventDefault();let i=e(this).data("fieldset");if(e("."+i+"-panel").hasClass("active-panel"))return e("."+i+"-panel").removeClass("active-panel"),void e(this).removeClass("active");e("."+i+"-panel").parent().find(".active-panel").removeClass("active-panel"),e("."+i+"-panel").addClass("active-panel"),e(this).parents("#hu-options").find(".hu-fieldset .hu-fieldset-header").hasClass("active")&&e(this).parents("#hu-options").find(".hu-fieldset .hu-fieldset-header").removeClass("active"),e(this).addClass("active"),p(),Joomla.utils.calculateSiblingDistances()})),e(".hu-panel-close").on("click",(function(t){t.preventDefault(),e(this).closest(".hu-edit-panel").hasClass("active-panel")&&e(this).closest(".hu-edit-panel").removeClass("active-panel");let i=e(`.${e(this).data("sidebarclass")} .hu-fieldset-header`);i.hasClass("active")&&i.removeClass("active")})),e(".hu-fieldset-toggle-icon").on("click",(function(t){t.preventDefault(),e(".hu-fieldset").removeClass("active"),e("#hu, #hu-options").removeClass()})),e(".hu-group-header-box").on("click",(function(t){t.preventDefault();let i=e(this).closest(".hu-edit-panel").find(".hu-group-wrap").find(".hu-field-list.active-group");if(i.length>0){i.data("uid")!==e(this).next().data("uid")&&(i.removeClass("active-group"),i.parent().removeClass("active"),i.slideUp(400))}let a=e(this).next();a.hasClass("active-group")?(e(this).parent().removeClass("active"),a.removeClass("active-group"),a.slideUp(400)):(a.addClass("active-group"),e(this).parent().addClass("active"),a.slideDown(400))})),e(".hu-header-item").on("click",(function(t){t.preventDefault();var i=e(this).closest(".hu-header-list");i.find(".hu-header-item").removeClass("active"),e(this).addClass("active");var a=e(this).data("style"),s=i.data("name");e("#"+s).val(a).trigger("change")})),e(".hu-offcanvas-item").on("click",(function(t){t.preventDefault();var i=e(this).closest(".hu-offcanvas-list");i.find(".hu-offcanvas-item").removeClass("active"),e(this).addClass("active");var a=e(this).data("style"),s=i.data("name");e("#"+s).val(a).trigger("change")})),e(document).ready((function(){"checked"==e("#custom_style").attr("checked")?e(".hu-fieldset-presets").find(".hu-group-wrap").show():e(".hu-fieldset-presets").find(".hu-group-wrap").hide()})),e(document).on("change","#custom_style",(function(t){t.preventDefault(),"checked"==e(this).attr("checked")?e(".hu-fieldset-presets").find(".hu-group-wrap").slideDown():e(".hu-fieldset-presets").find(".hu-group-wrap").slideUp()})),e(document).on("click",".hu-preset",(function(t){t.preventDefault(),e(".hu-preset").removeClass("active"),e(this).addClass("active"),r()})),e(".helix-responsive-devices span").click((function(){if(e(this).hasClass("active"))return;const t=e(this).parents(".hu-webfont-size");t.find("input").removeClass("active");const i=e(this).data("active_class");t.find(i).addClass("active"),e(this).parent().find("span.active").removeClass("active"),e(this).addClass("active");d(e(this).data("device"))})),window.purgeCss=function(t=null){e.ajax({type:"POST",url:"index.php?option=com_ajax&request=task&helix=ultimate&id="+helixUltimateStyleId+"&action=purge-css-file&format=json&helix_id="+helixUltimateStyleId,data:{},beforeSend:function(){t&&t.append('')},success:function(i){var a=e.parseJSON(i);t&&a.status&&(t.find("span").remove(),t.removeClass("disable"))},error:function(){alert("Somethings wrong, Try again")}})},e(".btn-purge-hu-css").on("click",(function(t){t.preventDefault();var i=e(this);i.hasClass("disable")||(i.addClass("disable"),window.purgeCss(i))})),e("#btn-hu-import-settings").on("click",(function(t){t.preventDefault(),e("#helix-import-file").click()})),e("#helix-import-file").on("change",(function(t){const i=new FileReader;i.onload=function(t){JSON.parse(t.target.result);var i={action:"import-tmpl-style",option:"com_ajax",helix:"ultimate",request:"task",data:{settings:t.target.result},format:"json"};return e.ajax({type:"POST",data:i,success:function(t){e.parseJSON(t).status&&window.location.reload()},complete(){Joomla.HelixToaster.success("Settings have been successfully imported!","Success")},error:function(){Joomla.HelixToaster.error("Something went wrong importing settings!","Error")}}),!1},i.readAsText(t.target.files[0])})),e(".hu-help-icon").on("click",(function(t){t.preventDefault();let i=e(this).closest(".control-group").find(".hu-control-help");e(this).toggleClass("active"),i.hasClass("show")?(i.removeClass("show"),i.slideUp(100)):(i.addClass("show"),i.slideDown(100)),e(this).closest(".control-group").siblings().each((function(){let t=e(this).find(".hu-control-help");t.hasClass("show")&&(t.removeClass("show"),t.slideUp(100))}))})),e(document).on("click",".hu-option-group-title",(function(t){t.preventDefault(),e(this).closest(".hu-option-group").toggleClass("active").siblings().removeClass("active")}));let v={};function g(){e(".hu-group-wrap").each((function(){if(e(this).attr("data-dependon")){let t=e(this).data("dependon"),[i,a]=t.split(":"),s=e(`[name=${i}]`),o=s.val();"checkbox"===s.prop("type")&&(o=s.prop("checked"),a=1==a),o==a?e(this).fadeIn(300):e(this).fadeOut(300),v[i]=s}}))}g(),Object.values(v).forEach((function(e){e.on("change",(function(e){e.preventDefault(),g()}))})),function(){let t=e(".hu-field-dimension-width"),i=e(".hu-field-dimension-height");t.on("keyup",(function(t){t.preventDefault();let i=e(this).closest(".controls").find(".hu-field-dimension-input"),a=i.val()||"0x0",s=e(this).val(),[o,n]=a.toLowerCase().split("x");""===s&&(s="0"),o=s,a=`${o}x${n}`,i.val(a)})),i.on("keyup",(function(t){t.preventDefault();let i=e(this).closest(".controls").find(".hu-field-dimension-input"),a=i.val()||"0x0",s=e(this).val(),[o,n]=a.toLowerCase().split("x");""===s&&(s="0"),n=s,a=`${o}x${n}`,i.val(a)}))}();let y=[];function w(){e(".control-group[data-enableon]").each((function(){let[t,i]=e(this).data("enableon").split(":"),a=e(`[name=${t}]`);y.push(a);let s=a.val();"checkbox"===a.prop("type")&&(s=a.prop("checked"),i=1==i),s==i?(e(this).find("input, select, textarea").prop("readonly",!1),e(this).hasClass("uneditable")&&e(this).removeClass("uneditable")):(e(this).find("input, select, textarea").prop("readonly",!0),e(this).hasClass("uneditable")||e(this).addClass("uneditable"))}))}w(),y.forEach((function(e){e.on("change",(function(){w()}))})),e(".hu-switcher .hu-action-group [hu-switcher-action]").on("click",(function(t){let i=e(this).data("value");e(this).siblings().removeClass("active"),e(this).addClass("active"),e(this).closest(".hu-switcher").find("input[type=hidden]").val(i).trigger("change");const a=t.target.closest(".hu-switcher").querySelector("input[type=hidden]");Joomla.utils.triggerEvent(a,"change")}))}));PK!d~NN-system/helixultimate/assets/js/admin/media.jsnu[/** * @package Helix Ultimate Framework * @author JoomShaper https://www.joomshaper.com * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ jQuery((function(e){e(".hu-media-picker").on("click",(function(a){a.preventDefault();var t=this,i="id",o="";void 0!==e(this).data("id")?(i="id",o=e(this).data("id")):void 0!==e(this).data("target")&&(i="data",o=e(this).data("target")),e(this).helixUltimateModal({target_type:i,target:o});e.ajax({type:"POST",data:{action:"view-media",option:"com_ajax",helix:"ultimate",request:"task",format:"json"},beforeSend:function(){e(t).find(".fa").removeClass("fa-picture-o").addClass("fa-spinner fa-spin")},success:function(a){var i=e.parseJSON(a);e(t).find(".fa").removeClass("fa-spinner fa-spin").addClass("fa-picture-o"),i.status?(e(".hu-modal-breadcrumbs").html(i.breadcrumbs),e(".hu-modal-inner").html(i.output)):(e(".hu-modal-overlay, .hu-modal").remove(),e("body").addClass("hu-modal-open"),alert(i.output))},error:function(){alert("Somethings wrong, Try again")}})})),e(document).on("dblclick",".hu-media-folder",(function(a){a.preventDefault();var t={action:"view-media",option:"com_ajax",helix:"ultimate",request:"task",path:e(this).data("path"),format:"json"};e.ajax({type:"POST",data:t,beforeSend:function(){e(".hu-media-selected").removeClass("hu-media-selected"),e(".hu-modal-actions-left").hide(),e(".hu-modal-actions-right").show(),e(".hu-modal-inner").html('
    ')},success:function(a){var t=e.parseJSON(a);t.status?(e(".hu-modal-breadcrumbs").html(t.breadcrumbs),e(".hu-modal-inner").html(t.output)):alert(t.output)},error:function(){alert("Somethings wrong, Try again")}})})),e(document).on("click",".hu-media-breadcrumb-item > a",(function(a){a.preventDefault();var t={action:"view-media",option:"com_ajax",helix:"ultimate",request:"task",path:e(this).data("path"),format:"json"};e.ajax({type:"POST",data:t,beforeSend:function(){e(".hu-modal-inner").html('
    ')},success:function(a){var t=e.parseJSON(a);t.status?(e(".hu-modal-breadcrumbs").html(t.breadcrumbs),e(".hu-modal-inner").html(t.output)):alert(t.output)},error:function(){alert("Somethings wrong, Try again")}})})),e(document).on("click",".hu-media-folder, .hu-media-image",(function(a){a.preventDefault(),e(".hu-media-selected").removeClass("hu-media-selected"),e(this).addClass("hu-media-selected"),e(this).hasClass("hu-media-folder")?e(".hu-modal-action-select").hide():e(".hu-modal-action-select").removeAttr("style"),e(".hu-modal-actions-left").show(),e(".hu-modal-actions-right").hide()})),e(document).on("click",".hu-modal-action-select",(function(a){a.preventDefault();var t=e(".hu-media-selected").data("path"),i=e(".hu-media-selected").data("preview"),o=e(".hu-modal").attr("data-target");if("data"==e(".hu-modal").attr("data-target_type")){e(".hu-options-modal").find('[data-attrname="'+o+'"]').val(t).trigger("change");const a=document.querySelector(`.hu-options-modal [data-attrname=${o}]`);Joomla.utils.triggerEvent(a,"change"),e(".hu-options-modal").find('[data-attrname="'+o+'"]').prev(".hu-image-holder").html('');let d=e(".hu-options-modal").find('[data-attrname="'+o+'"]').siblings(".hu-media-clear");d.hasClass("hide")&&d.removeClass("hide")}else{e("#"+o).val(t).trigger("change"),Joomla.utils.triggerEvent(document.querySelector(`#${o}`),"change"),e("#"+o).prev(".hu-image-holder").html('');let a=e("#"+o).siblings(".hu-media-clear");a.hasClass("hide")&&a.removeClass("hide")}e(".hu-modal-overlay, .hu-modal").remove(),e("body").removeClass("hu-modal-open")})),e(document).on("click",".hu-modal-action-cancel",(function(a){a.preventDefault(),e(".hu-media-selected").removeClass("hu-media-selected"),e(".hu-modal-actions-left").hide(),e(".hu-modal-actions-right").show()})),e(document).on("click",".action-hu-modal-close",(function(a){a.preventDefault(),e(".hu-modal-overlay, .hu-modal").remove(),e("body").removeClass("hu-modal-open")})),e(document).on("click",".hu-media-clear",(function(a){a.preventDefault(),e(this).parent().find("input").val("").trigger("change"),Joomla.utils.triggerEvent(a.target.parentNode.querySelector("input"),"change"),e(this).parent().find(".hu-image-holder").empty(),e(this).hasClass("hide")||e(this).addClass("hide")})),e(document).on("click",".hu-modal-action-delete",(function(a){a.preventDefault();var t="file";if(e(".hu-media-selected").length){if(t=e(".hu-media-selected").hasClass("hu-media-folder")?"folder":"file",confirm("Are you sure you want to delete this "+t+"?")){var i={action:"delete-media",option:"com_ajax",helix:"ultimate",request:"task",type:t,path:e(".hu-media-selected").data("path"),format:"json"};e.ajax({type:"POST",data:i,success:function(a){var t=e.parseJSON(a);t.status?(e(".hu-media-selected").remove(),e(".hu-modal-actions-left").hide(),e(".hu-modal-actions-right").show()):alert(t.message)},error:function(){alert("Somethings wrong, Try again")}})}}else alert("Please select a file or directory first to delete.")})),e(document).on("click",".hu-modal-action-new-folder",(function(a){a.preventDefault();var t=prompt("Please enter the name of the directory which should be created.");if(null==t||""==t);else{var i={action:"create-folder",option:"com_ajax",helix:"ultimate",request:"task",folder_name:t,path:e(".hu-media-breadcrumb-item.active").data("path"),format:"json"};e.ajax({type:"POST",data:i,success:function(a){var t=e.parseJSON(a);t.status?e(".hu-modal-inner").html(t.output):alert(t.message)},error:function(){alert("Somethings wrong, Try again")}})}})),e.fn.uploadMedia=function(a){a=e.extend({data:"",index:""},a);e.ajax({type:"POST",url:"index.php?option=com_ajax&helix=ultimate&request=task&action=upload-media&format=json&helix_id="+helixUltimateStyleId,data:a.data,contentType:!1,cache:!1,processData:!1,beforeSend:function(){var t='
  • ';t+='
    ',t+='
    ',t+="
    ",t+='
    Uploading...
    ',t+="
  • ",e("#hu-media-manager").animate({scrollTop:e("#hu-media-manager").prop("scrollHeight")},1e3),e(".hu-media").append(t)},success:function(t){var i=e.parseJSON(t);i.status?e("."+a.index).removeClass().addClass("hu-media-image").attr("data-path",i.path).attr("data-preview",i.src).html(i.output):(e("."+a.index).remove(),alert(i.message))},xhr:function(){return myXhr=e.ajaxSettings.xhr(),myXhr.upload?myXhr.upload.addEventListener("progress",(function(t){e("."+a.index).find(".hu-progress-bar").css("width",Math.floor(t.loaded/t.total*100)+"%"),e("."+a.index).find(".hu-media-upload-percentage").text(Math.floor(t.loaded/t.total*100)+"% ")}),!1):alert("Uploadress is not supported."),myXhr}})},e(document).on("click",".hu-modal-action-upload",(function(a){a.preventDefault(),e("#hu-file-input").click()})),e(document).on("change","#hu-file-input",(function(a){a.preventDefault();var t=e(this),o=e(this).prop("files");for(i=0;i
    '+u+"
    ";n.item.removeAttr("style class").addClass("hu-megamenu-item").html(o),n.item.clone().insertAfter(n.item.html(' '+u).removeAttr("class").addClass("hu-megamenu-draggable-module")),e(this).sortable("cancel"),a()}}).disableSelection(),e(".hu-megamenu-row").sortable({start:function(e,a){a.placeholder.height(a.item.height()),a.placeholder.width(a.item.width()-50)},items:".hu-megmenu-col",handle:".hu-action-move-column",placeholder:"drop-col-highlight",stop:function(e,a){}}),e("#hu-megamenu-layout").sortable({start:function(e,a){a.placeholder.height(a.item.height()),a.placeholder.width(a.item.width()-50)},items:".hu-megamenu-row",handle:".hu-action-move-row",placeholder:"drop-highlight",stop:function(e,a){}}),e(document).on("click",".hu-megamenu-remove-module",(function(a){a.preventDefault(),e(this).closest(".hu-megamenu-item").remove()}))}e("#attrib-helixultimatemegamenu").find(".control-group").first().find(".control-label").remove(),e("#attrib-helixultimatemegamenu").find(".control-group").first().find(">.controls").removeClass().addClass("megamenu").unwrap(),e(document).on("click","#hu-megamenu-toggler",(function(a){var t=e(this).is(":checked");e("#hu-megamenu-layout").data("megamenu",t),t?(e(".hu-megamenu-field-control, .hu-megamenu-sidebar").removeClass("hide-menu-builder"),e(".hu-dropdown-field-control").addClass("hide-menu-builder")):(e(".hu-megamenu-field-control, .hu-megamenu-sidebar").addClass("hide-menu-builder"),e(".hu-dropdown-field-control").removeClass("hide-menu-builder"))})),e(document).on("change","#hu-megamenu-width",(function(a){e("#hu-megamenu-layout").data("width",e(this).val())})),e(document).on("change","#hu-megamenu-alignment",(function(a){e("#hu-megamenu-layout").data("menualign",e(this).val())})),e(document).on("click","#hu-megamenu-title-toggler",(function(a){e("#hu-megamenu-layout").data("showtitle",e(this).is(":checked"))})),e(document).on("change","#hu-megamenu-dropdown",(function(a){e("#hu-megamenu-layout").data("dropdown",e(this).val())})),e(document).on("change","#hu-megamenu-fa-icon",(function(a){e("#hu-megamenu-layout").data("faicon",e(this).val())})),e(document).on("change","#hu-megamenu-custom-class",(function(a){e("#hu-megamenu-layout").data("customclass",e(this).val())})),e(document).on("change","#hu-megamenu-menu-badge",(function(a){e("#hu-megamenu-layout").data("badge",e(this).val())})),e(document).on("change","#hu-megamenu-badge-position",(function(a){e("#hu-megamenu-layout").data("badge_position",e(this).val())})),e(document).on("change","#hu-menu-badge-bg-color",(function(a){e("#hu-megamenu-layout").data("badge_bg_color",e(this).val())})),e(document).on("change","#hu-menu-badge-text-color",(function(a){e("#hu-megamenu-layout").data("badge_text_color",e(this).val())})),document.adminForm.onsubmit=function(a){var t=[];e("#hu-megamenu-layout").find(".hu-megamenu-row").each((function(a){var n=e(this),u=a;t[u]={type:"row",attr:[]},n.find(".hu-megmenu-col").each((function(a){var n=e(this),o=a,i=n.attr("data-grid");t[u].attr[o]={type:"column",colGrid:i,menuParentId:"",moduleId:"",items:[]};var m="";n.find("h4").each((function(a,t){m+=e(this).data("current_child")+","})),m&&(m=m.slice(",",-1),t[u].attr[o].menuParentId=m);var l="";n.find(".hu-megamenu-item").each((function(a,n){l+=e(this).data("mod_id")+",";var i=e(this).data("type"),m=e(this).data("mod_id");t[u].attr[o].items[a]={type:i,item_id:m}})),l&&(l=l.slice(",",-1),t[u].attr[o].moduleId=l)}))}));var n=e("#hu-megamenu-layout").data(),u={width:n.width||"0",menuitem:n.menuitem,menualign:n.menualign,megamenu:n.megamenu,showtitle:n.showtitle,faicon:n.faicon,customclass:n.customclass,dropdown:n.dropdown,badge:n.badge,badge_position:n.badge_position,badge_bg_color:n.badge_bg_color,badge_text_color:n.badge_text_color,layout:t};e("#jform_params_helixultimatemenulayout").val(JSON.stringify(u))},e(document).on("click","#hu-choose-megamenu-layout",(function(a){a.preventDefault(),e("#hu-megamenu-layout-modal").toggle()})),e(document).on("click",".hu-megamenu-grids",(function(t){t.preventDefault();var n=e(this).attr("data-layout"),u='
    ';u+='
    ',u+='
    ',u+=' Row',u+="
    ",u+='',u+="
    ",u+='
    ';var o='
    ';o+='
    ',o+='
    ',o+=' Column',o+="
    ",o+='
    ',o+="
    ",o+="
    ";var m="";if(12!=n){var l=n.split("+");for(i=0;i",u+="
    ",e("#hu-megamenu-layout").append(u),e(this).closest("#hu-megamenu-layout-modal").hide(),a()})),a(),e(document).on("click",".hu-action-detele-row",(function(a){a.preventDefault(),e(this).closest(".hu-megamenu-row").remove()}))}));PK!f /system/helixultimate/assets/js/admin/presets.jsnu[/** * @package Helix Ultimate Framework * @author JoomShaper https://www.joomshaper.com * Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ jQuery((function(e){let t=e(".hu-presets #presets-data"),a=e(".hu-presets .hu-preset"),s=t.val();function n(n,o,r,l){s[o].data=n,console.log(n),t.val(JSON.stringify(s)),a.each((function(){let t=this;e(this).data("preset")===o&&Object.entries(n).forEach((function([a,s]){e(t).attr(`data-${a}`,s),e(t).data(a,s)}))})),r.html(l.find("> div")),window.purgeCss(),e(".hu-options-modal-overlay, .hu-options-modal").remove(),e("body").removeClass("hu-options-modal-open");let i=function(e){let t=Object.values(e).reduce((function(e,t){return e[t]=(e[t]||0)+1,e}),{}),a=0;return Object.entries(t).reduce((function(e,[t,s]){return s>=a&&(a=s,e=t),e}),"")}(n),u=e(`.hu-preset[data-preset=${o}]`);u.css({"background-color":i}),u.find(".hu-edit-preset").css({color:i}),e(`.hu-preset[data-preset=${o}]`).click()}"string"==typeof s&&s.length&&(s=JSON.parse(s)),e(document).on("click",".hu-edit-preset",(function(t){t.preventDefault(),t.stopPropagation();let a=e(this).data("preset_data")||"",{name:s,data:o}=a,r=e(`.hu-preset-container#${s}`),l=r.clone(!0);l.each((function(){e(this).find("input").removeAttr("id")})),e(this).helixUltimateOptionsModal({flag:"edit-presets",title:` Edit Preset: ${s}`,class:`hu-modal-small edit-preset-modal modal-${s}`,applyBtnClass:"hu-save-preset",footerButtons:[' Reset to Default']}),e(".hu-options-modal-inner").html(l.removeAttr("id").removeAttr("style").addClass("hu-options-modal-content")),l.find("input.preset-control").each((function(){e(this).on("change",(function(t){t.preventDefault();let a=e(this).attr("name"),s=e(this).val();o[a]=s}))}));let i=e(`.edit-preset-modal.modal-${s}`).find(".hu-save-preset"),u=e(`.edit-preset-modal.modal-${s}`).find(".helix-preset-reset");i.length&&(i.on("click",(function(e){e.preventDefault(),n(o,s,r,l)})),u.on("click",(function(t){if(t.preventDefault(),window.confirm("Do you really want to reset your changes to default?")){n(JSON.parse(e("#default-values").val())[s],s,r,l)}})))}))}));PK!45system/helixultimate/assets/js/admin/devices-field.jsnu[jQuery(document).ready((function(e){let t=e(".helix-field"),i=t.find("input"),a=Joomla.getOptions("data")||{};t.length>0&&t.find(".helix-devices .device-btn").on("click",(function(d){d.preventDefault();let l=e(this).data("device");!function(t){const i={lg:"100%",md:`${a.breakpoints.tablet}px`,sm:`${a.breakpoints.mobile}px`},d={md:"desktop",sm:"tablet",xs:"mobile",desktop:"desktop",tablet:"tablet",mobile:"mobile"};e(`.hu-device[data-device=${d[t]}]`).parent().find(".active").removeClass("active"),e(`.hu-device[data-device=${d[t]}]`).addClass("active");e("#hu-template-preview").animate({width:i[t]},500,"linear")}(l),i.val(l).trigger("change"),t.find(".helix-devices .device-btn").each((function(){e(this).hasClass("active")&&e(this).removeClass("active")})),e(this).addClass("active")}))}));PK!z_L4system/helixultimate/assets/js/admin/blog-options.jsnu[/** * @package Helix Ultimate Framework * @author JoomShaper https://www.joomshaper.com * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ jQuery((function(a){a(document).ready((function(){var e=a("#myTabTabs").find(">li").first();a('a[href="#attrib-helix_ultimate_blog_options"]').parent().insertAfter(e)})),a(".hu-image-field").each((function(e,t){var i=a(t);i.find(".btn-hu-image-upload").on("click",(function(a){a.preventDefault(),i.find(".hu-image-upload").click()})),i.find(".hu-image-upload").on("change",(function(e){e.preventDefault();var t=a(this),l=a(this).prop("files")[0],r=new FormData;r.append("option","com_ajax"),r.append("helix","ultimate"),r.append("request","task"),r.append("action","upload-blog-image"),r.append("format","json"),l.type.match(/image.*/)&&(r.append("image",l),a.ajax({type:"POST",data:r,contentType:!1,cache:!1,processData:!1,beforeSend:function(){t.prop("disabled",!0),i.find(".btn-hu-image-upload").attr("disabled","disabled");var e=a('
    ');i.find(".hu-image-upload-wrapper").addClass("loading").html(e)},success:function(e){var l=a.parseJSON(e);l.status?i.find(".hu-image-upload-wrapper").removeClass("loading").empty().html(l.output):i.find(".hu-image-upload-wrapper").removeClass("loading").empty();var r=i.find(".hu-image-upload-wrapper").find(">img");r.length?(a(".hu-image-field").removeClass("hu-image-field-empty").addClass("hu-image-field-has-image"),i.find("#jform_attribs_helix_ultimate_image").val(r.data("src"))):(a(".hu-image-field").removeClass("hu-image-field-has-image").addClass("hu-image-field-empty"),i.find("#jform_attribs_helix_ultimate_image").val("")),t.val(""),t.prop("disabled",!1),i.find(".btn-hu-image-upload").removeAttr("disabled")},xhr:function(){return myXhr=a.ajaxSettings.xhr(),myXhr.upload?myXhr.upload.addEventListener("progress",(function(e){a("#upload-image-progress").find(".bar").css("width",Math.floor(e.loaded/e.total*100)+"%")}),!1):alert("Uploadress is not supported."),myXhr},error:function(){i.find(".hu-image-upload-wrapper").empty(),t.val("")}})),t.val("")}))})),a(document).on("click",".btn-hu-image-remove",(function(e){e.preventDefault();var t=a(this).closest(".hu-image-field");if(1==confirm("You are about to delete this item permanently. 'Cancel' to stop, 'OK' to delete.")){var i={option:"com_ajax",helix:"ultimate",request:"task",action:"remove-blog-image",src:t.find(".sp-image-upload-wrapper").find(">img").data("src"),format:"json"};a.ajax({type:"POST",data:i,success:function(e){var i=a.parseJSON(e);i.status?(t.find(".hu-image-upload-wrapper").empty(),a(".hu-image-field").removeClass("hu-image-field-has-image").addClass("hu-image-field-empty"),t.find("#jform_attribs_helix_ultimate_image").val("")):alert(i.output)}})}})),a(".btn-hu-gallery-item-upload").on("click",(function(e){e.preventDefault(),a("#hu-gallery-item-upload").click()})),a("#hu-gallery-item-upload").on("change",(function(e){e.preventDefault();var t=a(this),l=a(this).prop("files");Joomla.getOptions("system.paths");for(i=0;i
    ');a(".hu-gallery-items").append(t)},success:function(t){var i=a.parseJSON(t);i.status?a("#"+e).attr("data-src",i.data_src).removeClass("loading").empty().html(i.output):(a("#"+e).remove(),alert(i.output));let l=[];a(".hu-gallery-items").find(">.hu-gallery-item").each((function(e,t){l.push('"'+a(t).data("src")+'"')}));let r='{"helix_ultimate_gallery_images":['+l+"]}";a("#jform_attribs_helix_ultimate_gallery").val(r)},xhr:function(){return myXhr=a.ajaxSettings.xhr(),myXhr.upload?myXhr.upload.addEventListener("progress",(function(t){a("#"+e).find(".bar").css("width",Math.floor(t.loaded/t.total*100)+"%")}),!1):console.log("Uploadress is not supported."),myXhr}})}}t.val("")})),a(".hu-gallery-items").sortable({stop:function(e,t){let i=[];a(".hu-gallery-item").each((function(e,t){i.push('"'+a(t).data("src")+'"')}));let l='{"helix_ultimate_gallery_images":['+i+"]}";a("#jform_attribs_helix_ultimate_gallery").val(l)}}),a(document).on("click",".btn-hu-remove-gallery-image",(function(e){e.preventDefault();var t=a(this);if(1==confirm("You are about to delete this item permanently. 'Cancel' to stop, 'OK' to delete.")){var i={option:"com_ajax",helix:"ultimate",request:"task",action:"remove-blog-image",src:t.parent().data("src"),format:"json"};a.ajax({type:"POST",data:i,success:function(e){var i=a.parseJSON(e);if(i.status){t.parent().remove();let e=[];a(".hu-gallery-item").each((function(t,i){e.push('"'+a(i).data("src")+'"')}));let i='{"helix_ultimate_gallery_images":['+e+"]}";a("#jform_attribs_helix_ultimate_gallery").val(i)}else alert(i.output)}})}}))}));PK!)r**/system/helixultimate/assets/js/admin/details.jsnu[/** * @package Helix Ultimate Framework * @author JoomShaper https://www.joomshaper.com * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ jQuery((function(o){o(".hu-options").unwrap(),o(".hu-options").prev().remove()}));PK!{0system/helixultimate/assets/images/select-bg.svgnu[ PK!d^:system/helixultimate/assets/images/helix-ultimate-logo.svgnu[ PK!" .system/helixultimate/assets/images/favicon.iconu[PNG  IHDRasRGB pHYs  $iTXtXML:com.adobe.xmp 2 5 72 1 72 16 1 16 2015:03:15 13:03:46 Pixelmator 3.3.1 >Iv]XIDAT8}]h\Eϙ{wﺻI]mXClK4REw-E(->f|)y~(Z"ȢARhZB46M-$ӆ6&-k41cxnS\sg;^t}Pc{յ ׽uQ{VJ5"I":X7O)): L;j8lQP %!럒|2qy e4m m <3@!$+c粒Jۤ-SRHkA8$k )[O/ov,6˔}O0| n NҀF{Ӂ{ǽLK){|G ʭ"W?X-YW~Rn2˰o. x*S߇Kê: 4`DFoԝ.(Y&pKqѵXn9bbn|ccNݛZĴ&ܖۑtBTrj]ޱ*Sxqdw? p|n)3^E8Y⑷g"rU`WnAO5?HlpY[Q8+]rqoޱetj Z GO\}r7wَCV6tb70j#Ū!_WH+RF&/Ϗj.9WxZA!/W> `[X;GPw6VR{4weWD0ΑhLȣ %JЛz=i ZϰŠQ^"O:58՛k~hl`MǽSqV1DZmhbwyuKo;DS(IENDB`PK!.N /system/helixultimate/assets/images/icon-res.svgnu[ PK!PU  >system/helixultimate/assets/images/helix-ultimate-logo-alt.svgnu[ PK!1(ۣ 2system/helixultimate/assets/images/icons/basic.svgnu[ PK!52system/helixultimate/assets/images/icons/close.svgnu[ PK!y 4system/helixultimate/assets/images/icons/advance.svgnu[PK!11Q7system/helixultimate/assets/images/icons/typography.svgnu[ PK!v``1system/helixultimate/assets/images/icons/blog.svgnu[ PK!s)@@1system/helixultimate/assets/images/icons/menu.svgnu[ PK!h/4system/helixultimate/assets/images/icons/presets.svgnu[ PK!Ņ1system/helixultimate/assets/images/icons/bars.svgnu[ PK!1system/helixultimate/assets/images/icons/save.svgnu[ PK!y;system/helixultimate/assets/images/icons/device-desktop.svgnu[ PK! UX<system/helixultimate/assets/images/icons/image-thumbnail.svgnu[PK!y :system/helixultimate/assets/images/icons/licenseupdate.svgnu[PK!Q3system/helixultimate/assets/images/icons/layout.svgnu[ PK!4Ncc8system/helixultimate/assets/images/icons/image-large.svgnu[PK!#bb:system/helixultimate/assets/images/icons/device-mobile.svgnu[ PK!+;8system/helixultimate/assets/images/icons/custom_code.svgnu[ PK! EE:system/helixultimate/assets/images/icons/device-tablet.svgnu[ PK!y 5system/helixultimate/assets/images/icons/advanced.svgnu[PK!\9system/helixultimate/assets/images/icons/image-medium.svgnu[PK!x8system/helixultimate/assets/images/icons/image-small.svgnu[PK!KZ4system/helixultimate/assets/images/select-bg-rtl.svgnu[ PK!}=system/helixultimate/assets/images/mega-menu-color-select.jpgnu[JFIF     &""&0-0>>T     &""&0-0>>T." K5T֮UI=j;uWNјOCb>TshQ#+`יN|M23M$(k[#ٌ4B=uUӆfPػp6κT3 l]_U]8j\4&Fu GMM /4Ts!5D"1Q ?3ˣ!vnȊe1S9J@"25u=I52s Ɖ<HxD{U>W㋤ZO,C5>9?Uopn4OU h{F#%ڮ_z 1?NLLLjP?PK!(Ii>>>system/helixultimate/layouts/cpanel/control-board/settings.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use Joomla\CMS\Layout\LayoutHelper; extract($displayData); ?>
    $fieldset): ?> $fieldset, 'key' => $key, 'form' => $form], HELIX_LAYOUTS_PATH); ?>
    PK!ӝCsystem/helixultimate/layouts/cpanel/control-board/fieldset/icon.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Uri\Uri; extract($displayData); $iconsrc = Uri::root() . "plugins/system/helixultimate/assets/images/icons/{$fieldset->name}.svg"; ?>
    <?php echo $fieldset->name; ?> label); ?>
    PK!Dsystem/helixultimate/layouts/cpanel/control-board/fieldset/field.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use HelixUltimate\Framework\Platform\Helper; use HelixUltimate\Framework\Platform\Settings; use HelixUltimate\Framework\System\JoomlaBridge; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; extract($displayData); ?> getAttribute('showon'); $attribs = ''; if ($showon) { $attribs .= ' data-showon=\'' . json_encode(Settings::parseShowOnConditions($showon)) . '\''; } $setvalue = ''; if (\is_array($field->value) || \is_object($field->value)) { $setvalue = json_encode($field->value); } else { $setvalue = $field->value; } $track = $field->getAttribute('track'); $hasTrack = true; if (!empty($track)) { $hasTrack = !($track === 'false' || $track === 'off'); } $hideLabel = $field->getAttribute('hideLabel', false); $description = Text::_($field->getAttribute('description', '')); $type = $field->getAttribute('type', 'text'); $multiple = $field->getAttribute('multiple'); $multiple = isset($multiple) && ($multiple === 'true' || $multiple === 'on'); $separator = $field->getAttribute('separator'); $separator = isset($separator) && ($separator === 'true' || $separator === 'on') ? true : false; // Enable disable on $enableOn = $field->getAttribute('enableon', ''); if ($enableOn) { $attribs .= ' data-enableon="' . $enableOn . '"'; } $checkboxStyle = $field->getAttribute('style', 'switch'); $className = $field->getAttribute('className', ''); // Group Class $group_class = (($group) ? 'group-style-' . $group : ''); if ($type === 'checkbox') { $group_class .= ($checkboxStyle === 'plain') ? ' hu-style-checkbox': ' hu-style-switcher'; } $group_class .= $separator ? ' hu-field-separator': ''; $group_class .= !empty($className) ? ' ' . $className : ''; $listStyle = $field->getAttribute('style'); $display = $field->getAttribute('display', ''); $invalidDataFields = ['before_head', 'after_body', 'before_body', 'custom_css', 'custom_js']; $isValidDataField = !\in_array($field->name, $invalidDataFields); ?>
    >
    getAttribute('hideLabel', false)): ?>
    ' data-currpoint='' data-selector="#id; ?>"> input; ?>

    PK!tm||Dsystem/helixultimate/layouts/cpanel/control-board/fieldset/panel.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use Joomla\CMS\Layout\LayoutHelper; extract($displayData); $fields = $form->getFieldset($key); $activeGroup = isset($fieldset->activegroup) ? $fieldset->activegroup : ''; if (!empty($fields)) { $index = 0; foreach ($fields as $i => $field) { $subgroup = $field->getAttribute('helixsubgroup'); $group = $field->getAttribute('helixgroup') ? $field->getAttribute('helixgroup') : 'no-group'; if (isset($subgroup)) { $groups[$group]['subgroup-' . $subgroup][] = $field; } else { $groups[$group][] = $field; } $groups[$group]['isActive'] = false; $groups[$group]['dependent'] = $field->getAttribute('dependant', ''); if ($activeGroup === $group) { $groups[$group]['isActive'] = true; } } } $headerTitle = implode(' ', explode('_', $fieldset->name)); ?>
    $groups, 'fieldset_name' => $fieldset->name], HELIX_LAYOUTS_PATH); ?>
    PK!n /Esystem/helixultimate/layouts/cpanel/control-board/fieldset/groups.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; extract($displayData); ?> $group): ?>
    >
    > $key, 'groupData' => $group], HELIX_LAYOUTS_PATH); ?>
    $key, 'groupData' => $group], HELIX_LAYOUTS_PATH); ?>
    PK!WEsystem/helixultimate/layouts/cpanel/control-board/fieldset/fields.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use HelixUltimate\Framework\Platform\Settings; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; extract($displayData); ?> $data): ?> $data, 'group' => $group], HELIX_LAYOUTS_PATH); ?> getAttribute('masterlabel'); $masterLabel = isset($masterLabel) ? Text::_($masterLabel) : ''; $masterDescription = $data[0]->getAttribute('masterdesc'); $masterDescription = isset($masterDescription) ? Text::_($masterDescription) : ''; $masterClass = $data[0]->getAttribute('masterclass'); $masterClass = isset($masterClass) ? $masterClass : 'row hu-align-items-center'; $masterHasSeparator = $data[0]->getAttribute('masterseparator'); $masterHasSeparator = isset($masterHasSeparator) && ($masterHasSeparator === 'true' || $masterHasSeparator === 'on') ? ' hu-field-separator': ''; ?>

    $field): ?> getAttribute('subclasses'); $classes = isset($classes) ? $classes : 'col'; ?>
    $field, 'group' => $group], HELIX_LAYOUTS_PATH); ?>
    PK!&##5system/helixultimate/layouts/cpanel/editor/topbar.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use HelixUltimate\Framework\Platform\Settings; use HelixUltimate\Framework\Platform\Helper; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; extract($displayData); $app = Factory::getApplication(); // Gets the FrontEnd Main page Uri $frontEndUri = Uri::getInstance(Uri::root()); $frontEndUri->setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); $mainPageUri = $frontEndUri->toString(); $sidebar = new Settings; ?>
    Drafting...
    PK!TԎ7system/helixultimate/layouts/cpanel/editor/controls.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use HelixUltimate\Framework\Platform\Settings; extract($displayData); $sidebar = new Settings; ?>
    renderBuilderControlBoard(); ?>
    PK!H<**0system/helixultimate/layouts/backend/section.phpnu[' ), array( '6+6', '' ), array( '4+4+4', '' ), array( '3+3+3+3', '' ), array( '4+8', '' ), array( '3+9', '' ), array( '3+6+3', '' ), array( '2+6+4', '' ), array( '2+10', '' ), array( '5+7', '' ), array( '2+3+7', '' ) ); $row = $displayData; $rowSettings = ''; if(isset($row->settings)) { $rowSettings = RowColumnSettings::getSettings($row->settings); } $name = Text::_('HELIX_ULTIMATE_SECTION_TITLE'); if (isset($row->settings->name)) { $name = $row->settings->name; } $layout_path = JPATH_ROOT .'/plugins/system/helixultimate/layouts'; $layout_column = new FileLayout('backend.column', $layout_path ); $output = ''; $output .= '
    sectionID) && $row->sectionID)?'id="hu-layout-section"':'').' class="hu-layout-section" ' . $rowSettings .'>'; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= ''; $output .= '' . $name . ''; $output .= '
    '; $output .= '
    '; $output .= '
      '; $output .= '
    • '; $output .= ''; $output .= '
      '; $output .= '
      '; if(!isset($row->layout)){ $row->layout = 12; } $custom = true; foreach ($grids as $grid) { $output .= ''; if($grid[0] == $row->layout) { $custom = false; } } $output .= ''; $output .= '
      '; $output .= ''; $output .= '
      '; $output .= '
    • '; $output .= '
    • '; $output .= '
    • '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; if(isset($row->attr) && $row->attr) { foreach ($row->attr as $column) { $output .= $layout_column->render($column->settings); } } else { $output .= $layout_column->render(new stdClass); } $output .= '
    '; $output .= '
    '; $output .= ''; $output .= '
    '; $output .= '
    '; echo $output;PK!/system/helixultimate/layouts/backend/column.phpnu[grid_size) && $settings->grid_size){ $colSettings = RowColumnSettings::getSettings($settings); } $output = '
    '; $output .= '
    '; if (isset($settings->column_type) && $settings->column_type) { $output .= 'Component'; } else { if (isset($settings->name)) { $output .= ''. $settings->name .''; } else { $output .= 'None'; } } $output .= ''; $output .= '
    '; $output .= '
    '; echo $output;PK! (system/helixultimate/layouts/display.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use HelixUltimate\Framework\Platform\Settings; use Joomla\CMS\Factory; use Joomla\CMS\Layout\LayoutHelper; extract($displayData); $app = Factory::getApplication(); $sidebar = new Settings; ?>
    $id, 'view' => $view], HELIX_LAYOUTS_PATH); ?>
    $id, 'view' => $view], HELIX_LAYOUTS_PATH); ?>
    renderFieldsetContents(); ?>
    PK!177.system/helixultimate/layouts/frontend/rows.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use Joomla\CMS\Layout\FileLayout; $layout_path_carea = JPATH_ROOT .'/plugins/system/helixultimate/layouts'; $layout_path_module = JPATH_ROOT .'/plugins/system/helixultimate/layouts'; $data = $displayData; $section_sematic = $data['sematic']; extract($displayData); ?>
    $column) { if (isset($componentArea) && $componentArea) { $column->sematic = 'aside'; } else { $column->sematic = 'div'; } $column->hasFeature = $loadFeature; $column->section_sematic = $section_sematic; if ($column->settings->column_type) { echo (new FileLayout('frontend.conponentarea', $layout_path_carea))->render($column); } else { echo (new FileLayout('frontend.modules', $layout_path_module))->render($column); } } ?>
    PK!~   1system/helixultimate/layouts/frontend/modules.phpnu[settings; $params = Helper::loadTemplateData()->params; $isHeader = !empty($data->section_sematic) && $data->section_sematic === 'header'; $menuType = $params->get('menu_type', ''); $hasOffcanvas = in_array($menuType, ['mega_offcanvas', 'offcanvas']); $offcanvasPosition = $params->get('offcanvas_position', 'right'); $columnClass = $isHeader ? ' d-flex align-items-center' : ''; $columnClass .= $isHeader && $options->name === 'menu' ? ' justify-content-end' : ''; $output =''; $output .= '<'.$data->sematic.' id="sp-' . OutputFilter::stringURLSafe($options->name) . '" class="'. $options->className .'">'; $output .= '
    '; $features = (isset($data->hasFeature[$options->name]) && $data->hasFeature[$options->name])? $data->hasFeature[$options->name] : array(); foreach ($features as $key => $feature) { if (isset($feature['feature']) && $feature['load_pos'] == 'before' ) { $output .= $feature['feature']; } } $output .= ''; foreach ($features as $key => $feature) { if (isset($feature['feature']) && $feature['load_pos'] != 'before' ) { $output .= $feature['feature']; } } if ($isHeader && $hasOffcanvas && $options->name === 'menu') { if ($offcanvasPosition === 'right') { if ($menuType !== 'offcanvas') { $output .= ''; $output .= '
    '; $output .= '
    '; } } } $output .= '
    '; $output .= 'sematic.'>'; echo $output; PK!6&njj2system/helixultimate/layouts/frontend/generate.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); $layout_path = JPATH_ROOT .'/plugins/system/helixultimate/layouts'; $data = $displayData; extract($displayData); ?> < id="" >
    render($data); ?>
    >PK!t'U7system/helixultimate/layouts/frontend/conponentarea.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ defined('_JEXEC') or die(); use Joomla\CMS\Factory; $doc = Factory::getDocument(); $data = $displayData; ?>
    countModules('content-top')): ?>
    countModules('content-bottom')): ?>
    PK!Csystem/helixultimate/layouts/frontend/headerlist/style-1/header.phpnu[template->template . '/features/'; include_once $feature_folder_path.'logo.php'; include_once $feature_folder_path.'social.php'; include_once $feature_folder_path.'contact.php'; include_once $feature_folder_path.'menu.php'; $output = ''; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $social = new HelixUltimateFeatureSocial($data->params); $output .= $social->renderFeature(); $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $contact = new HelixUltimateFeatureContact($data->params); $output .= $contact->renderFeature(); $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= ''; $output .= '
    '; $output .= '
    '; $menu = new HelixUltimateFeatureMenu($data->params); $output .= $menu->renderFeature(); $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; echo $output;PK!/.4Bsystem/helixultimate/layouts/frontend/headerlist/style-1/thumb.jpgnu[JFIFC   %# , #&')*)-0-(0%()(C   (((((((((((((((((((((((((((((((((((((((((((((((((((/X"8!1AUQ"2Raq#3Br$b 1!2Q ?qa,[16}j]?p\TYʥF^FJ}YP HJ 1 M-^^. d,8 5)%"6cueY)Ǥڕq,)Z!:nᦱ!JJSU-zğS ,V694$&n$GːKta)BR.)D)1yenՕE ǭ6t:veR 8JC RA86ꊦPU}-!ru+RJMM~^H)2J8(} KM6@6͘x(G-hu7q $i(QSrPTӍ%mܝTuQ$IO( /4zP$/)Z$9V-(P]2 GdNy9]| I71^6?CU*mY¥yIR^q$$V U diR ̜N B =4 CZMttS P[d YOUJHK5"ܣ2{BTQYA`49% K̢C9 " pt "DԨJZT #1j֯x:pqj+Q$\ Z@gsW6}j!ϭ^ڹ0{W>{j֯x\ Z@gsW6}j!ϭ^ڹ0{W>{j֯x\ Z@gsW6}j!ϭ^ڹ0{W>{dzMM/2)ulK%*}`QʒSkF:uVR/r?,JyUc Lf\8PBPQ'>)%5u(p<x3Xu0io r@$[ٰ~`u߭#횒h:/,«|Y<[h1#Rh:h,qNXON:G*o m[F~jt6XԊ%Lh@د1Xom}xjAR4ĚuWslghV}yXk@b I2&. HeK/)RS_;$>&}SLTڔD%d,p,4޼ӫHlBmĶқʵ(mfSIЀdtD22IPer,@(ǔ6\L e]Nm`;#gKJi) Py6nNHJ˙F(oq ?Jԕ}ca8҂<X[Wi w:&Y [KھUcBVQ|Nbfm A#eVLUf~p5CIdd $ /8bI"iJdA$RuZVzNN},T%fR6mޚceť-akV\JIהH*LLK~Y`>△8YsE^p#N}EK Cm7bysp &c6\ʫlޗuï9/2%.)I#!GYW6t2fCi p(_x(cՆ3&>-d؛'CqpJfMmiaïdt4ճZe{{i_Qq eŨ+[Z^{j֯x̸wZs1c@~WR Rn7!:rY0!:r7!:rY1VvY 5(84$ir}fӨM л| л|N* JU`C#*#TRyƮ&SRdI )^OIw5ε?-`ܻ `ܻ _NuJSġ;Ι$-b5{~$u-6*Tےeco:JtxnCt.(nCt.(ʯNUk2)FN')D^M@t'ǒjR6K3_YH]l_О6nCt.(nCt.(V+ 8$~\LDiCW%T л| л|MQ-SPU9(Cs,>PYSLH:[qn݈b 6/rw.Crw.DR& 'T-6%.*>M6WTBP2[q9H0B]0B]]kq{7TOǤm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ʉm л| л|Ɏ(mTHZ\yL\"$*1&b< w w'?Ʃ{v%%s.F̬-/XٔB)0JmzBkh7w!:r7!:rY150Ԥ3 a)Ŭj@>%w л| л|]HTjZut&`]P.$+xnJu V)3!A1 л| л|f~Mt>ܻ-ĸRP8x!:r7!:rY1ɮb*m VO̓ͩ@@*Q"Xf0B]0B]򉜾#,_#*}ajCd)AV)svP PpX~!:r7!:rY0!:r7!:rOZp3%Z 8p?hnIu,)TfCOSs#rw.Crw.Dz%, )Bn(|VHؒSg]uI]-RU𝠺, +܆]˾P܆]˾QcNfԕ]&܆]˾P܆]˾QdOJ Pn?!!ea!r)(hPƄvt[s;MiK/+6] )%$$6< %G~Y SAĕ!`,mkȼX0NP.'s?/~-ɩ)VTB3oJ7IT\󳌷#Ou49VIU"dKnO*zZsrỤ mKaeSMܜ!*4,+QOTۘU!e.lm˛($M-?ZjWeʓMI,lXly8\c}*'(4T @761ڄnqK2VI-)'sy ̭Ien: "a=r8A\}eZr[Х\ fzXΉIEJmsN"@xɥJ2n% 4IB~iG!!!!!!!!!!!!!!!!!L&jeN;2!YR@7OĔ&7#LywImH@.5eJFs6;rOKp(-%JH)kC W$rSEe^mmÕZרʦz5(└L4@h%Gґ2=u9.̒ .WUkV͛@ 9ւͲBci-Kd3\'*T,AaTԺuA +3.?\mknIaFnij: JMŠI PĒSբʝ+(=,&6ɺJ@nunLR,T|#}BM Ja!ĸaBbr~q2.IRY@*x ">{3?4ԅLhک l7 W;Ń\1yg\|L&)Gy}jT ԇQGJHI6* XM%P֦S$Xe K2m<O30PK!{Csystem/helixultimate/layouts/frontend/headerlist/style-2/header.phpnu[template->template . '/features/'; include_once $feature_folder_path.'logo.php'; include_once $feature_folder_path.'menu.php'; $output = ''; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= ''; $output .= '
    '; $output .= '
    '; $menu = new HelixUltimateFeatureMenu($data->params); $output .= $menu->renderFeature(); $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; $output .= '
    '; echo $output;PK!7Bsystem/helixultimate/layouts/frontend/headerlist/style-2/thumb.jpgnu[JFIFC   %# , #&')*)-0-(0%()(C   (((((((((((((((((((((((((((((((((((((((((((((((((((X"2!1AQ"2aq#R$Bbr1! ?5ĕ(2G.w;NѲ}oj_)1fҘ# աc,ژ/Uc$qq۾4'[/`e%2-3A_NqXe˴rc:r/z #}(Ts ,fB#x~Ǡ[XD}K4ndZ+^q t\uIdp^6Q[Yk^H$`tŤ~ދh3j㤀vts<Dz#aLo%gb y  DZ6yh胠tζ>/"D9⃡,$oC;#J=>?:M[G^v#$w8,#kApEϪMKS;Ȉ@p~ 5]:ΓHY'k$\' M-q@NYw:1HLG}lSu|ֱb0M;;O݁_sGdvY ɪ9,%#ahw,2VL}2'k Bf޽\DfO b(l%7DoJZ" """ (9ZrZ7VCj[{ NEvjţ%crͅQNG_`4x+-,Xg-qHO&ўNQY;|7鮤;3I1H'k,=veggI2#[y~װ+"?^,O6kr$&q[GFa11梥Y쭗-W2;sS^+ X-y[% WKbw=~Cd)0amfCbŻa2vļ5cz[4Aت&73lguU^IZ*߃:=.?=V@uxG([u eVJ#}yKIawm:̒^ nwOȈψXHԑд9bf=,cY8mj-YRF7hk2904Ru"2@%ƾ75a>R>:*C!s-np8M_ B_;Dw?dEaDiՂhӆ8+4hkZ?@dD2BHz{/t7?4^ZZP  X5h"Z6h%;nr*ۉ5kO{u.A2 +Q}vuDP' Pݾ;Y(ЧGF00hzvJ """ ""PK!/Vh((/system/helixultimate/layouts/preview/iframe.phpnu[ * @copyright Copyright (c) 2010 - 2021 JoomShaper * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later */ use Joomla\CMS\Factory; use Joomla\CMS\Uri\Uri; defined('_JEXEC') or die(); $doc = Factory::getDocument(); $doc->addStyleSheet(Uri::root(true) . '/media/system/css/joomla-fontawesome.min.css', ['relative' => false, 'version' => 'auto']); extract($displayData); $style = ''; if (empty($width)) { $width = '100%'; } if (empty($height)) { $height = '100%'; } $style .= "width: {$width}; height: {$height}; box-shadow: rgba(139, 139, 143, 0.56) 3px 0px 10px;"; ?> PK!pp1system/helixultimate/layouts/form/field/media.phpnu[ 'auto', 'relative' => true, 'framework' => true)); // Tooltip for INPUT showing whole image path $options = array( 'onShow' => 'jMediaRefreshImgpathTip', ); JHtml::_('behavior.tooltip', '.hasTipImgpath', $options); if (!empty($class)) { $class .= ' hasTipImgpath'; } else { $class = 'hasTipImgpath'; } $attr = ''; $attr .= ' title="' . htmlspecialchars('', ENT_COMPAT, 'UTF-8') . '"'; // Initialize some field attributes. $attr .= !empty($class) ? ' class="input-small field-media-input ' . $class . '"' : ' class="input-small"'; $attr .= !empty($size) ? ' size="' . $size . '"' : ''; // Initialize JavaScript field attributes. $attr .= !empty($onchange) ? ' onchange="' . $onchange . '"' : ''; // The text field. echo '
    '; // The Preview. $showPreview = true; $showAsTooltip = false; switch ($preview) { case 'no': // Deprecated parameter value case 'false': case 'none': $showPreview = false; break; case 'yes': // Deprecated parameter value case 'true': case 'show': break; case 'tooltip': default: $showAsTooltip = true; $options = array( 'onShow' => 'jMediaRefreshPreviewTip', ); JHtml::_('behavior.tooltip', '.hasTipPreview', $options); break; } // Pre fill the contents of the popover if ($showPreview) { if ($value && file_exists(JPATH_ROOT . '/' . $value)) { $src = Uri::root() . $value; } else { $src = ''; } $width = $previewWidth; $height = $previewHeight; $style = ''; $style .= ($width > 0) ? 'max-width:' . $width . 'px;' : ''; $style .= ($height > 0) ? 'max-height:' . $height . 'px;' : ''; $imgattr = array( 'id' => $id . '_preview', 'class' => 'media-preview', 'style' => $style, ); $img = JHtml::_('image', $src, JText::_('JLIB_FORM_MEDIA_PREVIEW_ALT'), $imgattr); $previewImg = ''; $previewImgEmpty = ''; if ($showAsTooltip) { echo '
    '; $tooltip = $previewImgEmpty . $previewImg; $options = array( 'title' => JText::_('JLIB_FORM_MEDIA_PREVIEW_SELECTED_IMAGE'), 'text' => '', 'class' => 'hasTipPreview' ); echo JHtml::_('tooltip', $tooltip, $options); echo '
    '; } else { echo '
    '; echo ' ' . $previewImgEmpty; echo ' ' . $previewImg; echo '
    '; } } echo ' '; ?> >
    PK!SZZBsystem/helixultimate/html/layouts/libraries/cms/html/bootstrap.phpnu[addScriptOptions('bootstrap.alert', array($selector => '')); static::$loaded[__METHOD__][$selector] = true; } /** * Add javascript support for Bootstrap buttons * * @param string $selector Common class for the buttons * * @return void * * @since 3.1 */ public static function button($selector = 'button') { // Only load once if (!empty(static::$loaded[__METHOD__][$selector])) { return; } // Include Bootstrap framework HTMLHelper::_('bootstrap.framework'); Factory::getDocument()->addScriptOptions('bootstrap.button', array($selector)); static::$loaded[__METHOD__][$selector] = true; } /** * Add javascript support for Bootstrap carousels * * @param string $selector Common class for the carousels. * @param array $params An array of options for the carousel. * Options for the carousel can be: * - interval number The amount of time to delay between automatically cycling an item. * If false, carousel will not automatically cycle. * - pause string Pauses the cycling of the carousel on mouseenter and resumes the cycling * of the carousel on mouseleave. * * @return void * * @since 3.0 */ public static function carousel($selector = 'carousel', $params = array()) { // Only load once if (!empty(static::$loaded[__METHOD__][$selector])) { return; } // Include Bootstrap framework HTMLHelper::_('bootstrap.framework'); // Setup options object $opt['interval'] = isset($params['interval']) ? (int) $params['interval'] : 5000; $opt['pause'] = isset($params['pause']) ? $params['pause'] : 'hover'; Factory::getDocument()->addScriptOptions('bootstrap.carousel', array($selector => $opt)); static::$loaded[__METHOD__][$selector] = true; } /** * Add javascript support for Bootstrap dropdowns * * @param string $selector Common class for the dropdowns * * @return void * * @since 3.0 */ public static function dropdown($selector = 'dropdown-toggle') { // Only load once if (!empty(static::$loaded[__METHOD__][$selector])) { return; } // Include Bootstrap framework HTMLHelper::_('bootstrap.framework'); Factory::getDocument()->addScriptOptions('bootstrap.dropdown', array($selector)); static::$loaded[__METHOD__][$selector] = true; } /** * Method to load the Bootstrap JavaScript framework into the document head * * If debugging mode is on an uncompressed version of Bootstrap is included for easier debugging. * * @param mixed $debug Is debugging mode on? [optional] * * @return void * * @since 3.0 */ public static function framework($debug = null) { // Only load once if (!empty(static::$loaded[__METHOD__])) { return; } $debug = (isset($debug) && $debug != JDEBUG) ? $debug : JDEBUG; // Load the needed scripts HTMLHelper::_('behavior.core'); HTMLHelper::_('jquery.framework'); HTMLHelper::_('script', 'vendor/tether/tether.min.js', array('version' => 'auto', 'relative' => true, 'detectDebug' => $debug)); HTMLHelper::_('script', 'vendor/bootstrap/bootstrap.min.js', array('version' => 'auto', 'relative' => true, 'detectDebug' => $debug)); HTMLHelper::_('script', 'system/bootstrap-init.min.js', array('version' => 'auto', 'relative' => true, 'detectDebug' => $debug)); static::$loaded[__METHOD__] = true; } /** * Method to render a Bootstrap modal * * @param string $selector The ID selector for the modal. * @param array $params An array of options for the modal. * Options for the modal can be: * - title string The modal title * - backdrop mixed A boolean select if a modal-backdrop element should be included (default = true) * The string 'static' includes a backdrop which doesn't close the modal on click. * - keyboard boolean Closes the modal when escape key is pressed (default = true) * - closeButton boolean Display modal close button (default = true) * - animation boolean Fade in from the top of the page (default = true) * - footer string Optional markup for the modal footer * - url string URL of a resource to be inserted as an `',{iframe:["src","class","title","width","height"]});$(this).find(".joomla-modal").attr("data-url",url).attr("data-iframe",ifrHtml)}$linkBtn.length&&$linkBtn.attr("href",url)})}function cleanInputValue(elm){var val=$(elm).val()||"";val.indexOf("#joomlaImage")!=-1&&(val=val.substring(0,val.indexOf("#")),$(elm).val(val).attr("value",val))}function isImage(value){return value&&/\.(jpg|jpeg|png|gif|svg|apng|webp)$/.test(value)}var counter=0;$.fn.WfMediaUpload=function(){return this.each(function(){function insertFile(value){var $wrapper=$(elm).parents(".field-media-wrapper"),inst=$wrapper.data("fieldMedia")||$wrapper.get(0);return inst&&inst.setValue?inst.setValue(value):$(elm).val(value).trigger("change"),!0}function uploadAndInsert(url,file){if(!file.name)return!1;var params=parseUrl(url),url=getBasePath(elm)+"index.php?option=com_jce",validParams=["task","context","plugin","filter","mediatype"],filter=params.filter||params.mediatype||"images";return checkMimeType(file,filter)?(params.task="plugin.rpc",$.each(params,function(key,value){$.inArray(key,validParams)===-1&&delete params[key]}),url+="&"+$.param(params),$(elm).prop("disabled",!0).addClass("wf-media-upload-busy"),void upload(url,file).then(function(response){$(elm).prop("disabled",!1).removeAttr("disabled").removeClass("wf-media-upload-busy");try{var o=JSON.parse(response),error="Unable to upload file";if($.isPlainObject(o)){o.error&&(error=o.error.message||error);var r=o.result;if(r){var files=r.files||[],item=files.length?files[0]:{};if(item.file)return insertFile(item.file)}}alert(error)}catch(e){alert("The server returned an invalid JSON response")}},function(){return $(elm).prop("disabled",!1).removeAttr("disabled").removeClass("wf-media-upload-busy"),!1})):(alert("The selected file is not supported."),!1)}var elm=this,url=getModalURL(elm);if(!url)return!1;var $uploadBtn=$('');$('input[type="file"]',$uploadBtn).on("change",function(e){if(e.preventDefault(),this.files){var file=this.files[0];file&&uploadAndInsert(url,file)}});var $selectBtn=$(elm).parent().find(".button-select, .modal.btn");$uploadBtn.insertAfter($selectBtn),$(elm).on("drag dragstart dragend dragover dragenter dragleave drop",function(e){e.preventDefault(),e.stopPropagation()}).on("dragover dragenter",function(e){$(this).addClass("wf-media-upload-hover")}).on("dragleave",function(e){$(this).removeClass("wf-media-upload-hover")}).on("drop",function(e){var dataTransfer=e.originalEvent.dataTransfer;if(dataTransfer&&dataTransfer.files&&dataTransfer.files.length){var file=dataTransfer.files[0];file&&uploadAndInsert(url,file)}$(this).removeClass("wf-media-upload-hover")})})},$(document).ready(function($){function canProcessField(elm){return options.replace_media||$(elm).find(".wf-media-input").length}var options=Joomla.getOptions("plg_system_jce",{});options.replace_media&&$(".field-media-wrapper, .fc-field-value-properties-box").find(".field-media-input").addClass("wf-media-input"),$(".wf-media-input").removeAttr("readonly").parents(".field-media-wrapper").addClass("wf-media-wrapper"),$(".wf-media-input").parents(".subform-repeatable-group").each(function(i,row){updateMediaUrl(row,options,!0)}),$("joomla-field-media.wf-media-wrapper").each(function(){var field=this;if(field.inputElement){cleanInputValue(field.inputElement);var markValidFunction=field.markValid||function(){};field.markValid=function(){cleanInputValue(this.inputElement),field.querySelector('label[for="'+this.inputElement.id+'"]')&&markValidFunction.apply(this)},field.inputElement.addEventListener("change",function(e){e.stopImmediatePropagation(),field.querySelector('label[for="'+this.id+'"]')&&markValidFunction.apply(this),field.updatePreview(),$(document).trigger("t4:media-selected",{selectedUrl:field.basePath+this.value})},!0)}updateMediaUrl(this,options)}),$(".wf-media-wrapper-custom").each(function(){updateMediaUrl(this,options,!0)}),$(document).on("subform-row-add",function(evt,row){var originalEvent=evt.originalEvent;originalEvent&&originalEvent.detail&&(row=originalEvent.detail.row||row),canProcessField(row)&&($(row).find(".wf-media-input, .field-media-input").removeAttr("readonly").addClass("wf-media-input wf-media-input-active"),updateMediaUrl(row,options,!0))}),$(".wf-media-input-upload").not('[name*="media-repeat"]').WfMediaUpload(),$(".wf-media-wrapper .modal-header h3").html(" ")})}(jQuery);PK!Lsystem/jce/templates/sun.phpnu[name; if (!is_file($path . '/template.defines.php')) { return false; } // add bootstrap $files[] = 'plugins/system/jsntplframework/assets/3rd-party/bootstrap/css/bootstrap-frontend.min.css'; // add base template.css file $files[] = 'templates/' . $template->name . '/css/template.css'; $params = new JRegistry($template->params); $preset = $params->get('preset', ''); $data = json_decode($preset); if ($data) { if (isset($data->templateColor)) { $files[] = 'templates/' . $template->name . '/css/color/' . $data->templateColor . '.css'; } if (isset($data->fontStyle) && isset($data->fontStyle->style)) { $files[] = 'templates/' . $template->name . '/css/styles/' . $data->fontStyle->style . '.css'; } } } }PK!: system/jce/templates/gantry.phpnu[name; // not a gantry template if (!is_dir($path . '/gantry') && !is_file($path . '/gantry.config.php')) { return false; } $name = substr($template->name, strpos($template->name, '_') + 1); // try Gantry5 templates $gantry5 = $path . '/custom/css-compiled'; $gantry4 = $path . '/css-compiled'; if (is_dir($gantry5)) { // update url $url = 'templates/' . $template->name . '/custom/css-compiled'; // editor.css file $editor_css = $gantry5 . '/editor.css'; // check for editor.css file if (is_file($editor_css) && filesize($editor_css) > 0) { $files[] = $url . '/' . basename($editor_css); return true; } // load gantry base files $files[] = 'media/gantry5/assets/css/bootstrap-gantry.css'; $files[] = 'media/gantry5/engines/nucleus/css-compiled/nucleus.css'; $items = array(); $custom = array(); $list = glob($gantry5 . '/*_[0-9]*.css'); foreach ($list as $file) { if (strpos(basename($file), 'custom_') !== false) { $custom[filemtime($file)] = $file; } else { $items[filemtime($file)] = $file; } } if (!empty($items)) { // sort items by modified time key ksort($items, SORT_NUMERIC); // get the last item in the array $item = end($items); $path = dirname($item); $file = basename($item); // load css files $files[] = $url . '/' . $file; } // load custom css file if it exists if (!empty($custom)) { // sort custom by modified time key ksort($custom, SORT_NUMERIC); // get the last custom file in the array $custom_file = end($custom); // create custom file url $files[] = $url . '/' . basename($custom_file); } } if (is_dir($gantry4)) { // update url $url = 'templates/' . $template->name . '/css-compiled'; // load gantry bootstrap files $files[] = $url . '/bootstrap.css'; $items = array(); $list = glob($gantry4 . '/master-*.css'); if (!empty($list)) { foreach ($list as $file) { $items[filemtime($file)] = $file; } // sort by modified time key ksort($items, SORT_NUMERIC); // get the last item in the array $item = end($items); // load css files $files[] = $url . '/' . basename($item); } } } } PK!(qosystem/jce/templates/core.phpnu[name . '/css', JPATH_SITE . '/media/templates/site/' . $template->name . '/css' ), 'template.css'); if (!$file) { return false; } // make relative $file = str_replace(JPATH_SITE, '', $file); // remove leading slash $file = trim($file, '/'); $files[] = $file; } }PK!"!system/jce/templates/joomlart.phpnu[name; if (!is_file($path . '/templateInfo.php')) { return false; } // add base template.css file $files[] = 'templates/' . $template->name . '/css/template.css'; $items = array(); $list = glob(JPATH_SITE . '/media/t4/css/*.css'); foreach($list as $file) { $items[filemtime($file)] = $file; } // sort by modified time key ksort($items, SORT_NUMERIC); // get the last item in the array $item = end($items); // add compiled css file $files[] = 'media/t4/css/' . basename($item); } }PK!tQsystem/jce/templates/helix.phpnu[name; if (!is_file($path . '/comingsoon.php')) { return false; } // add bootstrap $files[] = 'templates/' . $template->name . '/css/bootstrap.min.css'; // add base template.css file $files[] = 'templates/' . $template->name . '/css/template.css'; $params = new JRegistry($template->params); $preset = $params->get('preset', ''); $data = json_decode($preset); if ($data) { if (isset($data->preset)) { $files[] = 'templates/' . $template->name . '/css/presets/' . $data->preset . '.css'; } } } }PK!t:+system/jce/templates/wright.phpnu[name; // not a wright template if (!is_dir($path . '/wright')) { return false; } // add bootstrap $files[] = 'templates/' . $template->name . '/wright/css/bootstrap.min.css'; $params = new JRegistry($template->params); $style = $params->get('style', 'default'); // check style-custom.css file $file = $path . '/css/style-' . $style . '.css'; // add base theme.css file if (is_file($file)) { $files[] = 'templates/' . $template->name . '/css/style-' . $style . '.css'; } } }PK!SOO!system/jce/templates/yootheme.phpnu[name; // not a yootheme / warp template if (!is_dir($path . '/warp') && !is_dir($path . '/vendor/yootheme')) { return false; } if (is_dir($path . '/warp')) { $file = 'css/theme.css'; $config = $path . '/config.json'; if (is_file($config)) { $data = file_get_contents($config); $json = json_decode($data); $style = ''; if ($json) { if (!empty($json->layouts->default->style)) { $style = $json->layouts->default->style; } } if ($style && $style !== 'default') { $file = 'styles/' . $style . '/css/theme.css'; } } // add base theme.css file if (is_file($path . '/' . $file)) { $files[] = 'templates/' . $template->name . '/' . $file; } // add custom css file if (is_file($path . '/css/custom.css')) { $files[] = 'templates/' . $template->name . '/css/custom.css'; } } if (is_dir($path . '/vendor/yootheme')) { $files[] = 'templates/' . $template->name . '/css/theme.css'; // add custom css file if (is_file($path . '/css/custom.css')) { $files[] = 'templates/' . $template->name . '/css/custom.css'; } } } }PK!#P]3LL system/jce/templates/astroid.phpnu[name; if (is_dir($path . '/astroid')) { $items = glob($path . '/css/compiled-*.css'); foreach($items as $item) { $files[] = 'media/templates/site/' . $template->name . '/css/' . basename($item); } return true; } // Joomla 3 $path = JPATH_SITE . '/templates/' . $template->name; if (is_dir($path . '/astroid')) { $items = glob($path . '/css/compiled-*.css'); foreach($items as $item) { // add compiled css file $files[] = 'templates/' . $template->name . '/css/' . basename($item); } } } }PK!й+system/privacyconsent/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\System\PrivacyConsent\Extension\PrivacyConsent; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new PrivacyConsent( $dispatcher, (array) PluginHelper::getPlugin('system', 'privacyconsent') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!`%!.system/privacyconsent/forms/privacyconsent.xmlnu[
    PK!aa6system/privacyconsent/src/Extension/PrivacyConsent.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\PrivacyConsent\Extension; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Cache\Cache; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormHelper; use Joomla\CMS\Language\Associations; use Joomla\CMS\Language\Text; use Joomla\CMS\Mail\Exception\MailDisabledException; use Joomla\CMS\Mail\MailTemplate; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\UserHelper; use Joomla\Component\Actionlogs\Administrator\Model\ActionlogModel; use Joomla\Component\Messages\Administrator\Model\MessageModel; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\Exception\ExecutionFailureException; use Joomla\Database\ParameterType; use Joomla\Utilities\ArrayHelper; use PHPMailer\PHPMailer\Exception as phpmailerException; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * An example custom privacyconsent plugin. * * @since 3.9.0 */ final class PrivacyConsent extends CMSPlugin { use DatabaseAwareTrait; /** * Load the language file on instantiation. * * @var boolean * @since 3.9.0 */ protected $autoloadLanguage = true; /** * Adds additional fields to the user editing form * * @param Form $form The form to be altered. * @param mixed $data The associated data for the form. * * @return boolean * * @since 3.9.0 */ public function onContentPrepareForm(Form $form, $data) { // Check we are manipulating a valid form - we only display this on user registration form and user profile form. $name = $form->getName(); if (!in_array($name, ['com_users.profile', 'com_users.registration'])) { return true; } // We only display this if user has not consented before if (is_object($data)) { $userId = $data->id ?? 0; if ($userId > 0 && $this->isUserConsented($userId)) { return true; } } // Add the privacy policy fields to the form. FormHelper::addFieldPrefix('Joomla\\Plugin\\System\\PrivacyConsent\\Field'); FormHelper::addFormPath(JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/forms'); $form->loadFile('privacyconsent'); $privacyType = $this->params->get('privacy_type', 'article'); $privacyId = ($privacyType == 'menu_item') ? $this->getPrivacyItemId() : $this->getPrivacyArticleId(); $privacynote = $this->params->get('privacy_note'); // Push the privacy article ID into the privacy field. $form->setFieldAttribute('privacy', $privacyType, $privacyId, 'privacyconsent'); $form->setFieldAttribute('privacy', 'note', $privacynote, 'privacyconsent'); } /** * Method is called before user data is stored in the database * * @param array $user Holds the old user data. * @param boolean $isNew True if a new user is stored. * @param array $data Holds the new user data. * * @return boolean * * @since 3.9.0 * @throws \InvalidArgumentException on missing required data. */ public function onUserBeforeSave($user, $isNew, $data) { // // Only check for front-end user creation/update profile if ($this->getApplication()->isClient('administrator')) { return true; } $userId = ArrayHelper::getValue($user, 'id', 0, 'int'); // User already consented before, no need to check it further if ($userId > 0 && $this->isUserConsented($userId)) { return true; } // Check that the privacy is checked if required ie only in registration from frontend. $input = $this->getApplication()->getInput(); $option = $input->get('option'); $task = $input->post->get('task'); $form = $input->post->get('jform', [], 'array'); if ( $option == 'com_users' && in_array($task, ['registration.register', 'profile.save']) && empty($form['privacyconsent']['privacy']) ) { throw new \InvalidArgumentException($this->getApplication()->getLanguage()->_('PLG_SYSTEM_PRIVACYCONSENT_FIELD_ERROR')); } return true; } /** * Saves user privacy confirmation * * @param array $data entered user data * @param boolean $isNew true if this is a new user * @param boolean $result true if saving the user worked * @param string $error error message * * @return void * * @since 3.9.0 */ public function onUserAfterSave($data, $isNew, $result, $error): void { // Only create an entry on front-end user creation/update profile if ($this->getApplication()->isClient('administrator')) { return; } // Get the user's ID $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); // If user already consented before, no need to check it further if ($userId > 0 && $this->isUserConsented($userId)) { return; } $input = $this->getApplication()->getInput(); $option = $input->get('option'); $task = $input->post->get('task'); $form = $input->post->get('jform', [], 'array'); if ( $option == 'com_users' && in_array($task, ['registration.register', 'profile.save']) && !empty($form['privacyconsent']['privacy']) ) { $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); // Get the user's IP address $ip = $input->server->get('REMOTE_ADDR', '', 'string'); // Get the user agent string $userAgent = $input->server->get('HTTP_USER_AGENT', '', 'string'); // Create the user note $userNote = (object) [ 'user_id' => $userId, 'subject' => 'PLG_SYSTEM_PRIVACYCONSENT_SUBJECT', 'body' => Text::sprintf('PLG_SYSTEM_PRIVACYCONSENT_BODY', $ip, $userAgent), 'created' => Factory::getDate()->toSql(), ]; try { $this->getDatabase()->insertObject('#__privacy_consents', $userNote); } catch (\Exception $e) { // Do nothing if the save fails } $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); $message = [ 'action' => 'consent', 'id' => $userId, 'title' => $data['name'], 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $userId, 'userid' => $userId, 'username' => $data['username'], 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $userId, ]; /** @var ActionlogModel $model */ $model = $this->getApplication()->bootComponent('com_actionlogs')->getMVCFactory()->createModel('Actionlog', 'Administrator'); $model->addLog([$message], 'PLG_SYSTEM_PRIVACYCONSENT_CONSENT', 'plg_system_privacyconsent', $userId); } } /** * Remove all user privacy consent information for the given user ID * * Method is called after user data is deleted from the database * * @param array $user Holds the user data * @param boolean $success True if user was successfully stored in the database * @param string $msg Message * * @return void * * @since 3.9.0 */ public function onUserAfterDelete($user, $success, $msg): void { if (!$success) { return; } $userId = ArrayHelper::getValue($user, 'id', 0, 'int'); if ($userId) { // Remove user's consent $query = $this->getDatabase()->getQuery(true) ->delete($this->getDatabase()->quoteName('#__privacy_consents')) ->where($this->getDatabase()->quoteName('user_id') . ' = :userid') ->bind(':userid', $userId, ParameterType::INTEGER); $this->getDatabase()->setQuery($query); $this->getDatabase()->execute(); } } /** * If logged in users haven't agreed to privacy consent, redirect them to profile edit page, ask them to agree to * privacy consent before allowing access to any other pages * * @return void * * @since 3.9.0 */ public function onAfterRoute() { // Run this in frontend only if (!$this->getApplication()->isClient('site')) { return; } $userId = $this->getApplication()->getIdentity()->id; // Check to see whether user already consented, if not, redirect to user profile page if ($userId > 0) { // If user consented before, no need to check it further if ($this->isUserConsented($userId)) { return; } $input = $this->getApplication()->getInput(); $option = $input->getCmd('option'); $task = $input->get('task', ''); $view = $input->getString('view', ''); $layout = $input->getString('layout', ''); $id = $input->getInt('id'); $privacyArticleId = $this->getPrivacyArticleId(); /* * If user is already on edit profile screen or view privacy article * or press update/apply button, or logout, do nothing to avoid infinite redirect */ $allowedUserTasks = [ 'profile.save', 'profile.apply', 'user.logout', 'user.menulogout', 'method', 'methods', 'captive', 'callback', ]; $isAllowedUserTask = in_array($task, $allowedUserTasks) || substr($task, 0, 8) === 'captive.' || substr($task, 0, 8) === 'methods.' || substr($task, 0, 7) === 'method.' || substr($task, 0, 9) === 'callback.'; if ( ($option == 'com_users' && $isAllowedUserTask) || ($option == 'com_content' && $view == 'article' && $id == $privacyArticleId) || ($option == 'com_users' && $view == 'profile' && $layout == 'edit') ) { return; } // Redirect to com_users profile edit $this->getApplication()->enqueueMessage($this->getRedirectMessage(), 'notice'); $link = 'index.php?option=com_users&view=profile&layout=edit'; $this->getApplication()->redirect(Route::_($link, false)); } } /** * Event to specify whether a privacy policy has been published. * * @param array &$policy The privacy policy status data, passed by reference, with keys "published", "editLink" and "articlePublished". * * @return void * * @since 3.9.0 */ public function onPrivacyCheckPrivacyPolicyPublished(&$policy) { // If another plugin has already indicated a policy is published, we won't change anything here if ($policy['published']) { return; } $articleId = (int) $this->params->get('privacy_article'); if (!$articleId) { return; } // Check if the article exists in database and is published $query = $this->getDatabase()->getQuery(true) ->select($this->getDatabase()->quoteName(['id', 'state'])) ->from($this->getDatabase()->quoteName('#__content')) ->where($this->getDatabase()->quoteName('id') . ' = :id') ->bind(':id', $articleId, ParameterType::INTEGER); $this->getDatabase()->setQuery($query); $article = $this->getDatabase()->loadObject(); // Check if the article exists if (!$article) { return; } // Check if the article is published if ($article->state == 1) { $policy['articlePublished'] = true; } $policy['published'] = true; $policy['editLink'] = Route::_('index.php?option=com_content&task=article.edit&id=' . $articleId); } /** * Returns the configured redirect message and falls back to the default version. * * @return string redirect message * * @since 3.9.0 */ private function getRedirectMessage() { $messageOnRedirect = trim($this->params->get('messageOnRedirect', '')); if (empty($messageOnRedirect)) { return $this->getApplication()->getLanguage()->_('PLG_SYSTEM_PRIVACYCONSENT_REDIRECT_MESSAGE_DEFAULT'); } return $messageOnRedirect; } /** * Method to check if the given user has consented yet * * @param integer $userId ID of uer to check * * @return boolean * * @since 3.9.0 */ private function isUserConsented($userId) { $userId = (int) $userId; $db = $this->getDatabase(); $query = $db->getQuery(true); $query->select('COUNT(*)') ->from($db->quoteName('#__privacy_consents')) ->where($db->quoteName('user_id') . ' = :userid') ->where($db->quoteName('subject') . ' = ' . $db->quote('PLG_SYSTEM_PRIVACYCONSENT_SUBJECT')) ->where($db->quoteName('state') . ' = 1') ->bind(':userid', $userId, ParameterType::INTEGER); $db->setQuery($query); return (int) $db->loadResult() > 0; } /** * Get privacy article ID. If the site is a multilingual website and there is associated article for the * current language, ID of the associated article will be returned * * @return integer * * @since 3.9.0 */ private function getPrivacyArticleId() { $privacyArticleId = $this->params->get('privacy_article'); if ($privacyArticleId > 0 && Associations::isEnabled()) { $privacyAssociated = Associations::getAssociations('com_content', '#__content', 'com_content.item', $privacyArticleId); $currentLang = $this->getApplication()->getLanguage()->getTag(); if (isset($privacyAssociated[$currentLang])) { $privacyArticleId = $privacyAssociated[$currentLang]->id; } } return $privacyArticleId; } /** * Get privacy menu item ID. If the site is a multilingual website and there is associated menu item for the * current language, ID of the associated menu item will be returned. * * @return integer * * @since 4.0.0 */ private function getPrivacyItemId() { $itemId = $this->params->get('privacy_menu_item'); if ($itemId > 0 && Associations::isEnabled()) { $privacyAssociated = Associations::getAssociations('com_menus', '#__menu', 'com_menus.item', $itemId, 'id', '', ''); $currentLang = $this->getApplication()->getTag(); if (isset($privacyAssociated[$currentLang])) { $itemId = $privacyAssociated[$currentLang]->id; } } return $itemId; } /** * The privacy consent expiration check code is triggered after the page has fully rendered. * * @return void * * @since 3.9.0 */ public function onAfterRender() { if (!$this->params->get('enabled', 0)) { return; } $cacheTimeout = (int) $this->params->get('cachetimeout', 30); $cacheTimeout = 24 * 3600 * $cacheTimeout; // Do we need to run? Compare the last run timestamp stored in the plugin's options with the current // timestamp. If the difference is greater than the cache timeout we shall not execute again. $now = time(); $last = (int) $this->params->get('lastrun', 0); if ((abs($now - $last) < $cacheTimeout)) { return; } // Update last run status $this->params->set('lastrun', $now); $paramsJson = $this->params->toString('JSON'); $db = $this->getDatabase(); $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) ->set($db->quoteName('params') . ' = :params') ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) ->where($db->quoteName('element') . ' = ' . $db->quote('privacyconsent')) ->bind(':params', $paramsJson); try { // Lock the tables to prevent multiple plugin executions causing a race condition $db->lockTable('#__extensions'); } catch (\Exception $e) { // If we can't lock the tables it's too risky to continue execution return; } try { // Update the plugin parameters $result = $db->setQuery($query)->execute(); $this->clearCacheGroups(['com_plugins'], [0, 1]); } catch (\Exception $exc) { // If we failed to execute $db->unlockTables(); $result = false; } try { // Unlock the tables after writing $db->unlockTables(); } catch (\Exception $e) { // If we can't lock the tables assume we have somehow failed $result = false; } // Stop on failure if (!$result) { return; } // Delete the expired privacy consents $this->invalidateExpiredConsents(); // Remind for privacy consents near to expire $this->remindExpiringConsents(); } /** * Method to send the remind for privacy consents renew * * @return integer * * @since 3.9.0 */ private function remindExpiringConsents() { // Load the parameters. $expire = (int) $this->params->get('consentexpiration', 365); $remind = (int) $this->params->get('remind', 30); $now = Factory::getDate()->toSql(); $period = '-' . ($expire - $remind); $db = $this->getDatabase(); $query = $db->getQuery(true); $query->select($db->quoteName(['r.id', 'r.user_id', 'u.email'])) ->from($db->quoteName('#__privacy_consents', 'r')) ->join('LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('r.user_id')) ->where($db->quoteName('subject') . ' = ' . $db->quote('PLG_SYSTEM_PRIVACYCONSENT_SUBJECT')) ->where($db->quoteName('remind') . ' = 0') ->where($query->dateAdd($db->quote($now), $period, 'DAY') . ' > ' . $db->quoteName('created')); try { $users = $db->setQuery($query)->loadObjectList(); } catch (ExecutionFailureException $exception) { return false; } $app = $this->getApplication(); $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; foreach ($users as $user) { $token = ApplicationHelper::getHash(UserHelper::genRandomPassword()); $hashedToken = UserHelper::hashPassword($token); // The mail try { $templateData = [ 'sitename' => $app->get('sitename'), 'url' => Uri::root(), 'tokenurl' => Route::link('site', 'index.php?option=com_privacy&view=remind&remind_token=' . $token, false, $linkMode, true), 'formurl' => Route::link('site', 'index.php?option=com_privacy&view=remind', false, $linkMode, true), 'token' => $token, ]; $mailer = new MailTemplate('plg_system_privacyconsent.request.reminder', $app->getLanguage()->getTag()); $mailer->addTemplateData($templateData); $mailer->addRecipient($user->email); $mailResult = $mailer->send(); if ($mailResult === false) { return false; } $userId = (int) $user->id; // Update the privacy_consents item to not send the reminder again $query->clear() ->update($db->quoteName('#__privacy_consents')) ->set($db->quoteName('remind') . ' = 1') ->set($db->quoteName('token') . ' = :token') ->where($db->quoteName('id') . ' = :userid') ->bind(':token', $hashedToken) ->bind(':userid', $userId, ParameterType::INTEGER); $db->setQuery($query); try { $db->execute(); } catch (\RuntimeException $e) { return false; } } catch (MailDisabledException | phpmailerException $exception) { return false; } } } /** * Method to delete the expired privacy consents * * @return boolean * * @since 3.9.0 */ private function invalidateExpiredConsents() { // Load the parameters. $expire = (int) $this->params->get('consentexpiration', 365); $now = Factory::getDate()->toSql(); $period = '-' . $expire; $db = $this->getDatabase(); $query = $db->getQuery(true); $query->select($db->quoteName(['id', 'user_id'])) ->from($db->quoteName('#__privacy_consents')) ->where($query->dateAdd($db->quote($now), $period, 'DAY') . ' > ' . $db->quoteName('created')) ->where($db->quoteName('subject') . ' = ' . $db->quote('PLG_SYSTEM_PRIVACYCONSENT_SUBJECT')) ->where($db->quoteName('state') . ' = 1'); $db->setQuery($query); try { $users = $db->loadObjectList(); } catch (\RuntimeException $e) { return false; } // Do not process further if no expired consents found if (empty($users)) { return true; } // Push a notification to the site's super users /** @var MessageModel $messageModel */ $messageModel = $this->getApplication()->bootComponent('com_messages')->getMVCFactory()->createModel('Message', 'Administrator'); foreach ($users as $user) { $userId = (int) $user->id; $query = $db->getQuery(true) ->update($db->quoteName('#__privacy_consents')) ->set($db->quoteName('state') . ' = 0') ->where($db->quoteName('id') . ' = :userid') ->bind(':userid', $userId, ParameterType::INTEGER); $db->setQuery($query); try { $db->execute(); } catch (\RuntimeException $e) { return false; } $messageModel->notifySuperUsers( $this->getApplication()->getLanguage()->_('PLG_SYSTEM_PRIVACYCONSENT_NOTIFICATION_USER_PRIVACY_EXPIRED_SUBJECT'), Text::sprintf('PLG_SYSTEM_PRIVACYCONSENT_NOTIFICATION_USER_PRIVACY_EXPIRED_MESSAGE', Factory::getUser($user->user_id)->username) ); } return true; } /** * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. * * @param array $clearGroups The cache groups to clean * @param array $cacheClients The cache clients (site, admin) to clean * * @return void * * @since 3.9.0 */ private function clearCacheGroups(array $clearGroups, array $cacheClients = [0, 1]) { foreach ($clearGroups as $group) { foreach ($cacheClients as $client_id) { try { $options = [ 'defaultgroup' => $group, 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : $this->getApplication()->get('cache_path', JPATH_SITE . '/cache'), ]; $cache = Cache::getInstance('callback', $options); $cache->clean(); } catch (\Exception $e) { // Ignore it } } } } } PK!h0system/privacyconsent/src/Field/PrivacyField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\PrivacyConsent\Field; use Joomla\CMS\Factory; use Joomla\CMS\Form\Field\RadioField; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Language\Text; use Joomla\Component\Content\Site\Helper\RouteHelper; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Provides input for privacy * * @since 3.9.0 */ class PrivacyField extends RadioField { /** * The form field type. * * @var string * @since 3.9.0 */ protected $type = 'privacy'; /** * Method to get the field input markup. * * @return string The field input markup. * * @since 3.9.0 */ protected function getInput() { // Display the message before the field echo $this->getRenderer('plugins.system.privacyconsent.message')->render($this->getLayoutData()); return parent::getInput(); } /** * Method to get the field label markup. * * @return string The field label markup. * * @since 3.9.0 */ protected function getLabel() { if ($this->hidden) { return ''; } return $this->getRenderer('plugins.system.privacyconsent.label')->render($this->getLayoutData()); } /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 3.9.4 */ protected function getLayoutData() { $data = parent::getLayoutData(); $article = false; $link = false; $privacyArticle = $this->element['article'] > 0 ? (int) $this->element['article'] : 0; if ($privacyArticle && Factory::getApplication()->isClient('site')) { $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName(['id', 'alias', 'catid', 'language'])) ->from($db->quoteName('#__content')) ->where($db->quoteName('id') . ' = :id') ->bind(':id', $privacyArticle, ParameterType::INTEGER); $db->setQuery($query); $article = $db->loadObject(); $slug = $article->alias ? ($article->id . ':' . $article->alias) : $article->id; $article->link = RouteHelper::getArticleRoute($slug, $article->catid, $article->language); $link = $article->link; } $privacyMenuItem = $this->element['menu_item'] > 0 ? (int) $this->element['menu_item'] : 0; if ($privacyMenuItem && Factory::getApplication()->isClient('site')) { $link = 'index.php?Itemid=' . $privacyMenuItem; if (Multilanguage::isEnabled()) { $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName(['id', 'language'])) ->from($db->quoteName('#__menu')) ->where($db->quoteName('id') . ' = :id') ->bind(':id', $privacyMenuItem, ParameterType::INTEGER); $db->setQuery($query); $menuItem = $db->loadObject(); $link .= '&lang=' . $menuItem->language; } } $extraData = [ 'privacynote' => !empty($this->element['note']) ? $this->element['note'] : Text::_('PLG_SYSTEM_PRIVACYCONSENT_NOTE_FIELD_DEFAULT'), 'options' => $this->getOptions(), 'value' => (string) $this->value, 'translateLabel' => $this->translateLabel, 'translateDescription' => $this->translateDescription, 'translateHint' => $this->translateHint, 'privacyArticle' => $privacyArticle, 'article' => $article, 'privacyLink' => $link, ]; return array_merge($data, $extraData); } } PK!++(system/privacyconsent/privacyconsent.xmlnu[ plg_system_privacyconsent Joomla! Project 2018-04 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_SYSTEM_PRIVACYCONSENT_XML_DESCRIPTION Joomla\Plugin\System\PrivacyConsent forms services src language/en-GB/plg_system_privacyconsent.ini language/en-GB/plg_system_privacyconsent.sys.ini
    PK!  :system/sppagebuilderproupdater/sppagebuilderproupdater.phpnu[element == 'com_sppagebuilder' ) ) { $params = new Registry; $params->loadString($data->params); $email = $params->get('joomshaper_email'); $license_key = $params->get('joomshaper_license_key'); $url = $params->get('updater', ''); $fields = array(); $db = Factory::getDbo(); if (!empty($email) and !empty($license_key)) { $extra_query = 'joomshaper_email=' . urlencode($email); $extra_query .='&joomshaper_license_key=' . urlencode($license_key); $fields = array( $db->quoteName('extra_query') . '=' . $db->quote($extra_query), $db->quoteName('last_check_timestamp') . '=0' ); } if (!empty($url)) { array_push($fields, $db->quoteName('location') . '=' . $db->quote($url)); } //Update column values of #__update_sites table after extension is saved. $db = Factory::getDbo(); $query = $db->getQuery(true) ->update($db->quoteName('#__update_sites')) ->set($fields) ->where($db->quoteName('name') . '=' . $db->quote('SP Page Builder')); $db->setQuery($query); $db->execute(); } } }PK!us[:system/sppagebuilderproupdater/sppagebuilderproupdater.xmlnu[ System - SP Page Builder Pro Updater JoomShaper.com Jul 2015 Copyright (c) 2010 - 2023 JoomShaper. All rights reserved. http://www.gnu.org/licenses/gpl-2.0.html GPLv2 or later support@joomshaper.com www.joomshaper.com 4.0.8 SP Page Builder Pro Updater Plugin sppagebuilderproupdater.php PK!dsystem/jmap/jmap.xmlnu[ System - JSitemap utilities Joomla! Extensions Store 2022-11-18 Copyright (C) 2016 - Joomla! Extensions Store. All Rights Reserved. http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL info@storejextensions.org http://storejextensions.org 4.11 JSitemap utilities plugin jmap.php simplehtmldom.php index.html PK!d*"system/jmap/simplehtmldom.phpnu[ text used instead of
    tags when returning text */ defined('JMAP_DEFAULT_BR_TEXT') || define('JMAP_DEFAULT_BR_TEXT', "\r\n"); /** The default text used instead of tags when returning text */ defined('JMAP_DEFAULT_SPAN_TEXT') || define('JMAP_DEFAULT_SPAN_TEXT', ' '); /** The maximum file size the parser should load */ defined('JMAP_MAX_FILE_SIZE') || define('JMAP_MAX_FILE_SIZE', 600000); /** Contents between curly braces "{" and "}" are interpreted as text */ define('JMAP_HDOM_SMARTY_AS_TEXT', 1); // helper functions // ----------------------------------------------------------------------------- // get html dom from file // $maxlen is defined in the code as PHP_STREAM_COPY_ALL which is defined as -1. function jmap_simplehtmldom_file_get_html( $url, $use_include_path = false, $context = null, $offset = 0, $maxLen = -1, $lowercase = true, $forceTagsClosed = true, $target_charset = JMAP_DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = JMAP_DEFAULT_BR_TEXT, $defaultSpanText = JMAP_DEFAULT_SPAN_TEXT) { // Ensure maximum length is greater than zero if($maxLen <= 0) { $maxLen = JMAP_MAX_FILE_SIZE; } // We DO force the tags to be terminated. $dom = new JMapSimpleHtmlDom( null, $lowercase, $forceTagsClosed, $target_charset, $stripRN, $defaultBRText, $defaultSpanText); /** * For sourceforge users: uncomment the next line and comment the * retrieve_url_contents line 2 lines down if it is not already done. */ $contents = file_get_contents( $url, $use_include_path, $context, $offset, $maxLen); // Paperg - use our own mechanism for getting the contents as we want to // control the timeout. // $contents = retrieve_url_contents($url); if (empty($contents) || strlen($contents) > $maxLen) { return false; } // The second parameter can force the selectors to all be lowercase. $dom->load($contents, $lowercase, $stripRN); return $dom; } // get html dom from string function jmap_simplehtmldom_str_get_html( $str, $lowercase = true, $forceTagsClosed = true, $target_charset = JMAP_DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = JMAP_DEFAULT_BR_TEXT, $defaultSpanText = JMAP_DEFAULT_SPAN_TEXT) { $dom = new JMapSimpleHtmlDom( null, $lowercase, $forceTagsClosed, $target_charset, $stripRN, $defaultBRText, $defaultSpanText); if (empty($str) || strlen($str) > JMAP_MAX_FILE_SIZE) { $dom->clear(); return false; } $dom->load($str, $lowercase, $stripRN); return $dom; } /** * simple html dom node * PaperG - added ability for "find" routine to lowercase the value of the * selector. * * PaperG - added $tag_start to track the start position of the tag in the total * byte index * * @package PlaceLocalInclude */ class JMapSimpleHtmlDomNode { /** * Node type * * Default is {@see JMAP_HDOM_TYPE_TEXT} * * @var int */ public $nodetype = JMAP_HDOM_TYPE_TEXT; /** * Tag name * * Default is 'text' * * @var string */ public $tag = 'text'; /** * List of attributes * * @var array */ public $attr = array(); /** * List of child node objects * * @var array */ public $children = array(); public $nodes = array(); /** * The parent node object * * @var object|null */ public $parent = null; // The "info" array - see JMAP_HDOM_INFO_... for what each element contains. public $_ = array(); /** * Start position of the tag in the document * * @var int */ public $tag_start = 0; /** * The DOM object * * @var object|null */ private $dom = null; /** * Construct new node object * * Adds itself to the list of DOM Nodes {@see JMapSimpleHtmlDom::$nodes} */ function __construct($dom) { $this->dom = $dom; $dom->nodes[] = $this; } function __destruct() { $this->clear(); } function __toString() { return $this->outertext(); } // clean up memory due to php5 circular references memory leak... function clear() { $this->dom = null; $this->nodes = null; $this->parent = null; $this->children = null; } // dump node's tree function dump($show_attr = true, $deep = 0) { $lead = str_repeat(' ', $deep); echo $lead . $this->tag; if ($show_attr && count($this->attr) > 0) { echo '('; foreach ($this->attr as $k => $v) { echo "[$k]=>\"" . $this->$k . '", '; } echo ')'; } echo "\n"; if ($this->nodes) { foreach ($this->nodes as $c) { $c->dump($show_attr, $deep + 1); } } } // Debugging function to dump a single dom node with a bunch of information about it. function dump_node($echo = true) { $string = $this->tag; if (count($this->attr) > 0) { $string .= '('; foreach ($this->attr as $k => $v) { $string .= "[$k]=>\"" . $this->$k . '", '; } $string .= ')'; } if (count($this->_) > 0) { $string .= ' $_ ('; foreach ($this->_ as $k => $v) { if (is_array($v)) { $string .= "[$k]=>("; foreach ($v as $k2 => $v2) { $string .= "[$k2]=>\"" . $v2 . '", '; } $string .= ')'; } else { $string .= "[$k]=>\"" . $v . '", '; } } $string .= ')'; } if (isset($this->text)) { $string .= ' text: (' . $this->text . ')'; } $string .= " JMAP_HDOM_INNER_INFO: '"; if (isset($node->_[JMAP_HDOM_INFO_INNER])) { $string .= $node->_[JMAP_HDOM_INFO_INNER] . "'"; } else { $string .= ' NULL '; } $string .= ' children: ' . count($this->children); $string .= ' nodes: ' . count($this->nodes); $string .= ' tag_start: ' . $this->tag_start; $string .= "\n"; if ($echo) { echo $string; return; } else { return $string; } } /** * Return or set parent node * * @param object|null $parent (optional) The parent node, `null` to return * the current parent node. * @return object|null The parent node */ function parent($parent = null) { // I am SURE that this doesn't work properly. // It fails to unset the current node from it's current parents nodes or // children list first. if ($parent !== null) { $this->parent = $parent; $this->parent->nodes[] = $this; $this->parent->children[] = $this; } return $this->parent; } /** * @return bool True if the node has at least one child node */ function has_child() { return !empty($this->children); } /** * Get child node at specified index * * @param int $idx The index of the child node to return, `-1` to return all * child nodes. * @return object|array|null The child node at the specified index, all child * nodes or null if the index is invalid. */ function children($idx = -1) { if ($idx === -1) { return $this->children; } if (isset($this->children[$idx])) { return $this->children[$idx]; } return null; } /** * Get first child node * * @return object|null The first child node or null if the current node has * no child nodes. * * @todo Use `empty()` instead of `count()` to improve performance on large * arrays. */ function first_child() { if (count($this->children) > 0) { return $this->children[0]; } return null; } /** * Get last child node * * @return object|null The last child node or null if the current node has * no child nodes. * * @todo Use `end()` to slightly improve performance on large arrays. */ function last_child() { if (($count = count($this->children)) > 0) { return $this->children[$count - 1]; } return null; } /** * Get next sibling node * * @return object|null The sibling node or null if the current node has no * sibling nodes. */ function next_sibling() { if ($this->parent === null) { return null; } $idx = 0; $count = count($this->parent->children); while ($idx < $count && $this !== $this->parent->children[$idx]) { ++$idx; } if (++$idx >= $count) { return null; } return $this->parent->children[$idx]; } /** * Get previous sibling node * * @return object|null The sibling node or null if the current node has no * sibling nodes. */ function prev_sibling() { if ($this->parent === null) { return null; } $idx = 0; $count = count($this->parent->children); while ($idx < $count && $this !== $this->parent->children[$idx]) { ++$idx; } if (--$idx < 0) { return null; } return $this->parent->children[$idx]; } /** * Traverse ancestors to the first matching tag. * * @param string $tag Tag to find * @return object|null First matching node in the DOM tree or null if no * match was found. * * @todo Null is returned implicitly by calling ->parent on the root node. * This behaviour could change at any time, rendering this function invalid. */ function find_ancestor_tag($tag) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } // Start by including ourselves in the comparison. $returnDom = $this; while (!is_null($returnDom)) { if (is_object($debug_object)) { $debug_object->debug_log(2, 'Current tag is: ' . $returnDom->tag); } if ($returnDom->tag == $tag) { break; } $returnDom = $returnDom->parent; } return $returnDom; } /** * Get node's inner text (everything inside the opening and closing tags) * * @return string */ function innertext() { if (isset($this->_[JMAP_HDOM_INFO_INNER])) { return $this->_[JMAP_HDOM_INFO_INNER]; } if (isset($this->_[JMAP_HDOM_INFO_TEXT])) { return $this->dom->restore_noise($this->_[JMAP_HDOM_INFO_TEXT]); } $ret = ''; foreach ($this->nodes as $n) { $ret .= $n->outertext(); } return $ret; } /** * Get node's outer text (everything including the opening and closing tags) * * @return string */ function outertext() { global $debug_object; if (is_object($debug_object)) { $text = ''; if ($this->tag === 'text') { if (!empty($this->text)) { $text = ' with text: ' . $this->text; } } $debug_object->debug_log(1, 'Innertext of tag: ' . $this->tag . $text); } if ($this->tag === 'root') return $this->innertext(); // trigger callback if ($this->dom && $this->dom->callback !== null) { call_user_func_array($this->dom->callback, array($this)); } if (isset($this->_[JMAP_HDOM_INFO_OUTER])) { return $this->_[JMAP_HDOM_INFO_OUTER]; } if (isset($this->_[JMAP_HDOM_INFO_TEXT])) { return $this->dom->restore_noise($this->_[JMAP_HDOM_INFO_TEXT]); } // render begin tag if ($this->dom && $this->dom->nodes[$this->_[JMAP_HDOM_INFO_BEGIN]]) { $ret = $this->dom->nodes[$this->_[JMAP_HDOM_INFO_BEGIN]]->makeup(); } else { $ret = ''; } // render inner text if (isset($this->_[JMAP_HDOM_INFO_INNER])) { // If it's a br tag... don't return the JMAP_HDOM_INNER_INFO that we // may or may not have added. if ($this->tag !== 'br') { $ret .= $this->_[JMAP_HDOM_INFO_INNER]; } } else { if ($this->nodes) { foreach ($this->nodes as $n) { $ret .= $this->convert_text($n->outertext()); } } } // render end tag if (isset($this->_[JMAP_HDOM_INFO_END]) && $this->_[JMAP_HDOM_INFO_END] != 0) { $ret .= 'tag . '>'; } return $ret; } /** * Get node's plain text (everything excluding all tags) * * @return string */ function text() { if (isset($this->_[JMAP_HDOM_INFO_INNER])) { return $this->_[JMAP_HDOM_INFO_INNER]; } switch ($this->nodetype) { case JMAP_HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[JMAP_HDOM_INFO_TEXT]); case JMAP_HDOM_TYPE_COMMENT: return ''; case JMAP_HDOM_TYPE_UNKNOWN: return ''; } if (strcasecmp($this->tag, 'script') === 0) { return ''; } if (strcasecmp($this->tag, 'style') === 0) { return ''; } $ret = ''; // In rare cases, (always node type 1 or JMAP_HDOM_TYPE_ELEMENT - observed // for some span tags, and some p tags) $this->nodes is set to NULL. // NOTE: This indicates that there is a problem where it's set to NULL // without a clear happening. // WHY is this happening? if (!is_null($this->nodes)) { foreach ($this->nodes as $n) { // Start paragraph after a blank line if ($n->tag === 'p') { $ret .= "\n\n"; } $ret .= $this->convert_text($n->text()); // If this node is a span... add a space at the end of it so // multiple spans don't run into each other. This is plaintext // after all. if ($n->tag === 'span') { $ret .= $this->dom->default_span_text; } } } return trim($ret); } /** * Get node's xml text (inner text as a CDATA section) * * @return string */ function xmltext() { $ret = $this->innertext(); $ret = str_ireplace('', '', $ret); return $ret; } // build node's text with tag function makeup() { // text, comment, unknown if (isset($this->_[JMAP_HDOM_INFO_TEXT])) { return $this->dom->restore_noise($this->_[JMAP_HDOM_INFO_TEXT]); } $ret = '<' . $this->tag; $i = -1; foreach ($this->attr as $key => $val) { ++$i; // skip removed attribute if ($val === null || $val === false) { continue; } $ret .= $this->_[JMAP_HDOM_INFO_SPACE][$i][0]; //no value attr: nowrap, checked selected... if ($val === true) { $ret .= $key; } else { switch ($this->_[JMAP_HDOM_INFO_QUOTE][$i]) { case JMAP_HDOM_QUOTE_DOUBLE: $quote = '"'; break; case JMAP_HDOM_QUOTE_SINGLE: $quote = '\''; break; default: $quote = ''; } $ret .= $key . $this->_[JMAP_HDOM_INFO_SPACE][$i][1] . '=' . $this->_[JMAP_HDOM_INFO_SPACE][$i][2] . $quote . $val . $quote; } } $ret = $this->dom->restore_noise($ret); return $ret . $this->_[JMAP_HDOM_INFO_ENDSPACE] . '>'; } /** * Find elements by CSS selector * * @param string $selector The CSS selector * @param int|null $idx Index of element to return form the list of matching * elements (default: `null` = disabled). * @param bool $lowercase Matches tag names case insensitive (lowercase) if * enabled (default: `false`) * @return array|object|null A list of elements matching the specified CSS * selector or a single element if $idx is specified or null if no element * was found. */ function find($selector, $idx = null, $lowercase = false) { $selectors = $this->parse_selector($selector); if (($count = count($selectors)) === 0) { return array(); } $found_keys = array(); // find each selector for ($c = 0; $c < $count; ++$c) { // The change on the below line was documented on the sourceforge // code tracker id 2788009 // used to be: if (($levle=count($selectors[0]))===0) return array(); if (($levle = count($selectors[$c])) === 0) { return array(); } if (!isset($this->_[JMAP_HDOM_INFO_BEGIN])) { return array(); } $head = array($this->_[JMAP_HDOM_INFO_BEGIN] => 1); $cmd = ' '; // Combinator // handle descendant selectors, no recursive! for ($l = 0; $l < $levle; ++$l) { $ret = array(); foreach ($head as $k => $v) { $n = ($k === -1) ? $this->dom->root : $this->dom->nodes[$k]; //PaperG - Pass this optional parameter on to the seek function. $n->seek($selectors[$c][$l], $ret, $cmd, $lowercase); } $head = $ret; $cmd = $selectors[$c][$l][4]; // Next Combinator } foreach ($head as $k => $v) { if (!isset($found_keys[$k])) { $found_keys[$k] = 1; } } } // sort keys ksort($found_keys); $found = array(); foreach ($found_keys as $k => $v) { $found[] = $this->dom->nodes[$k]; } // return nth-element or array if (is_null($idx)) { return $found; } elseif ($idx < 0) { $idx = count($found) + $idx; } return (isset($found[$idx])) ? $found[$idx] : null; } /** * Seek DOM elements by selector * * **Note** * The selector element must be compatible to a selector from * {@see JMapSimpleHtmlDomNode::parse_selector()} * * @param array $selector A selector element * @param array $ret An array of matches * @param bool $lowercase Matches tag names case insensitive (lowercase) if * enabled (default: `false`) * @return void */ protected function seek($selector, &$ret, $parent_cmd, $lowercase = false) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } list($tag, $id, $class, $attributes, $cmb) = $selector; $nodes = array(); if ($parent_cmd === ' ') { // Descendant Combinator // Find parent closing tag if the current element doesn't have a closing // tag (i.e. void element) $end = (!empty($this->_[JMAP_HDOM_INFO_END])) ? $this->_[JMAP_HDOM_INFO_END] : 0; if ($end == 0) { $parent = $this->parent; while (!isset($parent->_[JMAP_HDOM_INFO_END]) && $parent !== null) { $end -= 1; $parent = $parent->parent; } $end += $parent->_[JMAP_HDOM_INFO_END]; } // Get list of target nodes $nodes_start = $this->_[JMAP_HDOM_INFO_BEGIN] + 1; $nodes_count = $end - $nodes_start; $nodes = array_slice($this->dom->nodes, $nodes_start, $nodes_count, true); } elseif ($parent_cmd === '>') { // Child Combinator $nodes = $this->children; } elseif ($parent_cmd === '+' && $this->parent && in_array($this, $this->parent->children)) { // Next-Sibling Combinator $index = array_search($this, $this->parent->children, true) + 1; $nodes[] = $this->parent->children[$index]; } elseif ($parent_cmd === '~' && $this->parent && in_array($this, $this->parent->children)) { // Subsequent Sibling Combinator $index = array_search($this, $this->parent->children, true); $nodes = array_slice($this->parent->children, $index); } // Go throgh each element starting at this element until the end tag // Note: If this element is a void tag, any previous void element is // skipped. foreach($nodes as $node) { $pass = true; // Skip root nodes if(!$node->parent) { $pass = false; } // Skip if node isn't a child node (i.e. text nodes) if($pass && !in_array($node, $node->parent->children, true)) { $pass = false; } // Skip if tag doesn't match if ($pass && $tag !== '' && $tag !== $node->tag && $tag !== '*') { $pass = false; } // Skip if ID doesn't exist if ($pass && $id !== '' && !isset($node->attr['id'])) { $pass = false; } // Check if ID matches if ($pass && $id !== '' && isset($node->attr['id'])) { // Note: Only consider the first ID (as browsers do) $nodeTemp = explode(' ', trim($node->attr['id'])); $node_id = $nodeTemp[0]; if($id !== $node_id) { $pass = false; } } // Check if all class(es) exist if ($pass && $class !== '' && is_array($class) && !empty($class)) { if (isset($node->attr['class'])) { $node_classes = explode(' ', $node->attr['class']); if ($lowercase) { $node_classes = array_map('strtolower', $node_classes); } foreach($class as $c) { if(!in_array($c, $node_classes)) { $pass = false; break; } } } else { $pass = false; } } // Check attributes if ($pass && $attributes !== '' && is_array($attributes) && !empty($attributes)) { foreach($attributes as $a) { list ( $att_name, $att_expr, $att_val, $att_inv, $att_case_sensitivity ) = $a; // Handle indexing attributes (i.e. "[2]") /** * Note: This is not supported by the CSS Standard but adds * the ability to select items compatible to XPath (i.e. * the 3rd element within it's parent). * * Note: This doesn't conflict with the CSS Standard which * doesn't work on numeric attributes anyway. */ if (is_numeric($att_name) && $att_expr === '' && $att_val === '') { $count = 0; // Find index of current element in parent foreach ($node->parent->children as $c) { if ($c->tag === $node->tag) ++$count; if ($c === $node) break; } // If this is the correct node, continue with next // attribute if ($count === (int)$att_name) continue; } // Check attribute availability if ($att_inv) { // Attribute should NOT be set if (isset($node->attr[$att_name])) { $pass = false; break; } } else { // Attribute should be set // todo: "plaintext" is not a valid CSS selector! if ($att_name !== 'plaintext' && !isset($node->attr[$att_name])) { $pass = false; break; } } // Continue with next attribute if expression isn't defined if ($att_expr === '') continue; // If they have told us that this is a "plaintext" // search then we want the plaintext of the node - right? // todo "plaintext" is not a valid CSS selector! if ($att_name === 'plaintext') { $nodeKeyValue = $node->text(); } else { $nodeKeyValue = $node->attr[$att_name]; } if (is_object($debug_object)) { $debug_object->debug_log(2, 'testing node: ' . $node->tag . ' for attribute: ' . $att_name . $att_expr . $att_val . ' where nodes value is: ' . $nodeKeyValue ); } // If lowercase is set, do a case insensitive test of // the value of the selector. if ($lowercase) { $check = $this->match( $att_expr, strtolower($att_val), strtolower($nodeKeyValue), $att_case_sensitivity ); } else { $check = $this->match( $att_expr, $att_val, $nodeKeyValue, $att_case_sensitivity ); } if (is_object($debug_object)) { $debug_object->debug_log(2, 'after match: ' . ($check ? 'true' : 'false') ); } if (!$check) { $pass = false; break; } } } // Found a match. Add to list and clear node if ($pass) $ret[$node->_[JMAP_HDOM_INFO_BEGIN]] = 1; unset($node); } // It's passed by reference so this is actually what this function returns. if (is_object($debug_object)) { $debug_object->debug_log(1, 'EXIT - ret: ', $ret); } } /** * Match value and pattern for a given CSS expression * * **Supported Expressions** * * | Expression | Description * | ---------- | ----------- * | `=` | $value and $pattern must be equal * | `!=` | $value and $pattern must not be equal * | `^=` | $value must start with $pattern * | `$=` | $value must end with $pattern * | `*=` | $value must contain $pattern * * @param string $exp The expression. * @param string $pattern The pattern * @param string $value The value * @value bool True if $value matches $pattern */ protected function match($exp, $pattern, $value, $case_sensitivity) { global $debug_object; if (is_object($debug_object)) {$debug_object->debug_log_entry(1);} if ($case_sensitivity === 'i') { $pattern = strtolower($pattern); $value = strtolower($value); } switch ($exp) { case '=': return ($value === $pattern); case '!=': return ($value !== $pattern); case '^=': return preg_match('/^' . preg_quote($pattern, '/') . '/', $value); case '$=': return preg_match('/' . preg_quote($pattern, '/') . '$/', $value); case '*=': return preg_match('/' . preg_quote($pattern, '/') . '/', $value); case '|=': /** * [att|=val] * * Represents an element with the att attribute, its value * either being exactly "val" or beginning with "val" * immediately followed by "-" (U+002D). */ return strpos($value, $pattern) === 0; case '~=': /** * [att~=val] * * Represents an element with the att attribute whose value is a * whitespace-separated list of words, one of which is exactly * "val". If "val" contains whitespace, it will never represent * anything (since the words are separated by spaces). Also if * "val" is the empty string, it will never represent anything. */ return in_array($pattern, explode(' ', trim($value)), true); } return false; } /** * Parse CSS selector * * @param string $selector_string CSS selector string * @return array List of CSS selectors. The format depends on the type of * selector: * * ```php * * array( // list of selectors (each separated by a comma), i.e. 'img, p, div' * array( // list of combinator selectors, i.e. 'img > p > div' * array( // selector element * [0], // (string) The element tag * [1], // (string) The element id * [2], // (array) The element classes * [3], // (array>) The list of attributes, each * // with four elements: name, expression, value, inverted * [4] // (string) The selector combinator (' ' | '>' | '+' | '~') * ) * ) * ) * ``` * * @link https://www.w3.org/TR/selectors/#compound Compound selector */ protected function parse_selector($selector_string) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } /** * Pattern of CSS selectors, modified from mootools (https://mootools.net/) * * Paperg: Add the colon to the attribute, so that it properly finds * like google does. * * Note: if you try to look at this attribute, you MUST use getAttribute * since $dom->x:y will fail the php syntax check. * * Notice the \[ starting the attribute? and the @? following? This * implies that an attribute can begin with an @ sign that is not * captured. This implies that an html attribute specifier may start * with an @ sign that is NOT captured by the expression. Farther study * is required to determine of this should be documented or removed. * * Matches selectors in this order: * * [0] - full match * * [1] - tag name * ([\w:\*-]*) * Matches the tag name consisting of zero or more words, colons, * asterisks and hyphens. * * [2] - id name * (?:\#([\w-]+)) * Optionally matches a id name, consisting of an "#" followed by * the id name (one or more words and hyphens). * * [3] - class names (including dots) * (?:\.([\w\.-]+))? * Optionally matches a list of classs, consisting of an "." * followed by the class name (one or more words and hyphens) * where multiple classes can be chained (i.e. ".foo.bar.baz") * * [4] - attributes * ((?:\[@?(?:!?[\w:-]+)(?:(?:[!*^$|~]?=)[\"']?(?:.*?)[\"']?)?(?:\s*?(?:[iIsS])?)?\])+)? * Optionally matches the attributes list * * [5] - separator * ([\/, >+~]+) * Matches the selector list separator */ // phpcs:ignore Generic.Files.LineLength $pattern = "/([\w:\*-]*)(?:\#([\w-]+))?(?:|\.([\w\.-]+))?((?:\[@?(?:!?[\w:-]+)(?:(?:[!*^$|~]?=)[\"']?(?:.*?)[\"']?)?(?:\s*?(?:[iIsS])?)?\])+)?([\/, >+~]+)/is"; preg_match_all( $pattern, trim($selector_string) . ' ', // Add final ' ' as pseudo separator $matches, PREG_SET_ORDER ); if (is_object($debug_object)) { $debug_object->debug_log(2, 'Matches Array: ', $matches); } $selectors = array(); $result = array(); foreach ($matches as $m) { $m[0] = trim($m[0]); // Skip NoOps if ($m[0] === '' || $m[0] === '/' || $m[0] === '//') { continue; } // Convert to lowercase if ($this->dom->lowercase) { $m[1] = strtolower($m[1]); } // Extract classes if ($m[3] !== '') { $m[3] = explode('.', $m[3]); } /* Extract attributes (pattern based on the pattern above!) * [0] - full match * [1] - attribute name * [2] - attribute expression * [3] - attribute value * [4] - case sensitivity * * Note: Attributes can be negated with a "!" prefix to their name */ if($m[4] !== '') { preg_match_all( "/\[@?(!?[\w:-]+)(?:([!*^$|~]?=)[\"']?(.*?)[\"']?)?(?:\s*?([iIsS])?)?\]/is", trim($m[4]), $attributes, PREG_SET_ORDER ); // Replace element by array $m[4] = array(); foreach($attributes as $att) { // Skip empty matches if(trim($att[0]) === '') { continue; } $inverted = (isset($att[1][0]) && $att[1][0] === '!'); $m[4][] = array( $inverted ? substr($att[1], 1) : $att[1], // Name (isset($att[2])) ? $att[2] : '', // Expression (isset($att[3])) ? $att[3] : '', // Value $inverted, // Inverted Flag (isset($att[4])) ? strtolower($att[4]) : '', // Case-Sensitivity ); } } // Sanitize Separator if ($m[5] !== '' && trim($m[5]) === '') { // Descendant Separator $m[5] = ' '; } else { // Other Separator $m[5] = trim($m[5]); } // Clear Separator if it's a Selector List if ($is_list = ($m[5] === ',')) { $m[5] = ''; } // Remove full match before adding to results array_shift($m); $result[] = $m; if ($is_list) { // Selector List $selectors[] = $result; $result = array(); } } if (count($result) > 0) { $selectors[] = $result; } return $selectors; } function __get($name) { if (isset($this->attr[$name])) { return $this->convert_text($this->attr[$name]); } switch ($name) { case 'outertext': return $this->outertext(); case 'innertext': return $this->innertext(); case 'plaintext': return $this->text(); case 'xmltext': return $this->xmltext(); default: return array_key_exists($name, $this->attr); } } function __set($name, $value) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } switch ($name) { case 'outertext': return $this->_[JMAP_HDOM_INFO_OUTER] = $value; case 'innertext': if (isset($this->_[JMAP_HDOM_INFO_TEXT])) { return $this->_[JMAP_HDOM_INFO_TEXT] = $value; } return $this->_[JMAP_HDOM_INFO_INNER] = $value; } if (!isset($this->attr[$name])) { $this->_[JMAP_HDOM_INFO_SPACE][] = array(' ', '', ''); $this->_[JMAP_HDOM_INFO_QUOTE][] = JMAP_HDOM_QUOTE_DOUBLE; } $this->attr[$name] = $value; } function __isset($name) { switch ($name) { case 'outertext': return true; case 'innertext': return true; case 'plaintext': return true; } //no value attr: nowrap, checked selected... return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]); } function __unset($name) { if (isset($this->attr[$name])) { unset($this->attr[$name]); } } // PaperG - Function to convert the text from one character set to another // if the two sets are not the same. function convert_text($text) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } $converted_text = $text; $sourceCharset = ''; $targetCharset = ''; if ($this->dom) { $sourceCharset = strtoupper($this->dom->_charset); $targetCharset = strtoupper($this->dom->_target_charset); } if (is_object($debug_object)) { $debug_object->debug_log(3, 'source charset: ' . $sourceCharset . ' target charaset: ' . $targetCharset ); } if (!empty($sourceCharset) && !empty($targetCharset) && (strcasecmp($sourceCharset, $targetCharset) != 0)) { // Check if the reported encoding could have been incorrect and the text is actually already UTF-8 if ((strcasecmp($targetCharset, 'UTF-8') == 0) && ($this->is_utf8($text))) { $converted_text = $text; } else { $converted_text = iconv($sourceCharset, $targetCharset, $text); } } // Lets make sure that we don't have that silly BOM issue with any of the utf-8 text we output. if ($targetCharset === 'UTF-8') { if (substr($converted_text, 0, 3) === "\xef\xbb\xbf") { $converted_text = substr($converted_text, 3); } if (substr($converted_text, -3) === "\xef\xbb\xbf") { $converted_text = substr($converted_text, 0, -3); } } return $converted_text; } /** * Returns true if $string is valid UTF-8 and false otherwise. * * @param mixed $str String to be tested * @return boolean */ static function is_utf8($str) { $c = 0; $b = 0; $bits = 0; $len = strlen($str); for($i = 0; $i < $len; $i++) { $c = ord($str[$i]); if($c > 128) { if(($c >= 254)) { return false; } elseif($c >= 252) { $bits = 6; } elseif($c >= 248) { $bits = 5; } elseif($c >= 240) { $bits = 4; } elseif($c >= 224) { $bits = 3; } elseif($c >= 192) { $bits = 2; } else { return false; } if(($i + $bits) > $len) { return false; } while($bits > 1) { $i++; $b = ord($str[$i]); if($b < 128 || $b > 191) { return false; } $bits--; } } } return true; } /** * Function to try a few tricks to determine the displayed size of an img on * the page. NOTE: This will ONLY work on an IMG tag. Returns false on all * other tag types. * * @author John Schlick * @version April 19 2012 * @return array an array containing the 'height' and 'width' of the image * on the page or -1 if we can't figure it out. */ function get_display_size() { global $debug_object; $width = -1; $height = -1; if ($this->tag !== 'img') { return false; } // See if there is aheight or width attribute in the tag itself. if (isset($this->attr['width'])) { $width = $this->attr['width']; } if (isset($this->attr['height'])) { $height = $this->attr['height']; } // Now look for an inline style. if (isset($this->attr['style'])) { // Thanks to user gnarf from stackoverflow for this regular expression. $attributes = array(); preg_match_all( '/([\w-]+)\s*:\s*([^;]+)\s*;?/', $this->attr['style'], $matches, PREG_SET_ORDER ); foreach ($matches as $match) { $attributes[$match[1]] = $match[2]; } // If there is a width in the style attributes: if (isset($attributes['width']) && $width == -1) { // check that the last two characters are px (pixels) if (strtolower(substr($attributes['width'], -2)) === 'px') { $proposed_width = substr($attributes['width'], 0, -2); // Now make sure that it's an integer and not something stupid. if (filter_var($proposed_width, FILTER_VALIDATE_INT)) { $width = $proposed_width; } } } // If there is a width in the style attributes: if (isset($attributes['height']) && $height == -1) { // check that the last two characters are px (pixels) if (strtolower(substr($attributes['height'], -2)) == 'px') { $proposed_height = substr($attributes['height'], 0, -2); // Now make sure that it's an integer and not something stupid. if (filter_var($proposed_height, FILTER_VALIDATE_INT)) { $height = $proposed_height; } } } } // Future enhancement: // Look in the tag to see if there is a class or id specified that has // a height or width attribute to it. // Far future enhancement // Look at all the parent tags of this image to see if they specify a // class or id that has an img selector that specifies a height or width // Note that in this case, the class or id will have the img subselector // for it to apply to the image. // ridiculously far future development // If the class or id is specified in a SEPARATE css file thats not on // the page, go get it and do what we were just doing for the ones on // the page. $result = array( 'height' => $height, 'width' => $width ); return $result; } // camel naming conventions function getAllAttributes() { return $this->attr; } function getAttribute($name) { return $this->__get($name); } function setAttribute($name, $value) { $this->__set($name, $value); } function hasAttribute($name) { return $this->__isset($name); } function removeAttribute($name) { $this->__set($name, null); } function getElementById($id) { return $this->find("#$id", 0); } function getElementsById($id, $idx = null) { return $this->find("#$id", $idx); } function getElementByTagName($name) { return $this->find($name, 0); } function getElementsByTagName($name, $idx = null) { return $this->find($name, $idx); } function parentNode() { return $this->parent(); } function childNodes($idx = -1) { return $this->children($idx); } function firstChild() { return $this->first_child(); } function lastChild() { return $this->last_child(); } function nextSibling() { return $this->next_sibling(); } function previousSibling() { return $this->prev_sibling(); } function hasChildNodes() { return $this->has_child(); } function nodeName() { return $this->tag; } function appendChild($node) { $node->parent($this); return $node; } } /** * simple html dom parser * * Paperg - in the find routine: allow us to specify that we want case * insensitive testing of the value of the selector. * * Paperg - change $size from protected to public so we can easily access it * * Paperg - added ForceTagsClosed in the constructor which tells us whether we * trust the html or not. Default is to NOT trust it. * * @package PlaceLocalInclude */ class JMapSimpleHtmlDom { /** * The root node of the document * * @var object */ public $root = null; /** * List of nodes in the current DOM * * @var array */ public $nodes = array(); /** * Callback function to run for each element in the DOM. * * @var callable|null */ public $callback = null; /** * Indicates how tags and attributes are matched * * @var bool When set to **true** tags and attributes will be converted to * lowercase before matching. */ public $lowercase = false; /** * Original document size * * Holds the original document size. * * @var int */ public $original_size; /** * Current document size * * Holds the current document size. The document size is determined by the * string length of ({@see JMapSimpleHtmlDom::$doc}). * * _Note_: Using this variable is more efficient than calling `strlen($doc)` * * @var int * */ public $size; /** * Current position in the document * * @var int */ protected $pos; /** * The document * * @var string */ protected $doc; /** * Current character * * Holds the current character at position {@see JMapSimpleHtmlDom::$pos} in * the document {@see JMapSimpleHtmlDom::$doc} * * _Note_: Using this variable is more efficient than calling * `substr($doc, $pos, 1)` * * @var string */ protected $char; protected $cursor; /** * Parent node of the next node detected by the parser * * @var object */ protected $parent; protected $noise = array(); /** * Tokens considered blank in HTML * * @var string */ protected $token_blank = " \t\r\n"; /** * Tokens to identify the equal sign for attributes, stopping either at the * closing tag ("/" i.e. "") or the end of an opening tag (">" i.e. * "") * * @var string */ protected $token_equal = ' =/>'; /** * Tokens to identify the end of a tag name. A tag name either ends on the * ending slash ("/" i.e. "") or whitespace ("\s\r\n\t") * * @var string */ protected $token_slash = " />\r\n\t"; /** * Tokens to identify the end of an attribute * * @var string */ protected $token_attr = ' >'; // Note that this is referenced by a child node, and so it needs to be // public for that node to see this information. public $_charset = ''; public $_target_charset = ''; /** * Innertext for
    elements * * @var string */ protected $default_br_text = ''; /** * Suffix for elements * * @var string */ public $default_span_text = ''; /** * Defines a list of self-closing tags (Void elements) according to the HTML * Specification * * _Remarks_: * - Use `isset()` instead of `in_array()` on array elements to boost * performance about 30% * - Sort elements by name for better readability! * * @link https://www.w3.org/TR/html HTML Specification * @link https://www.w3.org/TR/html/syntax.html#void-elements Void elements */ protected $self_closing_tags = array( 'area' => 1, 'base' => 1, 'br' => 1, 'col' => 1, 'embed' => 1, 'hr' => 1, 'img' => 1, 'input' => 1, 'link' => 1, 'meta' => 1, 'param' => 1, 'source' => 1, 'track' => 1, 'wbr' => 1 ); /** * Defines a list of tags which - if closed - close all optional closing * elements within if they haven't been closed yet. (So, an element where * neither opening nor closing tag is omissible consistently closes every * optional closing element within) * * _Remarks_: * - Use `isset()` instead of `in_array()` on array elements to boost * performance about 30% * - Sort elements by name for better readability! */ protected $block_tags = array( 'body' => 1, 'div' => 1, 'form' => 1, 'root' => 1, 'span' => 1, 'table' => 1 ); /** * Defines elements whose end tag is omissible. * * * key = Name of an element whose end tag is omissible. * * value = Names of elements whose end tag is omissible, that are closed * by the current element. * * _Remarks_: * - Use `isset()` instead of `in_array()` on array elements to boost * performance about 30% * - Sort elements by name for better readability! * * **Example** * * An `li` element’s end tag may be omitted if the `li` element is immediately * followed by another `li` element. To do that, add following element to the * array: * * ```php * 'li' => array('li'), * ``` * * With this, the following two examples are considered equal. Note that the * second example is missing the closing tags on `li` elements. * * ```html *
    • First Item
    • Second Item
    * ``` * *
    • First Item
    • Second Item
    * * ```html *
    • First Item
    • Second Item
    * ``` * *
    • First Item
    • Second Item
    * * @var array A two-dimensional array where the key is the name of an * element whose end tag is omissible and the value is an array of elements * whose end tag is omissible, that are closed by the current element. * * @link https://www.w3.org/TR/html/syntax.html#optional-tags Optional tags * * @todo The implementation of optional closing tags doesn't work in all cases * because it only consideres elements who close other optional closing * tags, not taking into account that some (non-blocking) tags should close * these optional closing tags. For example, the end tag for "p" is omissible * and can be closed by an "address" element, whose end tag is NOT omissible. * Currently a "p" element without closing tag stops at the next "p" element * or blocking tag, even if it contains other elements. * * @todo Known sourceforge issue #2977341 * B tags that are not closed cause us to return everything to the end of * the document. */ protected $optional_closing_tags = array( // Not optional, see // https://www.w3.org/TR/html/textlevel-semantics.html#the-b-element 'b' => array('b' => 1), 'dd' => array('dd' => 1, 'dt' => 1), // Not optional, see // https://www.w3.org/TR/html/grouping-content.html#the-dl-element 'dl' => array('dd' => 1, 'dt' => 1), 'dt' => array('dd' => 1, 'dt' => 1), 'li' => array('li' => 1), 'optgroup' => array('optgroup' => 1, 'option' => 1), 'option' => array('optgroup' => 1, 'option' => 1), 'p' => array('p' => 1), 'rp' => array('rp' => 1, 'rt' => 1), 'rt' => array('rp' => 1, 'rt' => 1), 'td' => array('td' => 1, 'th' => 1), 'th' => array('td' => 1, 'th' => 1), 'tr' => array('td' => 1, 'th' => 1, 'tr' => 1), ); function __construct( $str = null, $lowercase = true, $forceTagsClosed = true, $target_charset = JMAP_DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = JMAP_DEFAULT_BR_TEXT, $defaultSpanText = JMAP_DEFAULT_SPAN_TEXT, $options = 0) { if ($str) { if (preg_match('/^http:\/\//i', $str) || is_file($str)) { $this->load_file($str); } else { $this->load( $str, $lowercase, $stripRN, $defaultBRText, $defaultSpanText, $options ); } } // Forcing tags to be closed implies that we don't trust the html, but // it can lead to parsing errors if we SHOULD trust the html. if (!$forceTagsClosed) { $this->optional_closing_array = array(); } $this->_target_charset = $target_charset; } function __destruct() { $this->clear(); } // load html from string function load( $str, $lowercase = true, $stripRN = true, $defaultBRText = JMAP_DEFAULT_BR_TEXT, $defaultSpanText = JMAP_DEFAULT_SPAN_TEXT, $options = 0) { global $debug_object; // prepare $this->prepare($str, $lowercase, $defaultBRText, $defaultSpanText); // Per sourceforge http://sourceforge.net/tracker/?func=detail&aid=2949097&group_id=218559&atid=1044037 // Script tags removal now preceeds style tag removal. // strip out JS; } elseif ($gajsVersion == 'gtag') { $script = << window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '$gajsCode' $anonymizeGtagIp); JS2; } // Check if the tracking code must be injected, manipulate output JResponse if ($injectGaJs && $gajsCode) { if ($location == 'body') { $body = $app->getBody (); // Replace buffered main view contents at the body end $body = preg_replace ( '/<\/body>/i', $script . '', $body, 1 ); // Set the new JResponse contents $app->setBody ( $body ); } elseif ($location == 'head') { if ($doc->getType () === 'html') { $doc->addCustomTag ( $script ); } } } } /** * Handle the addition of the Matomo tracking code * * @access private * @param Object $app * @param Object $doc * @return void */ private function addMatomoTrackingCode($app, $doc) { // Get component params $injectMatomoJs = $this->jmapConfig->get ( 'inject_matomojs', 0 ); // Check if the tracking code must be injected, manipulate output Response if ($injectMatomoJs) { $matomoUrl = trim ( $this->jmapConfig->get ( 'matomo_url', '' ) ); $idSite = trim ( (int)$this->jmapConfig->get ( 'matomo_idsite', '' ) ); // Evaluate nonce csp feature $appNonce = $app->get('csp_nonce', null); $nonce = $appNonce ? ' nonce="' . $appNonce . '"' : ''; $script = << JS; if ($doc->getType () === 'html') { $doc->addCustomTag ( $script ); } } } /** * Handle the addition of the FBPixel tracking code * * @access private * @param Object $app * @param Object $doc * @return void */ private function addFBPixelTrackingCode($app, $doc) { // Get component params $injectFBPixelJs = $this->jmapConfig->get ( 'inject_fbpixel', 0 ); // Check if the tracking code must be injected, manipulate output Response if ($injectFBPixelJs) { $fbPixelId = trim ( $this->jmapConfig->get ( 'fbpixel_id', '' ) ); // Evaluate nonce csp feature $appNonce = $app->get('csp_nonce', null); $nonce = $appNonce ? ' nonce="' . $appNonce . '"' : ''; $script = << !function(f,b,e,v,n,t,s) {if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)}; if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0]; s.parentNode.insertBefore(t,s)}(window, document,'script', 'https://connect.facebook.net/en_US/fbevents.js'); fbq('init', '$fbPixelId'); fbq('track', 'PageView'); JS; if ($doc->getType () === 'html') { $doc->addCustomTag ( $script ); } } } /** * Performs the text replacement in the app body * * @access private * @return void */ private function patternReplacements () { $matchedPatterns = false; // Manage the patterns redirect $patternReplacementsQuery = "SELECT" . "\n " . $this->dbInstance->quoteName('original_text') . "," . "\n " . $this->dbInstance->quoteName('target_text') . "," . "\n " . $this->dbInstance->quoteName('original_text_regex') . "," . "\n " . $this->dbInstance->quoteName('target_text_regex') . "\n FROM" . "\n " . $this->dbInstance->quoteName('#__jmap_text_replacements') . "\n WHERE" . "\n" . $this->dbInstance->quoteName('published') . " = 1"; $patternReplacements = $this->dbInstance->setQuery ( $patternReplacementsQuery )->loadObjectList (); if (count ( $patternReplacements )) { // Get page body content $body = $this->appInstance->getBody (); foreach ($patternReplacements as $singlePattern) { // Is there a match with the current URL? if(preg_match('#' . $singlePattern->original_text_regex . '#iu', $body)) { $body = preg_replace('#' . $singlePattern->original_text_regex . '#iu', $singlePattern->target_text_regex, $body); $matchedPatterns = true; } } // Set the new Response contents if($matchedPatterns) { $this->appInstance->setBody ( $body ); } } } /** * Main dispatch method * * @param Event $event * @access public * @return boolean */ public function dispatchUtility(Event $event) { // Avoid operations if plugin is executed in backend if (!$this->appInstance->isClient('site')) { return; } // Security safe 1 - If JMAP internal link force always the lang url param using the cookie workaround if( $this->appInstance->getInput()->get ( 'option' ) == 'com_jmap' && $this->jmapConfig->get('advanced_multilanguage', 0)) { $lang = $this->appInstance->getInput()->get('lang'); $sefs = LanguageHelper::getLanguages('sef'); $lang_codes = LanguageHelper::getLanguages('lang_code'); if (isset($sefs[$lang])) { $lang_code = $sefs[$lang]->lang_code; // Create a cookie. $conf = $this->appInstance->getConfig(); $cookie_domain = $conf->get('config.cookie_domain', ''); $cookie_path = $conf->get('config.cookie_path', '/'); setcookie(ApplicationHelper::getHash('language'), $lang_code, 86400, $cookie_path, $cookie_domain); $this->appInstance->getInput()->cookie->set(ApplicationHelper::getHash('language'), $lang_code); // Set the request var. $this->appInstance->getInput()->set('language', $lang_code); // Check if remove default prefix is active and the default language is not the current one $defaultSiteLanguage = ComponentHelper::getParams('com_languages')->get('site', 'en-GB'); $pluginLangFilter = Joomla\CMS\Plugin\PluginHelper::getPlugin('system', 'languagefilter'); $removeDefaultPrefix = @json_decode($pluginLangFilter->params)->remove_default_prefix; if($removeDefaultPrefix && $defaultSiteLanguage != $lang_code) { $uri = Uri::getInstance(); $path = $uri->getPath(); // Force the language SEF code in the path $path = str_replace('/index.php', '/' . $lang . '/index.php', $path); $uri->setPath($path); } } } // Detect if current request come from a bot user agent if ($this->isBotRequest () && $this->appInstance->getInput()->get ( 'option' ) == 'com_jmap') { $_SERVER ['REQUEST_METHOD'] = 'POST'; // Set dummy nobot var $this->appInstance->getInput()->post->set ( 'nobotsef', true ); $GLOBALS['_' . strtoupper('post')] ['nobotsef'] = true; } } /** * Hook for the auto Pingomatic third party extensions that have not its own * route helper and work with the universal JSitemap route helper framework * * @param Event $event * @access public * @return boolean */ public function thirdPartyRoutePinging(Event $event) { // Security safe 2 - If JMAP internal link revert back the query string 'lang' param to the sef lang code 'en' instead of the iso lang code 'en-GB' $lang = $this->appInstance->getInput()->get('lang'); if($lang && $this->appInstance->getInput()->get ( 'option' ) == 'com_jmap' && $this->jmapConfig->get('advanced_multilanguage', 0) && strlen($lang) > 2) { $languageCode = $this->appInstance->getInput()->get('language'); $lang_codes = LanguageHelper::getLanguages('lang_code'); if(isset($lang_codes[$languageCode])) { $sefLang = $lang_codes[$languageCode]->sef; $this->appInstance->getInput()->set('lang', $sefLang); } } // Avoid below operations if the plugin is not executed in backend app if (!$this->appInstance->isClient('administrator')) { return; } // Redirect to the component configuration if the Joomla global configuration is requested instead $dispatchedComponent = $this->appInstance->getInput()->get ( 'option' ); $dispatchedView = $this->appInstance->getInput()->get ( 'view' ); $componentConfig = $this->appInstance->getInput()->get ( 'component' ); if($dispatchedComponent == 'com_config' && $dispatchedView == 'component' && $componentConfig == 'com_jmap') { $this->appInstance->redirect(Route::_('index.php?option=com_jmap&task=config.display', false)); return; } // Get component params if (! $this->jmapConfig->get ( 'default_autoping', 0 ) && ! $this->jmapConfig->get ( 'autoping', 0 )) { return; } // Retrieve more informations as much as possible from the current POST array $option = $this->appInstance->getInput()->get ( 'option' ); $view = $this->appInstance->getInput()->get ( 'view' ); $controller = $this->appInstance->getInput()->get ( 'controller' ); $task = $this->appInstance->getInput()->get ( 'task' ); $id = $this->appInstance->getInput()->getInt ( 'id' ); $catid = $this->appInstance->getInput()->get ( 'cid', null, 'array' ); $language = $this->appInstance->getInput()->get ( 'language' ); $name = $this->appInstance->getInput()->getString ( 'name' ); if (is_array ( $catid )) { $catid = $catid [0]; } // Valid execution mapping $arrayExecution = array ( 'com_zoo' => array ( 'controller' => 'item', 'task' => array ( 'apply', 'save', 'save2new', 'save2copy' ) ) ); // Test against valid execution, discard all invalid extensions operations if (array_key_exists ( $option, $arrayExecution )) { $testIfExecute = $arrayExecution [$option]; foreach ( $testIfExecute as $property => $value ) { $evaluated = $$property; if (is_array ( $value )) { if (! in_array ( $evaluated, $value )) { return; } } else { if ($evaluated != $value) { return; } } } } else { return; } // Valid execution success! Go on to route the request to the content plugin, mimic the native Joomla onContentAfterSave // Auto loader setup // Register autoloader prefix require_once JPATH_ADMINISTRATOR . '/components/com_jmap/Framework/Loader.php'; JMapLoader::setup(); JMapLoader::registerNamespacePsr4 ( 'JExtstore\\Component\\JMap\\Administrator', JPATH_ADMINISTRATOR . '/components/com_jmap' ); Joomla\CMS\Plugin\PluginHelper::importPlugin ( 'content', 'pingomatic', true, $this->appInstance->getDispatcher() ); // Simulate the jsitemap_category_id object for the JSitemap route helper $elm = new \stdClass (); $zooParams = $this->appInstance->getInput()->get ( 'params', null, 'array' ); $zooDetails = $this->appInstance->getInput()->get ( 'details', null, 'array' ); $elm->jsitemap_category_id = (int)$zooParams['primary_category']; // Simulate the $article Joomla object passed to the content observers $itemObject = new \stdClass (); $itemObject->id = $id; $itemObject->catid = $elm; $itemObject->option = $option; $itemObject->view = $view ? $view : $controller; $itemObject->language = $language; $itemObject->title = $name; // Setup the publish_up in UTC format $originalPublishUp = new DateTime($zooDetails['publish_up'], new DateTimeZone($this->joomlaConfig->get('offset'))); $originalPublishUp->setTimezone(new DateTimeZone("UTC")); $itemObject->publish_up = $originalPublishUp->format("Y-m-d H:i:s"); // Trigger the content plugin event $this->appInstance->getDispatcher ()->dispatch ( 'onContentAfterSave', new Event ( 'onContentAfterSave', [ 'com_zoo.item', $itemObject, false ] ) ); } /** * Hook for the management injection of the custom meta tags informations * * @param Event $event * @access public * @return void */ public function addHeadMetainfo(Event $event) { $document = $this->appInstance->getDocument(); // Avoid operations if plugin is executed in backend if (!$this->appInstance->isClient('site')) { return; } // Checkpoint for Google Analytics tracking code addition if($this->jmapConfig->get('inject_gajs', 0) && $this->jmapConfig->get('inject_gajs_location', 'body') == 'head') { $this->addGoogleAnalyticsTrackingCode($this->appInstance, $document, 'head'); } if($this->jmapConfig->get('inject_matomojs', 0)) { $this->addMatomoTrackingCode($this->appInstance, $document); } if($this->jmapConfig->get('inject_fbpixel', 0)) { $this->addFBPixelTrackingCode($this->appInstance, $document); } // Check if the robots opt-in directive is required if($this->jmapConfig->get('optin_contents', 0)) { $robots = trim($this->jmapConfig->get('optin_contents_robots_directive', 'max-snippet:-1,max-image-preview:large,max-video-preview:-1')); if($robots) { $currentMetaData = $document->getMetaData('robots'); if(StringHelper::strpos($currentMetaData, 'noindex') === false && StringHelper::strpos($currentMetaData, 'nosnippet') === false) { $document->setMetaData('robots', $robots); } } } // Get the current URI and check for an entry in the DB table if($this->jmapConfig->get('metainfo_urldecode', 1)) { $uri = urldecode(Uri::current()); } else { // Preserve URLs character encoding if any $uri = Uri::current(); } // Double check if there is a query string difference $uriInstanceString = (string)Uri::getInstance(); if(StringHelper::strpos($uriInstanceString, '?') !== false && $uri != $uriInstanceString) { // Get the current URI and check for an entry in the DB table if($this->jmapConfig->get('metainfo_urldecode', 1)) { $uri = urldecode($uriInstanceString); } else { // Preserve URLs character encoding if any $uri = $uriInstanceString; } } // K2 Tags decoding as an optional processing if($this->jmapConfig->get('metainfo_urlencode_space', 0)) { $uri = StringHelper::str_ireplace(' ', '%20', $uri); } // Remove trailing slash for URL matching, this ensure home page match if the option to remove ending slash is enabled if($this->jmapConfig->get('metainfo_remove_trailing_slash', 0)) { $uri = rtrim( $uri, '/' ); } // Apply same metadata even to the corresponding AMP pages if($this->jmapConfig->get('amp_sitemap_enabled', 0)) { $ampSuffix = $this->jmapConfig->get('amp_suffix', 'amp'); if(preg_match("/\.$ampSuffix\./i", $uri)) { $uri = preg_replace("/\.$ampSuffix\./i", '.', $uri, 1); } if(preg_match('/\/' . $ampSuffix . '$/i', $uri)) { $uri = preg_replace('/\/' . $ampSuffix . '$/i', '', $uri, 1); } } // Store for later stage processing $this->jmapUri = $uri; // Setup the query $query = "SELECT *" . "\n FROM #__jmap_metainfo" . "\n WHERE " . $this->dbInstance->quoteName('linkurl') . " = " . $this->dbInstance->quote($uri) . "\n AND " . $this->dbInstance->quoteName('published') . " = 1"; try { $metaInfoForThisUri = $this->dbInstance->setQuery($query)->loadObject(); } catch(\Exception $e) {} // Yes! Found some metainfo set for this uri, let's inject them into the document if(isset($metaInfoForThisUri->id)) { $title = trim($metaInfoForThisUri->meta_title); $description = trim($metaInfoForThisUri->meta_desc); $image = trim($metaInfoForThisUri->meta_image); $robots = $metaInfoForThisUri->robots; $ogTagsInclude = $this->jmapConfig->get('metainfo_ogtags', 1); $twitterCardsTagsInclude = $this->jmapConfig->get('metainfo_twitter_card_enable', 0); // Title and og:graph title if($title) { // Append site name if ($this->appInstance->get('sitename_pagetitles', 0) == 2 && trim($this->appInstance->get('sitename'))) { $title = $title . ' - ' . trim($this->appInstance->get('sitename')); } elseif ($this->appInstance->get('sitename_pagetitles', 0) == 1 && trim($this->appInstance->get('sitename'))) { // Prepend site name $title = trim($this->appInstance->get('sitename')) . ' - ' . $title; } $document->setTitle($title); $document->setMetaData('title', $title); $document->setMetaData('metatitle', $title); if($ogTagsInclude) { $document->setMetaData('og:title', $title, 'property'); $document->setMetaData('twitter:title', $title); } } // Description and og:graph meta description if($description) { $document->setDescription($description); if($ogTagsInclude) { $document->setMetaData('og:description', $description, 'property'); $document->setMetaData('twitter:description', $description); } } // Set always social share uri if title/desc is specified if(($title || $description) && $ogTagsInclude) { $document->setMetaData('og:url', $uri, 'property'); $document->setMetaData('og:type', 'article', 'property'); } // Image for social share og:image and twitter:image if($image && $ogTagsInclude) { $imageLink = preg_match('/http/i', $image) ? $image : Uri::base() . ltrim($image, '/'); $document->setMetaData('og:image', $imageLink, 'property'); $document->setMetaData('twitter:image', $imageLink); } // Robots directive if($robots) { $document->setMetaData('robots', $robots); } // Additional Twitter cards tags if($ogTagsInclude && $twitterCardsTagsInclude) { $document->setMetaData('twitter:card', 'summary'); $twitterCardSite = trim($this->jmapConfig->get('metainfo_twitter_card_site', '')); if($twitterCardSite) { $document->setMetaData('twitter:site', $twitterCardSite); } $twitterCardCreator = trim($this->jmapConfig->get('metainfo_twitter_card_creator', '')); if($twitterCardCreator) { $document->setMetaData('twitter:creator', $twitterCardCreator); } } } // Check if the override canonical feature is enabled and if so go on and check a url matching for some custom canonical if($this->jmapConfig->get('seospider_override_canonical', 1)) { $query = "SELECT *" . "\n FROM #__jmap_canonicals" . "\n WHERE " . $this->dbInstance->quoteName('linkurl') . " = " . $this->dbInstance->quote($uri); try { $canonicalForThisUri = $this->dbInstance->setQuery($query)->loadObject(); } catch(\Exception $e) {} // Yes! Found a canonical override set for this uri, let's replace them into the document if(isset($canonicalForThisUri->id)) { // Remove the current canonical tag from the document $header = $document->getHeadData(); foreach($header['links'] as $key => $array) { if($array['relation'] == 'canonical') { unset($document->_links[$key]); } } // Add the new overridden canonical link $document->addHeadLink(htmlspecialchars($canonicalForThisUri->canonical), 'canonical', 'rel', array('data-jmap-canonical-override'=>1)); // Override also the og:url metatag with the current canonical if(isset($title) && ($title || $description) && $ogTagsInclude) { $document->setMetaData('og:url', $canonicalForThisUri->canonical, 'property'); } } } // Fix pagination links if detected adding a page number/results suffix to make them unique and not duplicated $isPagination = $this->appInstance->getInput()->get->get('start', null, 'int'); $isPage = $this->appInstance->getInput()->get->get('page', null, 'int'); if($isPagination || $isPage) { $jmapParams = ComponentHelper::getParams('com_jmap'); // Fix pagination is enabled if($jmapParams->get('unique_pagination', 1)) { // Get dispatched component params with view overrides $contentParams = $this->appInstance->getParams(); // Load JMap language translations $jLang = $this->appInstance->getLanguage (); $jLang->load ( 'com_jmap', JPATH_ROOT . '/components/com_jmap', 'en-GB', true, true ); if ($jLang->getTag () != 'en-GB') { $jLang->load ( 'com_jmap', JPATH_SITE, null, true, false ); $jLang->load ( 'com_jmap', JPATH_SITE . '/components/com_jmap', null, true, false ); } // Check if pagination params are detected otherwise fallback $leadingNum = $contentParams->get('num_leading_articles', null); $introNum = $contentParams->get('num_intro_articles', null); if($leadingNum && $introNum) { $articlesPerPage = (int)($leadingNum + $introNum); $pageNum = ' - ' . Text::_('COM_JMAP_PAGE_NUMBER') . ((int)($isPagination / $articlesPerPage) + 1); } else { // Fallback for generic components staring from xxx if($isPage) { $pageNum = ' - ' . Text::_('COM_JMAP_PAGE_NUMBER') . (int)$isPage; } else { $pageNum = ' - ' . Text::_('COM_JMAP_RESULTS_FROM') . $isPagination; } } $currentTitle = $document->getTitle(); $document->setTitle($currentTitle . $pageNum); $currentDescription = $document->getDescription(); $document->setDescription($currentDescription . $pageNum); } } // Add script json+ld for Rich Snippet Searchbox ONLY to the website homepage if ($this->jmapConfig->get ( 'searchbox_enable', 0 )) { $loadedMenuItem = $this->appInstance->getMenu()->getActive(); if( $loadedMenuItem && $loadedMenuItem->home == 1 ) { $json = array (); $array = array (); $url = $this->jmapConfig->get ( 'searchbox_url', Uri::root () ); $type = $this->jmapConfig->get ( 'searchbox_type', 'finder' ); $custom = $this->jmapConfig->get ( 'searchbox_custom', '' ); $uriInstance = Uri::getInstance(); $getDomain = rtrim($uriInstance->getScheme() . '://' . $uriInstance->getHost(), '/'); // Register autoloader prefix require_once JPATH_ADMINISTRATOR . '/components/com_jmap/Framework/Loader.php'; JMapLoader::setup(); JMapLoader::registerNamespacePsr4 ( 'JExtstore\\Component\\JMap\\Administrator', JPATH_ADMINISTRATOR . '/components/com_jmap' ); $multiLanguageEnabled = JMapMultilang::isEnabled (); $currentSefLanguage = JMapMultilang::getCurrentSefLanguage () . '/'; if ($type == 'finder') { $smartSearchComponentLink = Route::_ ( 'index.php?option=com_finder&q={search_term}', false ); $smartSearchComponentLink = StringHelper::str_ireplace ( '/?', '?', $smartSearchComponentLink ); if ($multiLanguageEnabled) { $smartSearchComponentLink = StringHelper::str_ireplace ( $currentSefLanguage, '', $smartSearchComponentLink ); } $search = $getDomain . $smartSearchComponentLink; } else { $search = $custom; } $array ['@context'] = 'https://schema.org'; $array ['@type'] = 'WebSite'; $array ['url'] = $url; $array ['potentialAction'] ['@type'] = 'SearchAction'; $array ['potentialAction'] ['target'] = $search; $array ['potentialAction'] ['query-input'] = 'required name=search_term'; $document->getWebAssetManager()->addInlineScript ( json_encode ( $array ), [], ['type' => 'application/ld+json'] ); } } } /** * Hook for the management of the custom 404 page * * @param Event $event * @subparam $errorClass * @access public * @return boolean */ public function onExceptionHandler404Page(Event $event) { static $custom404Handled = false; // subparams: $form, $data $arguments = $event->getArguments(); $errorClass = $arguments['subject']; if($custom404Handled) { return false; } // Mark as handled for next execution cycles $custom404Handled = true; // Get component params and ensure that the custom 404 page is enabled $cParams = ComponentHelper::getParams('com_jmap'); if(!$cParams->get('custom_404_page_status', 0)) { return false; } // 404 custom page managed as an override by the postProcessParseRule if($cParams->get('custom_404_page_override', 1)) { return false; } // Execute only in frontend if (!$this->appInstance->isClient('site')) { return false; } // Dispatched format, apply only to html document $documentFormat = $this->appInstance->getInput()->get ( 'format', null ); if ($documentFormat && $documentFormat != 'html') { return false; } // Dispatched template file, ignores component tmpl if ($this->appInstance->getInput()->get ( 'tmpl', null ) === 'component') { return false; } if (!$errorClass instanceof RouteNotFoundException) { return false; } $documentRenderer = AbstractRenderer::getRenderer('html'); $document = $documentRenderer->getDocument(); // Evaluate the error code, 404 only is of our interest and ignore everything else // Generate and set a new custom error message based on custom text/html $custom404Text = $cParams->get('custom_404_page_text', null); // Process contents $custom404Text = $this->processContentPlugins($custom404Text, $cParams); // Check if a strip tags is required if($cParams->get('custom_404_page_mode', 'html') == 'text') { $custom404Text = strip_tags($custom404Text); } // Set the new Exception message supporting HTML and hoping that htmlspecialchars in not used by the error.php of the template try { $reflection = new \ReflectionProperty($errorClass, 'message'); $reflection->setAccessible(true); $reflection->setValue($errorClass, $custom404Text); } catch(\Exception $e) { $error = $e->getMessage(); } } /** * Application event * * @param Event $event * @access public */ public function refactorAppBody(Event $event) { // Framework reference $doc = $this->appInstance->getDocument (); // Check if the app can start if (!$this->appInstance->isClient('site')) { return false; } // Check if the app can start if ($doc->getType () !== 'html') { return false; } $option = $this->appInstance->getInput()->get('option', null); if ( $option == 'com_jmap' && $this->appInstance->getInput()->get('format') ) { return false; } // Check if the override headings feature is enabled and if so go on and check a url matching for some heading if($this->jmapConfig->get('seospider_override_headings', 1)) { // Search an headings override for this URL $query = "SELECT *" . "\n FROM #__jmap_headings" . "\n WHERE " . $this->dbInstance->quoteName('linkurl') . " = " . $this->dbInstance->quote($this->jmapUri); try { $headingsForThisUri = $this->dbInstance->setQuery($query)->loadObject(); } catch(\Exception $e) {} // Yes! Found some headings override set for this uri, let's replace them into the document if(isset($headingsForThisUri->id)) { // Go on only if there is at least one valid heading override if($headingsForThisUri->h1 || $headingsForThisUri->h2 || $headingsForThisUri->h3) { // Include DOM parser class require_once (JPATH_ROOT . '/plugins/system/jmap/simplehtmldom.php'); $simpleHtmlDomInstance = new \JMapSimpleHtmlDom(); $simpleHtmlDomInstance->load( $this->appInstance->getBody () ); // Find and replace the first encountered H1 tag if($headingsForThisUri->h1) { $domElementsH1 = $simpleHtmlDomInstance->find( 'h1' ); // Replace the original H1 header with the overridden one if(isset($domElementsH1[0])) { $element = $domElementsH1[0]; $nodeText = $element->text(true); $nodeText = $headingsForThisUri->h1; $element->innertext = $nodeText; $element->setAttribute('data-jmap-heading-override', 1); } } // Find and replace the first encountered H2 tag if($headingsForThisUri->h2) { $domElementsH2 = $simpleHtmlDomInstance->find( 'h2' ); // Replace the original H2 header with the overridden one if(isset($domElementsH2[0])) { $element = $domElementsH2[0]; $nodeText = $element->text(true); $nodeText = $headingsForThisUri->h2; $element->innertext = $nodeText; $element->setAttribute('data-jmap-heading-override', 1); } } // Find and replace the first encountered H3 tag if($headingsForThisUri->h3) { $domElementsH3 = $simpleHtmlDomInstance->find( 'h3' ); // Replace the original H3 header with the overridden one if(isset($domElementsH3[0])) { $element = $domElementsH3[0]; $nodeText = $element->text(true); $nodeText = $headingsForThisUri->h3; $element->innertext = $nodeText; $element->setAttribute('data-jmap-heading-override', 1); } } $body = $simpleHtmlDomInstance->save(); // Final assignment $this->appInstance->setBody ( $body ); } } } // Checkpoint for Google Analytics tracking code addition if($this->jmapConfig->get('inject_gajs', 0) && $this->jmapConfig->get('inject_gajs_location', 'body') == 'body') { $this->addGoogleAnalyticsTrackingCode($this->appInstance, $doc, 'body'); } if($this->jmapConfig->get('inject_matomojs', 0)) { $this->addMatomoTrackingCode($this->appInstance, $doc); } if($this->jmapConfig->get('inject_fbpixel', 0)) { $this->addFBPixelTrackingCode($this->appInstance, $doc); } if($this->jmapConfig->get('enable_pattern_replacements', 'enabled') == 'enabled') { $this->patternReplacements(); } } /** * Preprocess dummy to load language files * * @param Event $event * @subparam Joomla\CMS\Form\Form $form * @subparam object $data * @access public * @return boolean */ public function loadModulesLanguageFiles(Event $event) { // subparams: $form, $data $arguments = $event->getArguments(); $form = $arguments[0]; $data = $arguments[1]; // Manage partial language translations if editing modules jmap in backend if((($this->appInstance->getInput()->get('option') == 'com_modules' || $this->appInstance->getInput()->get('option') == 'com_advancedmodules') && $this->appInstance->getInput()->get('view') == 'module' && $this->appInstance->getInput()->get('layout') == 'edit' && $this->appInstance->isClient ('administrator')) || ($this->appInstance->getInput()->get('option') == 'com_config' && $this->appInstance->getInput()->get('view') == 'modules' && $this->appInstance->getInput()->get('id') && $this->appInstance->isClient ('site'))) { $jLang = $this->appInstance->getLanguage (); $jLang->load ( 'com_jmap', JPATH_ADMINISTRATOR . '/components/com_jmap', 'en-GB', true, true ); if ($jLang->getTag () != 'en-GB') { $jLang->load ( 'com_jmap', JPATH_ADMINISTRATOR, null, true, false ); $jLang->load ( 'com_jmap', JPATH_ADMINISTRATOR . '/components/com_jmap', null, true, false ); } } // Check if the default merge data source feature is enabled $cParams = ComponentHelper::getParams('com_jmap'); if(!$cParams->get('merge_generic_menu_by_class', 0)) { return true; } // Only works on JForms if (!($form instanceof \Joomla\CMS\Form\Form)) return true; // which belong to the following components $components_list = array( "com_menus.item" ); $formName = $form->getName(); if ($this->appInstance->isClient('site') || !in_array($formName, $components_list)) return true; if(!isset($data->type) || (isset($data->type) && $data->type != 'component')) return true; switch ($formName) { case 'com_menus.item': $form->load('
    '); break; } return true; } /** * Integration for components performing route helper directly in the main router such as Virtuemart * The component router must be executed BEFORE the SiteRouter::buildSefRoute to allow the Itemid to be already found by the crouter * * @param &$router Router object * @param &$uri Uri object * @access public * @return void */ public function preProcessBuildRule(&$router, &$uri) { $option = $this->appInstance->getInput()->get ( 'option' ); $urlOption = $uri->getVar('option'); if (!$this->appInstance->isClient ('site') || !array_key_exists($urlOption, $this->appInstance->get('jmap_croute_helpers_preprocess', []))) { return; } $originalUri = clone ($uri); $query = $originalUri->getQuery ( true ); // Build the component route $component = preg_replace ( '/[^A-Z0-9_\.-]/i', '', $query ['option'] ); $crouter = $router->getComponentRouter ( $component ); $crouter->build ( $query ); if (! empty ( $query ['Itemid'] ) && $query ['Itemid'] != $uri->getVar ( 'Itemid' )) { $uri->setVar ( 'Itemid', $query ['Itemid'] ); } } /** * Support for new routing throwing 404 exception in the parse function of the base router * * @param &$router Router object * @param &$uri Uri object * @access public * @return boolean */ public function postProcessParseRule(&$router, &$uri) { // Dispatched format, apply only to html document $documentFormat = $this->appInstance->getInput()->get ( 'format', null ); if ($documentFormat && $documentFormat != 'html') { return false; } // Dispatched template file, ignores component tmpl if ($this->appInstance->getInput()->get ( 'tmpl', null ) === 'component') { return false; } $siteRouter = Factory::getContainer()->has('SiteRouter') ? Factory::getContainer()->get('SiteRouter') : SiteRouter::getInstance ( 'site' ); $option = $siteRouter->getVar('option') ? : $uri->getVar('option'); // Check if all parts of the URL have been parsed. // Otherwise we have an invalid URL if ($option == 'com_content' && strlen($uri->getPath()) > 0) { // Get component params and ensure that the custom 404 page is enabled $cParams = ComponentHelper::getParams('com_jmap'); // Generate and set a new custom error message based on custom text/html $custom404Text = $cParams->get('custom_404_page_text', null); // Process contents $custom404Text = $this->processContentPlugins($custom404Text, $cParams); // Check if a strip tags is required if($cParams->get('custom_404_page_mode', 'html') == 'text') { $custom404Text = strip_tags($custom404Text); } throw new \Exception($custom404Text, 404); } } /** * Event to manipulate the menu item dashboard in backend * * @param Event $event * @subparam array &$policy The privacy policy status data, passed by reference, with keys "published" and "editLink" * * @return void */ public function processMenuItemsDashboard(Event $event) { static $updaterScript; // Exclude always other than administrator client if (!$this->appInstance->isClient ('administrator')) { return; } // subparams: $policy $arguments = $event->getArguments(); $context = &$arguments[0]; $items = &$arguments[1]; if(!empty($items) && $context == 'administrator.module.mod_submenu') { foreach ($items as &$item) { if($item->element == 'com_jmap') { $item->img = Uri::base() . 'components/com_jmap/images/jmap-16x16.png'; $item->title = 'COM_JMAP_DASHBOARD_TITLE'; } } } // Kill com_joomlaupdate informations about extensions missing updater info, leave only main one $document = $this->appInstance->getDocument(); if(!$this->appInstance->get('jextstore_joomlaupdate_script') && $this->appInstance->getInput()->get('option') == 'com_joomlaupdate' && !$this->appInstance->getInput()->get('view') && !$this->appInstance->getInput()->get('task')) { $document->getWebAssetManager()->addInlineScript (" window.addEventListener('DOMContentLoaded', function(e) { if(document.querySelector('#preupdatecheck')) { var jextensionsIntervalCount = 0; var jextensionsIntervalTimer = setInterval(function() { [].slice.call(document.querySelectorAll('#compatibilityTable1 tbody tr th.exname')).forEach(function(th) { let txt = th.innerText; if (txt && txt.toLowerCase().match(/jsitemap|gdpr|responsivizer|jchatsocial|jcomment|jrealtime|jspeed|jredirects|vsutility|visualstyles|visual\sstyles|instant\sfacebook\slogin|instantpaypal|screen\sreader|jspeed|jamp/i)) { th.parentElement.style.display = 'none'; th.parentElement.classList.remove('error'); th.parentElement.classList.add('jextcompatible'); } }); [].slice.call(document.querySelectorAll('#compatibilityTable2 tbody tr th.exname')).forEach(function(th) { let txt = th.innerText; if (txt && txt.toLowerCase().match(/jsitemap|gdpr|responsivizer|jchatsocial|jcomment|jrealtime|jspeed|jredirects|vsutility|visualstyles|visual\sstyles|instant\sfacebook\slogin|instantpaypal|screen\sreader|jspeed|jamp/i)) { th.parentElement.classList.remove('error'); th.parentElement.classList.add('jextcompatible'); let smallDiv = th.querySelector(':scope div.small'); if(smallDiv) { smallDiv.style.display = 'none'; } } }); if (document.querySelectorAll('#compatibilityTable0 tbody tr').length == 0 && document.querySelectorAll('#compatibilityTable1 tbody tr:not(.jextcompatible)').length == 0 && document.querySelectorAll('#compatibilityTable2 tbody tr:not(.jextcompatible)').length == 0) { [].slice.call(document.querySelectorAll('#preupdatecheckbox, #preupdateCheckCompleteProblems')).forEach(function(element) { element.style.display = 'none'; }); if(document.querySelector('#noncoreplugins')) { document.querySelector('#noncoreplugins').checked = true; } if(document.querySelector('button.submitupdate')) { document.querySelector('button.submitupdate').disabled = false; document.querySelector('button.submitupdate').classList.remove('disabled'); } if(document.querySelector('#joomlaupdate-precheck-extensions-tab span.fa')) { let tabIcon = document.querySelector('#joomlaupdate-precheck-extensions-tab span.fa'); tabIcon.classList.remove('fa-times'); tabIcon.classList.remove('text-danger'); tabIcon.classList.remove('fa-exclamation-triangle'); tabIcon.classList.remove('text-warning'); tabIcon.classList.add('fa-check'); tabIcon.classList.add('text-success'); } }; if (document.querySelectorAll('#compatibilityTable0 tbody tr').length == 0) { if(document.querySelectorAll('#compatibilityTable1 tbody tr:not(.jextcompatible)').length == 0) { let compatibilityTable1 = document.querySelector('#compatibilityTable1'); if(compatibilityTable1) { compatibilityTable1.style.display = 'none'; } } clearInterval(jextensionsIntervalTimer); } jextensionsIntervalCount++; }, 1000); }; });"); $this->appInstance->set('jextstore_joomlaupdate_script', true); } } /** Manage the Joomla updater based on the user license * * @param Event $event * @subparam string The $url for the package update download * @subparam array The headers array. * @access public * @return void */ public function jmapUpdateInstall(Event $event) { // subparams: &$url, &$headers $arguments = $event->getArguments(); $url = &$arguments[0]; $headers = &$arguments[1]; $uri = Uri::getInstance($url); $parts = explode('/', $uri->getPath()); if ($uri->getHost() == 'storejextensions.org' && in_array('com_jsitemap.zip', $parts)) { // Init as false unless the license is valid $validUpdate = false; // Manage partial language translations $jLang = $this->appInstance->getLanguage(); $jLang->load('com_jmap', JPATH_BASE . '/components/com_jmap', 'en-GB', true, true); if($jLang->getTag() != 'en-GB') { $jLang->load('com_jmap', JPATH_BASE, null, true, false); $jLang->load('com_jmap', JPATH_BASE . '/components/com_jmap', null, true, false); } // Email license validation API call and &$url building construction override $cParams = ComponentHelper::getParams('com_jmap'); $registrationEmail = $cParams->get('registration_email', null); // License if($registrationEmail) { $prodCode = 'jsitemappro'; $cdFuncUsed = 'str_' . 'ro' . 't' . '13'; // Retrieve license informations from the remote REST API $apiResponse = null; $apiEndpoint = $cdFuncUsed('uggc' . '://' . 'fgberwrkgrafvbaf' . '.bet') . "/option,com_easycommerce/action,licenseCode/email,$registrationEmail/productcode,$prodCode"; if (function_exists('curl_init')){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $apiEndpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $apiResponse = curl_exec($ch); curl_close($ch); } $objectApiResponse = json_decode($apiResponse); if(!is_object($objectApiResponse)) { // Message user about error retrieving license informations $this->appInstance->enqueueMessage(Text::_('COM_JMAP_ERROR_RETRIEVING_LICENSE_INFO')); } else { if(!$objectApiResponse->success) { switch ($objectApiResponse->reason) { // Message user about the reason the license is not valid case 'nomatchingcode': $this->appInstance->enqueueMessage(Text::_('COM_JMAP_LICENSE_NOMATCHING')); break; case 'expired': // Message user about license expired on $objectApiResponse->expireon $this->appInstance->enqueueMessage(Text::sprintf('COM_JMAP_LICENSE_EXPIRED', $objectApiResponse->expireon)); break; } } // Valid license found, builds the URL update link and message user about the license expiration validity if($objectApiResponse->success) { $url = $cdFuncUsed('uggc' . '://' . 'fgberwrkgrafvbaf' . '.bet' . '/XZY1406TSPQnifs3243560923kfuxnj35td1rtt45664f.ugzy'); $validUpdate = true; $this->appInstance->enqueueMessage(Text::sprintf('COM_JMAP_EXTENSION_UPDATED_SUCCESS', $objectApiResponse->expireon)); } } } else { // Message user about missing email license code $this->appInstance->enqueueMessage(Text::sprintf('COM_JMAP_MISSING_REGISTRATION_EMAIL_ADDRESS', OutputFilter::ampReplace('index.php?option=com_jmap&task=config.display#_licensepreferences'))); } if(!$validUpdate) { $this->appInstance->enqueueMessage(Text::_('COM_JMAP_UPDATER_STANDARD_ADVISE'), 'notice'); } } } /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.0.0 */ public static function getSubscribedEvents(): array { return [ 'onAfterInitialise' => 'dispatchUtility', 'onAfterRoute' => 'thirdPartyRoutePinging', 'onBeforeCompileHead' => 'addHeadMetainfo', 'onError' => 'onExceptionHandler404Page', 'onAfterRender' => 'refactorAppBody', 'onContentPrepareForm' => 'loadModulesLanguageFiles', 'onPreprocessMenuItems' => 'processMenuItemsDashboard', 'onInstallerBeforePackageDownload' => 'jmapUpdateInstall' ]; } /** * Override registers Listeners to the Dispatcher * It allows to stop a plugin execution based on the return value of its constructor * * @override * @return void */ public function registerListeners(?DispatcherInterface $dispatcher = null) { // Check if the plugin has not been stopped by the constructor if(!$this->isPluginStopped) { parent::registerListeners($dispatcher); } } /** * Class constructor, manage params from component * * @access private * @return boolean */ public function __construct(& $subject, $config = array()) { parent::__construct ( $subject, $config ); // Init application $this->appInstance = Factory::getApplication(); // Init database $this->dbInstance = Factory::getContainer()->get('DatabaseDriver'); // Exclude always the api client if ($this->appInstance->isClient ('api') || $this->appInstance->isClient ('cli')) { $this->isPluginStopped = true; return; } $this->joomlaConfig = $this->appInstance->getConfig (); // Set the error handler for E_ERROR to be the class handleError method. $cParams = ComponentHelper::getParams('com_jmap'); $this->jmapConfig = $cParams; // Add compatibility support for third-party components performing inner routing helper $joomlaRouter = Factory::getContainer()->has('SiteRouter') ? Factory::getContainer()->get('SiteRouter') : $this->appInstance::getRouter(); if($this->appInstance->getInput()->get('format') != 'json' && $this->appInstance->isClient('site')) { $joomlaRouter->attachBuildRule ( array ( $this, 'preProcessBuildRule' ), \Joomla\CMS\Router\Router::PROCESS_BEFORE ); } if($cParams->get('custom_404_page_status', 0) && $cParams->get('custom_404_page_override', 1) && $this->appInstance->isClient('site')) { // Add compatibility support for new router management $joomlaRouter->attachParseRule ( array ( $this, 'postProcessParseRule' ), \Joomla\CMS\Router\Router::PROCESS_AFTER ); } } }PK!#o,,system/jmap/index.htmlnu[PK!M"system/metaman/install.phpnu[$key)) { return $object->$key; } return $default; } /** * Binds an array of data into the table * * @since 2.0 * @access public */ public function bindData($data, $type) { unset($data['task']); unset($data['mm']); unset($data['type']); $this->raw_url = $this->normalize($data, 'url', ''); unset($data['url']); $this->hash = $this->normalize($data, 'hash', ''); unset($data['hash']); // Try to get existing meta $meta = $this->getMeta($type); $registry = new JRegistry($data); if (!$meta) { $this->$type = $registry->toString(); } else { foreach ($data as $key => $value) { $meta->set($key, $value); } $registry = $meta; } $this->$type = $registry->toString(); $this->created_by = JFactory::getUser()->id; $this->created = JFactory::getDate()->toSql(); } /** * Retrieves the image for the respective rich snippet * * @since 1.0.0 * @access public */ public function getImage($type) { $meta = $this->getMeta($type); return $meta->get('image_uri', false); } /** * Retrieves the image for the respective rich snippet * * @since 1.0.0 * @access public */ public function getImagePath($type) { $meta = $this->getMeta($type); return $meta->get('image_absolute', false); } /** * Retrieves the meta data from the table * * @since 1.0.0 * @access public */ public function getMeta($type) { if (!$this->$type) { return false; } $registry = new JRegistry($this->$type); return $registry; } } PK!BԠ system/metaman/tables/table.phpnu[ $value) { if ($key != $this->_tbl_key && strpos($key, '_') !== 0) { // For Joomla 4, it does not convert array / objects into json strings if (is_object($value) || is_array($value)) { $this->$key = json_encode($value); } // For Joomla 4, it does not convert the boolean value into 1 / 0 if (is_bool($value)) { $this->$key = $value ? 1 : 0; } } } return parent::store($updateNulls); } /** * Method to reset class properties to the defaults set in the class * definition. It will ignore the primary key as well as any private class * properties. * * @return void * * @link http://docs.joomla.org/JTable/reset * @since 11.1 */ public function reset() { $properties = get_object_vars($this); $columns = []; foreach ($properties as $key => $value) { if ($key != $this->_tbl_key && strpos($key, '_') !== 0) { $columns[] = $value; } } return $columns; } }PK!/77system/metaman/metaman.phpnu[baseurl = JURI::root(true); parent::__construct($subject, $config); $this->doc = JFactory::getDocument(); $this->app = JFactory::getApplication(); $this->input = $this->app->input; $this->my = JFactory::getUser(); // Load language string JFactory::getLanguage()->load('plg_system_metaman', JPATH_ADMINISTRATOR); } /** * System event for Joomla 3.x * * @since 1.0.0 * @access public */ public function onAfterDispatch() { // This plugin should only work on html documents if ($this->doc->getType() !== 'html') { return; } // Skip com_media $tmpl = $this->input->get('tmpl', '', 'string'); if ($tmpl === 'component') { return; } // We don't want this on the admin if (MM::isFromAdmin()) { return; } // If the user is not logged in, skip this if ($this->my->guest) { return; } // Check if this person is a site admin if (!MM::hasAccess($this->params)) { return; } // to determine if metaman should be visible to site admins or not. // #35 $showadmin = $this->params->get('showforadmin', true); if (!$showadmin) { return; } $requirejQuery = MM::requirejQuery(); // Determines if we need to load jquery $jquery = $this->params->get('jquery_enable', false); $script = $this->baseurl . '/plugins/system/metaman/assets/scripts/jquery-3.1.0.min.js'; // Ensure that jQuery is enabled on the site if ($requirejQuery) { $this->doc->addScript($script); } if (!$requirejQuery) { // for some reason need to load own jQuery because conflict with some of the template if ($jquery) { $this->doc->addScript($script); } else { MM::renderjQueryFramework(); } } // Listens to JSON requests. This needs to be first, to avoid conflicting output with ourselves $this->listen(); // Attach the headers data on the page $this->attachHeaders(); } /** * System event to generate page header data * * @since 2.0 * @access public */ public function onBeforeCompileHead() { // This plugin should only work on html documents if ($this->doc->getType() !== 'html') { return; } // We don't want this on the admin if (MM::isFromAdmin()) { return; } // check if canonical exist to avoid duplicate. #34 $hash = MM::getCanonicalHashUrl($this->doc); // Get the current hash if (!$hash) { $hash = MM::getCurrentHashUrl(); } $table = MM::table('Meta'); $table->load(['hash' => $hash]); // Get the meta data and inject on the page $meta = $table->getMeta('meta'); if ($meta) { $title = $meta->get('title', ''); if ($title) { $this->doc->setTitle($title); } if ($meta->get('description', '')) { $this->doc->setMetaData('description', $meta->get('description')); } if ($meta->get('canonical', '')) { $this->doc->addHeadLink(htmlspecialchars($meta->get('canonical')), 'canonical'); } if ($meta->get('author', '')) { $this->doc->setMetaData('author', $meta->get('author')); } if ($meta->get('keywords', '')) { $this->doc->setMetaData('keywords', $meta->get('keywords')); } if ($meta->get('generator', '')) { $this->doc->setMetaData('generator', $meta->get('generator')); } if ($meta->get('robots', '')) { $this->doc->setMetaData('robots', $meta->get('robots')); } } // Get twitter card $card = $table->getMeta('card'); if ($card) { $cardType = $card->get('card', ''); $title = $card->get('title', ''); $handle = $card->get('site', '@' . $this->params->get('twitter_handle')); $description = $card->get('description', ''); $image = $table->getImage('card'); $this->doc->setMetaData('twitter:card', $cardType); $this->doc->setMetaData('twitter:site', $handle); $this->doc->setMetaData('twitter:title', $title); $this->doc->setMetaData('twitter:description', htmlspecialchars($description)); if ($image) { $this->doc->setMetaData('twitter:image', $image); } } else { if ($this->params->get('twitter_handle', '')) { $this->doc->setMetaData('twitter:site', '@' . $this->params->get('twitter_handle')); } } // Get opengraph data $opengraph = $table->getMeta('opengraph'); if ($opengraph) { $url = $opengraph->get('ogurl'); if ($url) { $this->doc->setMetaData('og:url', $url, 'property'); } $title = $opengraph->get('title'); if ($title) { $this->doc->setMetaData('og:title', $title, 'property'); } $description = $opengraph->get('description'); if ($description) { $this->doc->setMetaData('og:description', $description, 'property'); } $ogType = $opengraph->get('ogtype'); if ($ogType) { $this->doc->setMetaData('og:type', $ogType, 'property'); } $profileId = $opengraph->get('profile_id', $this->params->get('facebook_profile_id', '')); if ($profileId) { $this->doc->setMetaData('fb:profile_id', $profileId, 'property'); } $appId = $opengraph->get('app_id', $this->params->get('facebook_app_id', '')); if ($appId) { $this->doc->setMetaData('fb:app_id', $appId, 'property'); } $site = $opengraph->get('ogsite_name'); if ($site) { $this->doc->setMetaData('og:site_name', $site, 'property'); } $image = $table->getImage('opengraph'); if ($image) { $this->doc->setMetaData('og:image', $image, 'property'); } $imageWidth = $opengraph->get('image_width', ''); if ($imageWidth) { $this->doc->setMetaData('og:image:width', $imageWidth, 'property'); } $imageHeight = $opengraph->get('image_height', ''); if ($imageHeight) { $this->doc->setMetaData('og:image:height', $imageHeight, 'property'); } // video $video = $opengraph->get('video', ''); if ($video) { $this->doc->setMetaData('og:video', $video, 'property'); } $videoType = $opengraph->get('video_type', ''); if ($videoType) { $this->doc->setMetaData('og:video:type', $videoType, 'property'); } $videoWidth = $opengraph->get('video_width', ''); if ($videoWidth) { $this->doc->setMetaData('og:video:width', $videoWidth, 'property'); } $videoHeight = $opengraph->get('video_height', ''); if ($videoHeight) { $this->doc->setMetaData('og:video:height', $videoHeight, 'property'); } } else { if ($this->params->get('facebook_app_id', '')) { $this->doc->setMetaData('fb:app_id', $this->params->get('facebook_app_id'), 'property'); } if ($this->params->get('facebook_profile_id', '')) { $this->doc->setMetaData('fb:profile_id', $this->params->get('facebook_profile_id'), 'property'); } } } /** * Listens to JSON requests * * @since 1.0.0 * @access public */ public function listen() { $isJsonRequest = $this->input->get('mm', false, 'bool'); if (!$isJsonRequest) { return; } $task = $this->input->get('task', '', 'cmd'); if ($task == 'form') { // Determines which form we should be loading $form = $this->input->get('form', 'meta', 'string'); $output = $this->getForm($form); $this->setData('code', 200); $this->setData('html', $output); return $this->output(); } if ($task == 'save') { $state = $this->save(); if (!$state) { return $this->error('PLG_MM_SAVE_FAILED'); } $this->setData('code', 200); $this->setData('message', JText::_('PLG_MM_SAVE_SUCCESS')); return $this->output(); } // File uploads. Most likely image if ($task == 'upload') { return $this->upload(); } // Remove an image if ($task == 'removeImage') { return $this->removeImage(); } if ($task == 'remove') { return $this->remove(); } return $this->error(JText::_('PLG_MM_ERROR_JSON')); } /** * Attaches headers on the page * * @since 1.0.0 * @access public */ public function attachHeaders() { // Attach css files $css = '/plugins/system/metaman/assets/styles/style.css'; $this->doc->addStylesheet($this->baseurl . $css); // Attach our scripts $script = '/plugins/system/metaman/assets/scripts/script.js'; $this->doc->addScript($this->baseurl . $script); // We need to tell the scripts the current location of the page $url = MM::getCurrentRawUrl(); $hash = MM::getCurrentHashUrl(); // Api key $apiKey = '8e4096fcf7747d8a90e8f470457e3d9d'; $ajaxUrl = MM::getAjaxURL(); $this->doc->setMetaData('mm_ajax_url', $ajaxUrl); $this->doc->setMetaData('mm_base_url', $this->baseurl); $this->doc->setMetaData('mm_apikey', $apiKey); $this->doc->setMetaData('mm_hash', $hash); $this->doc->setMetaData('mm_url', $url); $this->doc->setMetaData('mm_card', $this->params->get('card_button', 1) ? "1" : "0"); $this->doc->setMetaData('mm_opengraph', $this->params->get('opengraph_button', 1) ? "1" : "0"); $this->doc->setMetaData('mm_meta', $this->params->get('meta_button', 1) ? "1" : "0"); } /** * Saves the meta of the site * * @since 1.0.0 * @access public */ public function save() { $hash = $this->input->get('hash', '', 'string'); if (!$hash) { return $this->error('PLG_MM_INVALID_HASH_PROVIDED'); } $table = MM::table('Meta'); $table->load(['hash' => $hash]); $type = $this->input->get('type', '', 'word'); // Saving of meta $post = $this->input->post->getArray(); $table->bindData($post, $type); $state = $table->store(); return $state; } /** * Renders the form * * @since 1.0.0 * @access public */ public function getForm($form) { ob_start(); include(__DIR__ . '/templates/forms/' . $form . '.php'); $contents = ob_get_contents(); ob_end_clean(); // Get the wrapper $type = $form; $title = JText::_('PLG_METAMAN_POPUP_TITLE_' . strtoupper($type)); ob_start(); include(__DIR__ . '/templates/forms/wrapper.php'); $output = ob_get_contents(); ob_end_clean(); return $output; } /** * Processes file uploads, mainly for rich media * * @since 1.0.0 * @access public */ public function upload() { $type = $this->input->get('type', '', 'word'); $hash = $this->input->get('hash', '', 'string'); $path = MM::getStoragePath($type, $hash); // @TODO: Throw error when it fails to create the folder if ($path === false) { return $this->error('PLG_MM_ERROR_CREATE_FOLDER'); } // Here we assume that everything is fine. $file = $this->input->files->get('image'); // If there is no file uploaded, we assume the user didn't change the image. if (!$file) { $this->setData('code', '300'); $this->setData('message', JText::_('Image not updated')); return $this->output(); } $source = $file['tmp_name']; $destination = $path . '/' . $file['name']; // Copy the file now JFile::copy($source, $destination); // Once the file is copied, we need to set the image url $table = MM::table('Meta'); $table->load(array('hash' => $hash)); $meta = $table->getMeta($type); $meta->set('image_absolute', $path . '/' . $file['name']); $meta->set('image_uri', MM::getStorageUri($type, $hash) . '/' . $file['name']); $table->$type = $meta->toString(); $state = $table->store(); $this->setData('code', 200); $this->setData('url', $meta->get('image_uri')); return $this->output(); } /** * Removes an image * * @since 1.0.0 * @access public */ public function removeImage() { $type = $this->input->get('type', '', 'word'); $hash = $this->input->get('hash', '', 'string'); $table = MM::table('Meta'); $exists = $table->load(array('hash' => $hash)); if (!$exists) { echo "INVALID HASH"; exit; } $meta = $table->getMeta($type); // Get the file and remove it. $file = $meta->get('image_absolute', ''); jimport('joomla.filesystem.file'); $state = JFile::delete($file); // Reset the properties $meta->set('image_absolute', ''); $meta->set('image_uri', ''); $table->$type = $meta->toString(); $table->store(); return $this->success('PLG_MM_META_IMAGE_REMOVED_SUCCESS'); } /** * Removes the meta item altogether * * @since 1.0.0 * @access public */ public function remove() { $type = $this->input->get('type', '', 'word'); $hash = $this->input->get('hash', '', 'string'); $table = MM::table('Meta'); $exists = $table->load(array('hash' => $hash)); if (!$exists) { return $this->error('PLG_MM_INVALID_HASH_PROVIDED'); } $file = $table->getImagePath($type); JFile::delete($file); $table->$type = ''; $state = $table->store(); // Once we removed the property, also get the image return $this->success('PLG_MM_META_REMOVED_SUCCESS'); } /** * Throws a success for json requests * * @since 1.0.0 * @access public */ public function success($message) { $message = JText::_($message); $this->setData('code', 200); $this->setData('message', $message); return $this->output(); } /** * Throws an error for json requests * * @since 1.0.0 * @access public */ public function error($message) { $message = JText::_($message); $this->setData('code', 400); $this->setData('message', $message); return $this->output(); } /** * Adds values to the output buffer * * @since 1.0.0 * @access public */ public function setData($key, $value) { $this->data[$key] = $value; } /** * Responds with json encoded header data * * @since 1.0.0 * @access public */ public function output() { header('Content-type: text/plain; UTF-8'); echo json_encode($this->data); exit; } } PK!k=1 1system/metaman/assets/fonts/font-awesome-mm.woff2nu[wOF2  mTV@ p |;6$  !i ^#!" }r<|o8N/jD 9 T3Y:ۦL*/<{alU_儥!a6æS;=/;A9[7KhmQv3j#l٬ʽK ]Rft)Zvx͡k=9`?{V?0zk.i@fb9Į/њD!.k)a % C#NC̢ѡ%5{lBK?Enϗj"š$ظrZC!(O.='Qѧ>t8 ?GgjGEatS%u JRob$L.x)(t9T·+d-RHh 5Sy04ݝ`Q0kZtDZ ywT1MF^fM&8EK9v$.t%<P ׏440A=&..'d!Sv*GWЙ] l8Mo#N7 ʲmUje$l|K4fMuqZTW[Y5 ۩U҆xQD%fS ߌFC{#>G)ɻ|kծ> i,%(=ybUn/*<ߝ bw8'j tXē9׼w-"oמaᙥh$b` h6۞9IEXVPzݞi(U?geY;]UgTkQ"ֽ;ǏOqZp 8{?r0klUCFWA& =i[=^U?'F)ֶo,M. MMr<+Wjf=-u ̮0m17v7Sa+9KvlEIVgD$%!5]@@z>(@XNA&h 04IeƠ& P5`$cCrClj+kjIoXʛ1`K|! ޖ"x;p;-; k@Auzc>m%~6OރJ٬,nܐP[ d[>*2x)ç ɹԜ!:?+&>Q2SwOy=4༇^?zk ]£9TcQl4i8QMwDl>So:&Ǒão]0S^WxNzQt# ^cZfi[ }6 wXqj L I)"sD6awAd'QZ\TX=c[YHx_/rC^~=,~)] p ҒyU7Xr}y/5$~Sy# 0DbC$5\l' co"; Ae؁'1(et$1`?Q#璁7Ot0E(ܜ5,-gDZ=`+ O9 ySaḾ&!|i=sQʖ#,s'EJ(t63K :q5)V"q6ܜ5,-0nj[ O#Qo@u`Oyf$Qc[ –b:0 ?knf/eZ1N=ihxjȦgALz#AIEM& QKoE(]a4&ZFE%VYEL?!dMIݎ5hzH<ž9qD"S͓~u9i4#7%2[@?i1v==uzF PK!j@ @ 0system/metaman/assets/fonts/font-awesome-mm.woffnu[wOFF @GSUBX;T %yOS/2CV> Rcmapt8cvt L fpgm` pYgaspglyfOhead H16 WMhhea |$<Yhmtx loca maxp name !#post tPi(.prep zA+xc`d``b0`c`I,csq ab`a<21'3=ʱi f)YHxc`d:8iCf|`e`ef \S^0|2`0 ( 0x 0 D=PÞN4C{$4C;ыƖHcy9 #6J+og&ytZ\%}74~?Oe_yGѵt+bGZ`?xc`@? lxViwFyI,% -jaiF&l Ac ];_ds7~Z/$pweZ 둔/&< MQ|(;{!eQڷDD"PDYd|QF˶WM-=.[AU~:ʱ;f3th=%UUH=RҦe+I+WPˆN"iHgh5(l(R$Ay ͐ʧأVK/yw9?_oQ@Ȏt%_[[aܴ(TvwBlTfF+2Ќ`|+?!Y-OGZAeNK>)qY 3 >) xzG%)as4I0r`%e*8uZ[~їhPwb<[[9QhRLIͣ) t&x̯(?I^mc5G8fƄD"-KSA,;)ͣv-ZܣVSFVb: i/i"E~LA2-6Ôoז+}DO) LUV@bkYլwCVrǾq_33߉ӳ#.=sK|u=שrqfyNY4YK[,?iG:cyA t00CX^!, aCXa%creSIڙXlB`bEj*TBhTjCnTϪe^<9HȚ_1ΕF-o;Wo9R֋?T%bÓl'6xtMU=_TTX HX(ʲlpg":jClad-0fs2s|u/ d9 0'x_1a s|1s$a0-^]AUSOXPSeA / gALUӝ!7^1Le| ]l>@xeRjAomjv&͒͟$!좥$J1&JM)JF7)x++Τޜ=߷sΜo t #AfMEZ0p,^ \y^e|,>;F $t u}0ڜ7eՀAlKOeV8b I @HzߔXV:X\3EݼUe,`e)sWlGƫO޿.mEcz(&P̈ETK깴m3mV#\=Rsx;[I^݂~Tq$_\8=ͧ^'yAutxc`d``狾|(p 5# fn $ P xc`d``$_00IFT\eeYJ"}0$s^ pxJ@ƿb ޔ=IE=$T,⭇ b)Il-=>o%],733_p.֚+ō*{54[S7&)>,;8u.,WYR\#-y\fi@V:##Zsu{Wi%8Mt.E2#D2WlH[9:U&znw3Ծ" DU*nbTN3w:?k 39*Тzο.z"=1B0r#93ғӾheT%# t7/UI;BޖЫ;&e`.;gHXT&rj_ 0xm JN}fPAߡk 'ÿ\qÈ "SgOsWb^~(ce6nd/sQxcp"(b##c_Ɲ  X6102h9 ,>0i4'ffp٨#b#sF5oG#CGrHHI$labuKF& v#PK!h||/system/metaman/assets/fonts/font-awesome-mm.eotnu[|LPGfont-awesome-mmRegularVersion 1.0font-awesome-mmpGSUB %yTOS/2> RPVcmap8cvt  fpgmY pgasp glyfhhead WMd6hhea<Y$hmtxlocamaxp  name#!post(. ,iprepA+0 0>latnDFLTligazz1PfEd@0RjZR,tn, tB 00  L00$@"Gof+%"/"/&4?'&4?62762L,,LL,,LpLL,,LL./M@J.,*  GoooooTXL$#"(+'"'327.'327.=.47&54672676%5*Vxa}~b;\?R&,%,DpjJO5=6;4n6'Id@QMF6 bBN`*SdKh9 @$^Q@Gof+"'&4762^"LQ@ Gof+"/&4?'&4?62L:Y $J@GGmn `TVJ $# +2+37#546?5&#"#3!"&5463*o&D#AK\ppe MSsXS_G_<   RjeeYJ"}0$s^ p55DKZ it +  j + I W u   V &Copyright (C) 2016 by original authors @ fontello.comfont-awesome-mmRegularfont-awesome-mmfont-awesome-mmVersion 1.0font-awesome-mmGenerated by svg2ttf from Fontello project.http://fontello.comCopyright (C) 2016 by original authors @ fontello.comfont-awesome-mmRegularfont-awesome-mmfont-awesome-mmVersion 1.0font-awesome-mmGenerated by svg2ttf from Fontello project.http://fontello.com canceltwitter angle-left angle-rightfacebook-officialRjRj, UXEY KQKSZX4(Y`f UX%acc#b!!YC#DC`B-, `f-, d P&Z( CEcER[X!#!X PPX!@Y 8PX!8YY  CEcEad(PX! CEcE 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #B CEc C`Ec*! C +0%&QX`PaRYX#Y! @SX+!@Y#PXeY-,C+C`B-,#B# #Babfc`*-, E Ccb PX@`Yfc`D`-, CEB*!C`B- ,C#DC`B- , E +#C%` E#a d PX!0PX @YY#PXeY%#aDD`- , E +#C%` E#a d$PX@Y#PXeY%#aDD`- , #B EX!#!Y*!- ,EdaD-,` CJPX #BY CJRX #BY-, bfc c#aC` ` #B#-,KTXdDY$ e#x-,KQXKSXdDY!Y$e#x-,CUXCaB+YC%B %B %B# %PXC`%B #a*!#a #a*!C`%B%a*!Y CG CG`b PX@`Yfc Ccb PX@`Yfc`#DC>C`B-,ETX#B E #B #`B `aBB`+r+"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-, +ETX#B E #B #`B `aBB`+r+"Y-,+- ,+-!,+-",+-#,+-$,+-%,+-&,+-',+-(, +-), <`-*, `` C#`C%a`)*!-+,*+**-,, G Ccb PX@`Yfc`#a8# UX G Ccb PX@`Yfc`#a8!Y--,ETX,*0"Y-., +ETX,*0"Y-/, 5`-0,Ecb PX@`Yfc+ Ccb PX@`Yfc+D>#8/*-1, < G Ccb PX@`Yfc`Ca8-2,.<-3, < G Ccb PX@`Yfc`CaCc8-4,% . G#B%IG#G#a Xb!Y#B3*-5,%%G#G#a C+e.# <8-6,%% .G#G#a #B C+ `PX @QX  &YBB# C #G#G#a#F`Cb PX@`Yfc` + a C`d#CadPXCaC`Y%b PX@`Yfca# &#Fa8#CF%CG#G#a` Cb PX@`Yfc`# +#C`+%a%b PX@`Yfc&a %`d#%`dPX!#!Y# &#Fa8Y-7, & .G#G#a#<8-8, #B F#G+#a8-9,%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%acc# Xb!Ycb PX@`Yfc`#.# <8#!Y-:, C .G#G#a ` `fb PX@`Yfc# <8-;,# .F%FRX ,5+# .F%FRX +-S,>+-T,>+-U,>+-V,@+-W,@+-X,@+-Y,@+-Z,C+-[,C+-\,C+-],C+-^,?+-_,?+-`,?+-a,?+-b,7+.++-c,7+;+-d,7+<+-e,7+=+-f,8+.++-g,8+;+-h,8+<+-i,8+=+-j,9+.++-k,9+;+-l,9+<+-m,9+=+-n,:+.++-o,:+;+-p,:+<+-q,:+=+-r, EX!#!YB+e$Px0-KRXYcpB*B *B*B *B@ *D$QX@XdD&QX@cTXDYYYY  *DPK!7b/system/metaman/assets/fonts/font-awesome-mm.ttfnu[pGSUB %yTOS/2> RPVcmap8cvt  fpgmY pgasp glyfhhead WMd6hhea<Y$hmtxlocamaxp  name#!post(. ,iprepA+0 0>latnDFLTligazz1PfEd@0RjZR,tn, tB 00  L00$@"Gof+%"/"/&4?'&4?62762L,,LL,,LpLL,,LL./M@J.,*  GoooooTXL$#"(+'"'327.'327.=.47&54672676%5*Vxa}~b;\?R&,%,DpjJO5=6;4n6'Id@QMF6 bBN`*SdKh9 @$^Q@Gof+"'&4762^"LQ@ Gof+"/&4?'&4?62L:Y $J@GGmn `TVJ $# +2+37#546?5&#"#3!"&5463*o&D#AK\ppe MSsXS_G_<   RjeeYJ"}0$s^ p55DKZ it +  j + I W u   V &Copyright (C) 2016 by original authors @ fontello.comfont-awesome-mmRegularfont-awesome-mmfont-awesome-mmVersion 1.0font-awesome-mmGenerated by svg2ttf from Fontello project.http://fontello.comCopyright (C) 2016 by original authors @ fontello.comfont-awesome-mmRegularfont-awesome-mmfont-awesome-mmVersion 1.0font-awesome-mmGenerated by svg2ttf from Fontello project.http://fontello.com canceltwitter angle-left angle-rightfacebook-officialRjRj, UXEY KQKSZX4(Y`f UX%acc#b!!YC#DC`B-, `f-, d P&Z( CEcER[X!#!X PPX!@Y 8PX!8YY  CEcEad(PX! CEcE 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #B CEc C`Ec*! C +0%&QX`PaRYX#Y! @SX+!@Y#PXeY-,C+C`B-,#B# #Babfc`*-, E Ccb PX@`Yfc`D`-, CEB*!C`B- ,C#DC`B- , E +#C%` E#a d PX!0PX @YY#PXeY%#aDD`- , E +#C%` E#a d$PX@Y#PXeY%#aDD`- , #B EX!#!Y*!- ,EdaD-,` CJPX #BY CJRX #BY-, bfc c#aC` ` #B#-,KTXdDY$ e#x-,KQXKSXdDY!Y$e#x-,CUXCaB+YC%B %B %B# %PXC`%B #a*!#a #a*!C`%B%a*!Y CG CG`b PX@`Yfc Ccb PX@`Yfc`#DC>C`B-,ETX#B E #B #`B `aBB`+r+"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-, +ETX#B E #B #`B `aBB`+r+"Y-,+- ,+-!,+-",+-#,+-$,+-%,+-&,+-',+-(, +-), <`-*, `` C#`C%a`)*!-+,*+**-,, G Ccb PX@`Yfc`#a8# UX G Ccb PX@`Yfc`#a8!Y--,ETX,*0"Y-., +ETX,*0"Y-/, 5`-0,Ecb PX@`Yfc+ Ccb PX@`Yfc+D>#8/*-1, < G Ccb PX@`Yfc`Ca8-2,.<-3, < G Ccb PX@`Yfc`CaCc8-4,% . G#B%IG#G#a Xb!Y#B3*-5,%%G#G#a C+e.# <8-6,%% .G#G#a #B C+ `PX @QX  &YBB# C #G#G#a#F`Cb PX@`Yfc` + a C`d#CadPXCaC`Y%b PX@`Yfca# &#Fa8#CF%CG#G#a` Cb PX@`Yfc`# +#C`+%a%b PX@`Yfc&a %`d#%`dPX!#!Y# &#Fa8Y-7, & .G#G#a#<8-8, #B F#G+#a8-9,%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%acc# Xb!Ycb PX@`Yfc`#.# <8#!Y-:, C .G#G#a ` `fb PX@`Yfc# <8-;,# .F%FRX ,5+# .F%FRX +-S,>+-T,>+-U,>+-V,@+-W,@+-X,@+-Y,@+-Z,C+-[,C+-\,C+-],C+-^,?+-_,?+-`,?+-a,?+-b,7+.++-c,7+;+-d,7+<+-e,7+=+-f,8+.++-g,8+;+-h,8+<+-i,8+=+-j,9+.++-k,9+;+-l,9+<+-m,9+=+-n,:+.++-o,:+;+-p,:+<+-q,:+=+-r, EX!#!YB+e$Px0-KRXYcpB*B *B*B *B@ *D$QX@XdD&QX@cTXDYYYY  *DPK!9ݔ/system/metaman/assets/fonts/font-awesome-mm.svgnu[ Copyright (C) 2016 by original authors @ fontello.com PK!X_&system/metaman/assets/styles/style.cssnu[/* * - Site-wide mixins and functions. */ /*! * #Object * */ /* * Container */ /* * The Grid */ /* Add `.grid` for the table */ /* Add `.col` for the table cells, or columns */ /* Set the widths */ /* * Vertically center grid content * * Requires content within the column to be inline or inline-block. */ #mm { /* * - Low-specificity, far-reaching rulesets (e.g. resets). */ /*------------------------------------*\ Scaffolding/Reset \*------------------------------------*/ font-family: Helvetica, Arial, sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; text-align: left; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; font-smoothing: antialiased; line-height: 1.42857143; /*------------------------------------*\ $SHARED \*------------------------------------*/ /** * Where `margin-bottom` is concerned, this value will be the same as the * base line-height. This allows us to keep a consistent vertical rhythm. */ /** * Base elements */ /** * Doubled up `margin-bottom` helper class. */ /** * `hr` elements only take up a few pixels, so we need to give them special * treatment regarding vertical rhythm. */ /** * Where `margin-left` is concerned we want to try and indent certain elements * by a consistent amount. Define that amount once, here. */ /*------------------------------------*\ #LIST \*------------------------------------*/ /* * - Objects, abstractions, and design patterns (e.g. .media {}). * Buttons............Generic, underlying design patterns with minimum styles */ /*! * #Object * */ /* * Container */ /* Holds and centers the site content */ /* * o-row : Grid with table method */ /* Add `.grid` for the table */ /* Add `.col` for the table cells, or columns */ /* Set the widths */ /* * o-grid : Grid with flex method */ /* With gutters */ /* Alignment per row */ /* Alignment per cell */ /* ! 1. DO not use .o-label--inverse .o-label--important this is just a temporary classes for ED3.2 */ /* Markup:
    test
    */ /* Markup:
    */ /* Markup:
    */ /* Markup:
    */ /* */ font-size: 14px; /* */ /* * - - Discrete, complete chunks of UI. This is the one layer for customized. */ /*! * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ /* @media screen and (-webkit-min-device-pixel-ratio:0) { @font-face { font-family: 'font-awesome-mm'; src: url('../font/font-awesome-mm.svg?63801362#font-awesome-mm') format('svg'); } } */ /* '' */ /* '' */ /* '' */ /* '' */ /* '' */ /* * - High-specificity, very explicit selectors make sure this is last to override anything else. Overrides and helper classes (e.g. .t-hidden {}). */ /* t = trumps s = screen widths p = padding m = margin a = all t = top r = right b = bottom l = left no = none xs = extra small sm = small md = medium (default) lg = large xl = extra large e.g.: t-[screenwidth]-[spacing]--[size] t-xl-pt--lg = trumps-extralarge-paddingtop--large */ } #mm *, #mm *:before, #mm *:after { box-sizing: border-box; } #mm img, #mm input { min-width: 0; min-height: 0; } #mm blockquote, #mm header, #mm nav, #mm figure, #mm article, #mm aside, #mm footer, #mm form { padding: 0; margin: 0; width: auto; height: auto; border: 0; outline: 0; float: none; position: static; display: block; background: none; text-align: inherit; font-size: inherit; font-family: inherit; text-shadow: none; } #mm input, #mm button, #mm select, #mm textarea { font-family: Helvetica, Arial, sans-serif; } #mm h1, #mm h2, #mm h3, #mm h4, #mm h5, #mm h6 { border: none; box-shadow: none; } #mm img { vertical-align: middle; border: 0; } #mm hr { border: 0; -moz-box-sizing: content-box; box-sizing: content-box; height: 0; } #mm table { border-collapse: collapse; border-spacing: 0; } #mm tr, #mm td { border: 1px solid transparent; } #mm a { color: #90a4ae; } #mm a:link { text-decoration: underline; } #mm a:hover, #mm a:focus, #mm a:active { color: #667f8c; text-decoration: none; } #mm li { line-height: 1.42857143; } #mm .landmark { margin-bottom: 16px; margin-bottom: 1.14285714em; } #mm ul, #mm ol, #mm dd { margin-left: 16px; margin-left: 1.14285714em; } #mm blockquote { line-height: 1.42857143; } #mm pre { background: #fff; } #mm .divider { border-bottom: 0; } #mm .form-group:before, #mm .form-group:after { content: " "; display: table; } #mm .form-group:after { clear: both; } #mm .btn .caret { margin-top: 0; margin-bottom: 0; } #mm .g-list-unstyled { margin: 0; padding: 0; list-style: none; } #mm .g-list-inline { margin: 0; padding: 0; list-style: none; font-size: 0; } #mm .g-list-inline > li { display: inline-block; font-size: 12px; } #mm .g-list-inline--delimited > li + li { margin-left: 4px; } #mm .g-list-inline--delimited > li + li:before { content: attr(data-breadcrumb) "\00A0"; } #mm .g-list-inline--dashed > li { position: relative; } #mm .g-list-inline--dashed > :not(:first-child) { margin-left: 8px; padding-left: 8px; border-left: 1px dotted #ccc; } #mm .g-list-horizontal--space > li + li { margin-top: 16px; } #mm .g-list--horizontal { margin: 0; padding: 0; list-style: none; display: -webkit-flex; display: -ms-flexbox; display: flex; } #mm .g-list--horizontal > .g-list__item { -webkit-align-self: center; -ms-flex-item-align: center; align-self: center; display: inline-block; vertical-align: middle; } #mm .has-dividers--right > .g-list__item { position: relative; } #mm .has-dividers--right > .g-list__item:after { width: 4px; height: 4px; content: ''; display: inline-block; vertical-align: middle; margin-left: 4px; margin-right: 4px; border-radius: 50%; background-color: #888; } #mm .has-dividers--right > .g-list__item:last-child { margin-right: 0; padding-right: 0; } #mm .has-dividers--right > .g-list__item:last-child:after { content: none; } #mm .o-row { display: table; width: 100%; table-layout: fixed; } #mm .o-row--unset { table-layout: unset; } #mm .o-col-sm, #mm .o-col-sm--1, #mm .o-col-sm--2, #mm .o-col-sm--3, #mm .o-col-sm--4, #mm .o-col-sm--5, #mm .o-col-sm--6, #mm .o-col-sm--7, #mm .o-col-sm--8, #mm .o-col-sm--9, #mm .o-col-sm--10, #mm .o-col-sm--11, #mm .o-col-sm--12, #mm .o-col, #mm .o-col--1, #mm .o-col--2, #mm .o-col--3, #mm .o-col--4, #mm .o-col--5, #mm .o-col--6, #mm .o-col--7, #mm .o-col--8, #mm .o-col--9, #mm .o-col--10, #mm .o-col--11, #mm .o-col--12 { display: table-cell; vertical-align: middle; } #mm .o-col--1, #mm .o-col-sm--1 { width: 8.333333%; } #mm .o-col--2, #mm .o-col-sm--2 { width: 16.666667%; } #mm .o-col--3, #mm .o-col-sm--3 { width: 25%; } #mm .o-col--4, #mm .o-col-sm--4 { width: 33.333333%; } #mm .o-col--5, #mm .o-col-sm--5 { width: 41.666667%; } #mm .o-col--6, #mm .o-col-sm--6 { width: 50%; } #mm .o-col--7, #mm .o-col-sm--7 { width: 58.333333%; } #mm .o-col--8, #mm .o-col-sm--8 { width: 66.666667%; } #mm .o-col--9, #mm .o-col-sm--9 { width: 75%; } #mm .o-col--10, #mm .o-col-sm--10 { width: 83.333333%; } #mm .o-col--11, #mm .o-col-sm--11 { width: 91.666667%; } #mm .o-col--12, #mm .o-col-sm--12 { width: 100%; } #mm.w480 .o-col, #mm.w480 .o-col--1, #mm.w480 .o-col--2, #mm.w480 .o-col--3, #mm.w480 .o-col--4, #mm.w480 .o-col--5, #mm.w480 .o-col--6, #mm.w480 .o-col--7, #mm.w480 .o-col--8, #mm.w480 .o-col--9, #mm.w480 .o-col--10, #mm.w480 .o-col--11, #mm.w480 .o-col--12 { display: block; width: 100%; } #mm .o-col--top { vertical-align: top; } #mm .o-grid { display: flex; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; } #mm .o-grid__cell { flex: 1; } #mm.w480 .o-grid { display: block; } #mm.w480 .o-grid:before, #mm.w480 .o-grid:after { content: " "; display: table; } #mm.w480 .o-grid:after { clear: both; } #mm.w480 .o-grid__cell { flex: none; } #mm .o-grid--flex-cells > .o-grid__cell { display: flex; } #mm .o-grid--gutters { margin: -8px 0 0 -8px; } #mm .o-grid--gutters > .o-grid__cell { padding: 8px 0 0 8px; } #mm .o-grid--top { align-items: flex-start; } #mm .o-grid--bottom { align-items: flex-end; } #mm .o-grid--center { align-items: center; } #mm .o-grid--justify-center { justify-content: center; } #mm .o-grid__cell--top { align-self: flex-start; } #mm .o-grid__cell--bottom { align-self: flex-end; } #mm .o-grid__cell--center { align-self: center; } #mm .o-grid__cell--auto-size { flex: none; } #mm .o-grid--fit > .o-grid__cell { flex: 1; } #mm .o-grid--full > .o-grid__cell { flex: 0 0 100%; } #mm .o-grid--1of2 > .o-grid__cell { flex: 0 0 50%; } #mm .o-grid--1of3 > .o-grid__cell { flex: 0 0 33.3333%; } #mm .o-grid--1of4 > .o-grid__cell { flex: 0 0 25%; } #mm .u-1of3 { width: 33.3333% !important; -webkit-box-flex: 0!important; -webkit-flex: none!important; -ms-flex: none!important; flex: none!important; } #mm .o-grid--gutters { margin: -8px 0 8px -8px; } #mm .o-grid--gutters > .o-grid__cell { padding: 8px 0 0 8px; } #mm .o-grid--gutters-lg { margin: -16px 0 16px -16px; } #mm .o-grid--gutters-lg > .o-grid__cell { padding: 16px 0 0 16px; } #mm .o-grid--guttersXl { margin: -2em 0 2em -2em; } #mm .o-grid--guttersXl > .o-grid__cell { padding: 2em 0 0 2em; } #mm .btn { display: inline-block; margin-bottom: 0; font-weight: normal; text-align: center; vertical-align: middle; touch-action: manipulation; cursor: pointer; background-image: none; border: 1px solid transparent; white-space: nowrap; text-shadow: none; box-shadow: none; padding: 6px 12px; font-size: 12px; line-height: 1.66666667; border-radius: 3px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #mm .btn:focus, #mm .btn:active:focus, #mm .btn.active:focus, #mm .btn.focus, #mm .btn:active.focus, #mm .btn.active.focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } #mm .btn:hover, #mm .btn:focus, #mm .btn.focus { color: #fff; text-decoration: none; } #mm .btn:active, #mm .btn.active { outline: 0; background-image: none; -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } #mm .btn.disabled, #mm .btn[disabled], fieldset[disabled] #mm .btn { cursor: not-allowed; opacity: 0.65; filter: alpha(opacity=65); -webkit-box-shadow: none; box-shadow: none; } a#mm .btn.disabled, fieldset[disabled] a#mm .btn { pointer-events: none; } #mm .btn-default { color: #fff !important; background-color: #fff !important; border-color: #ccc !important; } #mm .btn-default:focus, #mm .btn-default.focus { color: #fff !important; background-color: #e6e6e6 !important; border-color: #8c8c8c !important; } #mm .btn-default:hover { color: #fff !important; background-color: #e6e6e6 !important; border-color: #adadad !important; } #mm .btn-default:active, #mm .btn-default.active, .open > .dropdown-toggle#mm .btn-default { color: #fff !important; background-color: #e6e6e6 !important; border-color: #adadad !important; } #mm .btn-default:active:hover, #mm .btn-default.active:hover, .open > .dropdown-toggle#mm .btn-default:hover, #mm .btn-default:active:focus, #mm .btn-default.active:focus, .open > .dropdown-toggle#mm .btn-default:focus, #mm .btn-default:active.focus, #mm .btn-default.active.focus, .open > .dropdown-toggle#mm .btn-default.focus { color: #fff !important; background-color: #d4d4d4 !important; border-color: #8c8c8c !important; } #mm .btn-default:active, #mm .btn-default.active, .open > .dropdown-toggle#mm .btn-default { background-image: none !important; } #mm .btn-default.disabled, #mm .btn-default[disabled], fieldset[disabled] #mm .btn-default, #mm .btn-default.disabled:hover, #mm .btn-default[disabled]:hover, fieldset[disabled] #mm .btn-default:hover, #mm .btn-default.disabled:focus, #mm .btn-default[disabled]:focus, fieldset[disabled] #mm .btn-default:focus, #mm .btn-default.disabled.focus, #mm .btn-default[disabled].focus, fieldset[disabled] #mm .btn-default.focus, #mm .btn-default.disabled:active, #mm .btn-default[disabled]:active, fieldset[disabled] #mm .btn-default:active, #mm .btn-default.disabled.active, #mm .btn-default[disabled].active, fieldset[disabled] #mm .btn-default.active { background-color: #fff !important; border-color: #ccc !important; } #mm .btn-default .badge { color: #fff !important; background-color: #fff !important; } #mm .btn-primary { color: #fff !important; background-color: #428bca !important; border-color: #357ebd !important; } #mm .btn-primary:focus, #mm .btn-primary.focus { color: #fff !important; background-color: #3071a9 !important; border-color: #193c5a !important; } #mm .btn-primary:hover { color: #fff !important; background-color: #3071a9 !important; border-color: #285e8e !important; } #mm .btn-primary:active, #mm .btn-primary.active, .open > .dropdown-toggle#mm .btn-primary { color: #fff !important; background-color: #3071a9 !important; border-color: #285e8e !important; } #mm .btn-primary:active:hover, #mm .btn-primary.active:hover, .open > .dropdown-toggle#mm .btn-primary:hover, #mm .btn-primary:active:focus, #mm .btn-primary.active:focus, .open > .dropdown-toggle#mm .btn-primary:focus, #mm .btn-primary:active.focus, #mm .btn-primary.active.focus, .open > .dropdown-toggle#mm .btn-primary.focus { color: #fff !important; background-color: #285e8e !important; border-color: #193c5a !important; } #mm .btn-primary:active, #mm .btn-primary.active, .open > .dropdown-toggle#mm .btn-primary { background-image: none !important; } #mm .btn-primary.disabled, #mm .btn-primary[disabled], fieldset[disabled] #mm .btn-primary, #mm .btn-primary.disabled:hover, #mm .btn-primary[disabled]:hover, fieldset[disabled] #mm .btn-primary:hover, #mm .btn-primary.disabled:focus, #mm .btn-primary[disabled]:focus, fieldset[disabled] #mm .btn-primary:focus, #mm .btn-primary.disabled.focus, #mm .btn-primary[disabled].focus, fieldset[disabled] #mm .btn-primary.focus, #mm .btn-primary.disabled:active, #mm .btn-primary[disabled]:active, fieldset[disabled] #mm .btn-primary:active, #mm .btn-primary.disabled.active, #mm .btn-primary[disabled].active, fieldset[disabled] #mm .btn-primary.active { background-color: #428bca !important; border-color: #357ebd !important; } #mm .btn-primary .badge { color: #428bca !important; background-color: #fff !important; } #mm .btn-success { color: #fff !important; background-color: #5cb85c !important; border-color: #4cae4c !important; } #mm .btn-success:focus, #mm .btn-success.focus { color: #fff !important; background-color: #449d44 !important; border-color: #255625 !important; } #mm .btn-success:hover { color: #fff !important; background-color: #449d44 !important; border-color: #398439 !important; } #mm .btn-success:active, #mm .btn-success.active, .open > .dropdown-toggle#mm .btn-success { color: #fff !important; background-color: #449d44 !important; border-color: #398439 !important; } #mm .btn-success:active:hover, #mm .btn-success.active:hover, .open > .dropdown-toggle#mm .btn-success:hover, #mm .btn-success:active:focus, #mm .btn-success.active:focus, .open > .dropdown-toggle#mm .btn-success:focus, #mm .btn-success:active.focus, #mm .btn-success.active.focus, .open > .dropdown-toggle#mm .btn-success.focus { color: #fff !important; background-color: #398439 !important; border-color: #255625 !important; } #mm .btn-success:active, #mm .btn-success.active, .open > .dropdown-toggle#mm .btn-success { background-image: none !important; } #mm .btn-success.disabled, #mm .btn-success[disabled], fieldset[disabled] #mm .btn-success, #mm .btn-success.disabled:hover, #mm .btn-success[disabled]:hover, fieldset[disabled] #mm .btn-success:hover, #mm .btn-success.disabled:focus, #mm .btn-success[disabled]:focus, fieldset[disabled] #mm .btn-success:focus, #mm .btn-success.disabled.focus, #mm .btn-success[disabled].focus, fieldset[disabled] #mm .btn-success.focus, #mm .btn-success.disabled:active, #mm .btn-success[disabled]:active, fieldset[disabled] #mm .btn-success:active, #mm .btn-success.disabled.active, #mm .btn-success[disabled].active, fieldset[disabled] #mm .btn-success.active { background-color: #5cb85c !important; border-color: #4cae4c !important; } #mm .btn-success .badge { color: #5cb85c !important; background-color: #fff !important; } #mm .btn-info { color: #fff !important; background-color: #5bc0de !important; border-color: #46b8da !important; } #mm .btn-info:focus, #mm .btn-info.focus { color: #fff !important; background-color: #31b0d5 !important; border-color: #1b6d85 !important; } #mm .btn-info:hover { color: #fff !important; background-color: #31b0d5 !important; border-color: #269abc !important; } #mm .btn-info:active, #mm .btn-info.active, .open > .dropdown-toggle#mm .btn-info { color: #fff !important; background-color: #31b0d5 !important; border-color: #269abc !important; } #mm .btn-info:active:hover, #mm .btn-info.active:hover, .open > .dropdown-toggle#mm .btn-info:hover, #mm .btn-info:active:focus, #mm .btn-info.active:focus, .open > .dropdown-toggle#mm .btn-info:focus, #mm .btn-info:active.focus, #mm .btn-info.active.focus, .open > .dropdown-toggle#mm .btn-info.focus { color: #fff !important; background-color: #269abc !important; border-color: #1b6d85 !important; } #mm .btn-info:active, #mm .btn-info.active, .open > .dropdown-toggle#mm .btn-info { background-image: none !important; } #mm .btn-info.disabled, #mm .btn-info[disabled], fieldset[disabled] #mm .btn-info, #mm .btn-info.disabled:hover, #mm .btn-info[disabled]:hover, fieldset[disabled] #mm .btn-info:hover, #mm .btn-info.disabled:focus, #mm .btn-info[disabled]:focus, fieldset[disabled] #mm .btn-info:focus, #mm .btn-info.disabled.focus, #mm .btn-info[disabled].focus, fieldset[disabled] #mm .btn-info.focus, #mm .btn-info.disabled:active, #mm .btn-info[disabled]:active, fieldset[disabled] #mm .btn-info:active, #mm .btn-info.disabled.active, #mm .btn-info[disabled].active, fieldset[disabled] #mm .btn-info.active { background-color: #5bc0de !important; border-color: #46b8da !important; } #mm .btn-info .badge { color: #5bc0de !important; background-color: #fff !important; } #mm .btn-warning { color: #fff !important; background-color: #f0ad4e !important; border-color: #eea236 !important; } #mm .btn-warning:focus, #mm .btn-warning.focus { color: #fff !important; background-color: #ec971f !important; border-color: #985f0d !important; } #mm .btn-warning:hover { color: #fff !important; background-color: #ec971f !important; border-color: #d58512 !important; } #mm .btn-warning:active, #mm .btn-warning.active, .open > .dropdown-toggle#mm .btn-warning { color: #fff !important; background-color: #ec971f !important; border-color: #d58512 !important; } #mm .btn-warning:active:hover, #mm .btn-warning.active:hover, .open > .dropdown-toggle#mm .btn-warning:hover, #mm .btn-warning:active:focus, #mm .btn-warning.active:focus, .open > .dropdown-toggle#mm .btn-warning:focus, #mm .btn-warning:active.focus, #mm .btn-warning.active.focus, .open > .dropdown-toggle#mm .btn-warning.focus { color: #fff !important; background-color: #d58512 !important; border-color: #985f0d !important; } #mm .btn-warning:active, #mm .btn-warning.active, .open > .dropdown-toggle#mm .btn-warning { background-image: none !important; } #mm .btn-warning.disabled, #mm .btn-warning[disabled], fieldset[disabled] #mm .btn-warning, #mm .btn-warning.disabled:hover, #mm .btn-warning[disabled]:hover, fieldset[disabled] #mm .btn-warning:hover, #mm .btn-warning.disabled:focus, #mm .btn-warning[disabled]:focus, fieldset[disabled] #mm .btn-warning:focus, #mm .btn-warning.disabled.focus, #mm .btn-warning[disabled].focus, fieldset[disabled] #mm .btn-warning.focus, #mm .btn-warning.disabled:active, #mm .btn-warning[disabled]:active, fieldset[disabled] #mm .btn-warning:active, #mm .btn-warning.disabled.active, #mm .btn-warning[disabled].active, fieldset[disabled] #mm .btn-warning.active { background-color: #f0ad4e !important; border-color: #eea236 !important; } #mm .btn-warning .badge { color: #f0ad4e !important; background-color: #fff !important; } #mm .btn-danger { color: #fff !important; background-color: #d9534f !important; border-color: #d43f3a !important; } #mm .btn-danger:focus, #mm .btn-danger.focus { color: #fff !important; background-color: #c9302c !important; border-color: #761c19 !important; } #mm .btn-danger:hover { color: #fff !important; background-color: #c9302c !important; border-color: #ac2925 !important; } #mm .btn-danger:active, #mm .btn-danger.active, .open > .dropdown-toggle#mm .btn-danger { color: #fff !important; background-color: #c9302c !important; border-color: #ac2925 !important; } #mm .btn-danger:active:hover, #mm .btn-danger.active:hover, .open > .dropdown-toggle#mm .btn-danger:hover, #mm .btn-danger:active:focus, #mm .btn-danger.active:focus, .open > .dropdown-toggle#mm .btn-danger:focus, #mm .btn-danger:active.focus, #mm .btn-danger.active.focus, .open > .dropdown-toggle#mm .btn-danger.focus { color: #fff !important; background-color: #ac2925 !important; border-color: #761c19 !important; } #mm .btn-danger:active, #mm .btn-danger.active, .open > .dropdown-toggle#mm .btn-danger { background-image: none !important; } #mm .btn-danger.disabled, #mm .btn-danger[disabled], fieldset[disabled] #mm .btn-danger, #mm .btn-danger.disabled:hover, #mm .btn-danger[disabled]:hover, fieldset[disabled] #mm .btn-danger:hover, #mm .btn-danger.disabled:focus, #mm .btn-danger[disabled]:focus, fieldset[disabled] #mm .btn-danger:focus, #mm .btn-danger.disabled.focus, #mm .btn-danger[disabled].focus, fieldset[disabled] #mm .btn-danger.focus, #mm .btn-danger.disabled:active, #mm .btn-danger[disabled]:active, fieldset[disabled] #mm .btn-danger:active, #mm .btn-danger.disabled.active, #mm .btn-danger[disabled].active, fieldset[disabled] #mm .btn-danger.active { background-color: #d9534f !important; border-color: #d43f3a !important; } #mm .btn-danger .badge { color: #d9534f !important; background-color: #fff !important; } #mm .btn-default-o { color: #333 !important; background-color: #fff !important; border-color: #ccc !important; } #mm .btn-default-o:focus, #mm .btn-default-o.focus { color: #333 !important; } #mm .btn-default-o:hover { color: #333 !important; } #mm .btn-default-o:active, #mm .btn-default-o.active, .open > .dropdown-toggle#mm .btn-default-o { color: #333 !important; } #mm .btn-default-o:active:hover, #mm .btn-default-o.active:hover, .open > .dropdown-toggle#mm .btn-default-o:hover, #mm .btn-default-o:active:focus, #mm .btn-default-o.active:focus, .open > .dropdown-toggle#mm .btn-default-o:focus, #mm .btn-default-o:active.focus, #mm .btn-default-o.active.focus, .open > .dropdown-toggle#mm .btn-default-o.focus { color: #333 !important; } #mm .btn-default-o:active, #mm .btn-default-o.active, .open > .dropdown-toggle#mm .btn-default-o { background-image: none !important; } #mm .btn-primary-o { color: #428bca !important; background-color: #fff !important; border-color: #ccc !important; } #mm .btn-primary-o:focus, #mm .btn-primary-o.focus { color: #428bca !important; } #mm .btn-primary-o:hover { color: #428bca !important; } #mm .btn-primary-o:active, #mm .btn-primary-o.active, .open > .dropdown-toggle#mm .btn-primary-o { color: #428bca !important; } #mm .btn-primary-o:active:hover, #mm .btn-primary-o.active:hover, .open > .dropdown-toggle#mm .btn-primary-o:hover, #mm .btn-primary-o:active:focus, #mm .btn-primary-o.active:focus, .open > .dropdown-toggle#mm .btn-primary-o:focus, #mm .btn-primary-o:active.focus, #mm .btn-primary-o.active.focus, .open > .dropdown-toggle#mm .btn-primary-o.focus { color: #428bca !important; } #mm .btn-primary-o:active, #mm .btn-primary-o.active, .open > .dropdown-toggle#mm .btn-primary-o { background-image: none !important; } #mm .btn-success-o { color: #5cb85c !important; background-color: #fff !important; border-color: #ccc !important; } #mm .btn-success-o:focus, #mm .btn-success-o.focus { color: #5cb85c !important; } #mm .btn-success-o:hover { color: #5cb85c !important; } #mm .btn-success-o:active, #mm .btn-success-o.active, .open > .dropdown-toggle#mm .btn-success-o { color: #5cb85c !important; } #mm .btn-success-o:active:hover, #mm .btn-success-o.active:hover, .open > .dropdown-toggle#mm .btn-success-o:hover, #mm .btn-success-o:active:focus, #mm .btn-success-o.active:focus, .open > .dropdown-toggle#mm .btn-success-o:focus, #mm .btn-success-o:active.focus, #mm .btn-success-o.active.focus, .open > .dropdown-toggle#mm .btn-success-o.focus { color: #5cb85c !important; } #mm .btn-success-o:active, #mm .btn-success-o.active, .open > .dropdown-toggle#mm .btn-success-o { background-image: none !important; } #mm .btn-danger-o { color: #d9534f !important; background-color: #fff !important; border-color: #ccc !important; } #mm .btn-danger-o:focus, #mm .btn-danger-o.focus { color: #d9534f !important; } #mm .btn-danger-o:hover { color: #d9534f !important; } #mm .btn-danger-o:active, #mm .btn-danger-o.active, .open > .dropdown-toggle#mm .btn-danger-o { color: #d9534f !important; } #mm .btn-danger-o:active:hover, #mm .btn-danger-o.active:hover, .open > .dropdown-toggle#mm .btn-danger-o:hover, #mm .btn-danger-o:active:focus, #mm .btn-danger-o.active:focus, .open > .dropdown-toggle#mm .btn-danger-o:focus, #mm .btn-danger-o:active.focus, #mm .btn-danger-o.active.focus, .open > .dropdown-toggle#mm .btn-danger-o.focus { color: #d9534f !important; } #mm .btn-danger-o:active, #mm .btn-danger-o.active, .open > .dropdown-toggle#mm .btn-danger-o { background-image: none !important; } #mm .btn-link { color: #428bca; font-weight: normal; border-radius: 0; } #mm .btn-link, #mm .btn-link:active, #mm .btn-link.active, #mm .btn-link[disabled], fieldset[disabled] #mm .btn-link { background-color: transparent; -webkit-box-shadow: none; box-shadow: none; } #mm .btn-link, #mm .btn-link:hover, #mm .btn-link:focus, #mm .btn-link:active { border-color: transparent; } #mm .btn-link:hover, #mm .btn-link:focus { color: #2a6496; text-decoration: underline; background-color: transparent; } #mm .btn-link[disabled]:hover, fieldset[disabled] #mm .btn-link:hover, #mm .btn-link[disabled]:focus, fieldset[disabled] #mm .btn-link:focus { color: #777777; text-decoration: none; } #mm .btn-lg { padding: 10px 16px; font-size: 15px; line-height: 1.3333333; border-radius: 5px; } #mm .btn-sm { padding: 5px 10px; font-size: 11px; line-height: 1.5; border-radius: 2px; } #mm .btn-xs { padding: 1px 5px; font-size: 11px; line-height: 1.5; border-radius: 2px; } #mm .btn-block { display: block; width: 100%; } #mm .btn-block + .btn-block { margin-top: 5px; } #mm input[type="submit"].btn-block, #mm input[type="reset"].btn-block, #mm input[type="button"].btn-block { width: 100%; } #mm .btn-group-yesno { width: auto; min-width: 90px; display: inline-block; margin: 0 auto; vertical-align: middle; white-space: nowrap; } #mm .btn-group-yesno .btn { float: left !important; background: #ddd !important; border: 1px solid #ccc !important; border-radius: 0 !important; border-bottom-left-radius: 3px !important; border-top-left-radius: 3px !important; text-align: center !important; font-size: 12px !important; } #mm .btn-group-yesno .btn + .btn { border-radius: 0 !important; border-bottom-right-radius: 3px !important; border-top-right-radius: 3px !important; } #mm .btn-group-yesno .btn.is-active { background: #fff !important; color: #fff !important; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25) !important; } #mm .btn-group-yesno .btn.btn--yes.is-active { background: #428bca !important; border-color: #3071a9 !important; } #mm .btn-group-yesno .btn.btn--no.is-active { background: #d9534f !important; border-color: #c9302c !important; } #mm .btn-file { position: relative; overflow: hidden; padding-left: 24px !important; white-space: normal; } #mm .btn-file:before { position: absolute; width: 16px; height: 16px; line-height: 16px; left: 4px; top: 6px; font-size: 10px; color: #555555; cursor: pointer; font-family: FontAwesome; font-weight: normal; font-style: normal; display: inline-block; text-decoration: inherit; content: "\f093"; } #mm .btn-file input[type=file] { position: absolute; top: 0; right: 0; min-width: 100%; min-height: 100%; font-size: 100px; text-align: right; filter: alpha(opacity=0); opacity: 0; outline: none; background: white; cursor: inherit; display: block; } #mm .o-label { display: inline; padding: 0.2em 0.6em 0.2em; font-size: 75%; font-weight: bold; line-height: 1; color: #455a64; text-align: center; white-space: nowrap; vertical-align: middle; border-radius: 0.25em; } #mm .o-label:empty { display: none; } .btn #mm .o-label { position: relative; top: -1px; } #mm .o-label--default, #mm .o-label--inverse { background-color: #777777 !important; } #mm .o-label--default[href]:hover, #mm .o-label--inverse[href]:hover, #mm .o-label--default[href]:focus, #mm .o-label--inverse[href]:focus { background-color: #5e5e5e !important; } #mm .o-label--primary { background-color: #428bca !important; } #mm .o-label--primary[href]:hover, #mm .o-label--primary[href]:focus { background-color: #3071a9 !important; } #mm .o-label--success { background-color: #39b54a !important; } #mm .o-label--success[href]:hover, #mm .o-label--success[href]:focus { background-color: #2d8e3a !important; } #mm .o-label--info { background-color: #5BC0DE !important; } #mm .o-label--info[href]:hover, #mm .o-label--info[href]:focus { background-color: #31b0d5 !important; } #mm .o-label--warning { background-color: #EC971F !important; } #mm .o-label--warning[href]:hover, #mm .o-label--warning[href]:focus { background-color: #c77c11 !important; } #mm .o-label--danger, #mm .o-label--important { background-color: #d9534f !important; } #mm .o-label--danger[href]:hover, #mm .o-label--important[href]:hover, #mm .o-label--danger[href]:focus, #mm .o-label--important[href]:focus { background-color: #c9302c !important; } #mm .o-label--default-o { background-color: #e2e2e2 !important; color: #777777 !important; border: 1px solid #777777 !important; } #mm .o-label--default-o[href]:hover, #mm .o-label--default-o[href]:focus { background-color: #e2e2e2 !important; } #mm .o-label--clean-o { background-color: #fff; color: #888; border: 1px solid #888; } #mm .o-label--primary-o { background-color: #e9f2f9 !important; color: #428bca !important; border: 1px solid #428bca !important; } #mm .o-label--primary-o[href]:hover, #mm .o-label--primary-o[href]:focus { background-color: #e9f2f9 !important; } #mm .o-label--success-o { background-color: #d3f1d7 !important; color: #39b54a !important; border: 1px solid #39b54a !important; } #mm .o-label--success-o[href]:hover, #mm .o-label--success-o[href]:focus { background-color: #d3f1d7 !important; } #mm .o-label--info-o { background-color: #ffffff !important; color: #5BC0DE !important; border: 1px solid #5BC0DE !important; } #mm .o-label--info-o[href]:hover, #mm .o-label--info-o[href]:focus { background-color: #ffffff !important; } #mm .o-label--warning-o { background-color: #fdf3e4 !important; color: #EC971F !important; border: 1px solid #EC971F !important; } #mm .o-label--warning-o[href]:hover, #mm .o-label--warning-o[href]:focus { background-color: #fdf3e4 !important; } #mm .o-label--danger-o { background-color: #ffffff !important; color: #d9534f !important; border: 1px solid #d9534f !important; } #mm .o-label--danger-o[href]:hover, #mm .o-label--danger-o[href]:focus { background-color: #ffffff !important; } #mm.tooltip { position: absolute; z-index: 1070; display: block; font-family: Helvetica, Arial, sans-serif; font-style: normal; font-weight: normal; letter-spacing: normal; line-break: auto; line-height: 1.66666667; text-align: left; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; white-space: normal; word-break: normal; word-spacing: normal; word-wrap: normal; font-size: 11px; width: auto !important; height: auto !important; background-color: transparent !important; border: none !important; opacity: 0; filter: alpha(opacity=0); } #mm.tooltip.in { opacity: 100; filter: alpha(opacity=10000); } #mm.tooltip.top { margin-top: -3px; padding: 5px 0 !important; } #mm.tooltip.right { margin-left: 3px; padding: 0 5px !important; } #mm.tooltip.bottom { margin-top: 3px; padding: 5px 0 !important; } #mm.tooltip.left { margin-left: -3px; padding: 0 5px !important; } #mm .tooltip-inner { max-width: 200px; padding: 3px 8px; color: #fff; text-align: center; background-color: #000; border-radius: 3px; } #mm .tooltip-arrow { position: absolute; width: 0; height: 0; border-color: transparent; border-style: solid; } #mm.tooltip.top .tooltip-arrow { bottom: 0; left: 50%; margin-left: -5px; border-width: 5px 5px 0; border-top-color: #000; } #mm.tooltip.top-left .tooltip-arrow { bottom: 0; right: 5px; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #000; } #mm.tooltip.top-right .tooltip-arrow { bottom: 0; left: 5px; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #000; } #mm.tooltip.right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-width: 5px 5px 5px 0; border-right-color: #000; } #mm.tooltip.left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-width: 5px 0 5px 5px; border-left-color: #000; } #mm.tooltip.bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } #mm.tooltip.bottom-left .tooltip-arrow { top: 0; right: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } #mm.tooltip.bottom-right .tooltip-arrow { top: 0; left: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } #mm .o-checkbox { padding-left: 16px; margin-top: 8px; margin-bottom: 8px; font-size: 14px; } #mm .o-checkbox label { display: block; position: relative; padding: 0 0 0 5px; font-weight: normal; font-size: inherit; line-height: 1.42857143; margin: 0; } #mm .o-checkbox label:before { content: ""; display: inline-block; position: absolute; width: 16px; height: 16px; left: 0; top: 0; margin-left: -16px; border: 1px solid #ccc; border-radius: 2px; background-color: #fff; cursor: pointer; } #mm .o-checkbox label:after { display: inline-block; position: absolute; width: 16px; height: 16px; line-height: 16px; left: 0; top: 0; margin-left: -16px; padding-left: 2px; padding-top: 0; font-size: 14px; color: #f5f5f5; cursor: pointer; } #mm .o-checkbox input[type="checkbox"] { display: none; } #mm .o-checkbox input[type="checkbox"]:checked + label:before { background-color: #428bca; border-color: #428bca; } #mm .o-checkbox input[type="checkbox"]:checked + label:after { font-family: FontAwesome; font-weight: normal; font-style: normal; display: inline-block; text-decoration: inherit; content: "\f00c"; color: #fff; } #mm .o-checkbox input[type="checkbox"]:disabled + label { cursor: not-allowed; } #mm .o-checkbox input[type="checkbox"]:disabled + label:before { background-color: #eeeeee; cursor: not-allowed; } #mm .o-checkbox input[type="checkbox"]:disabled + label:after { color: #428bca; } #mm .o-checkbox--sm label { font-size: 14px; } #mm .o-checkbox--inline { display: inline-block; margin-right: 8px; } #mm .o-checkbox--inline label { display: inline-block; } #mm .o-radio { padding-left: 16px; margin-top: 8px; margin-bottom: 8px; font-size: 14px; } #mm .o-radio label { display: block; position: relative; padding: 0 0 0 5px; font-weight: normal; font-size: inherit; line-height: 1.42857143; margin: 0; cursor: pointer; } #mm .o-radio label:before { content: ""; display: inline-block; position: absolute; width: 16px; height: 16px; left: 0; top: 0; margin-left: -16px; border: 1px solid #ccc; border-radius: 50%; background-color: #fff; cursor: pointer; } #mm .o-radio label:after { display: inline-block; position: absolute; width: 8px; height: 8px; line-height: 16px; left: -12px; top: 4px; cursor: pointer; background-color: #fff; border-radius: 50%; content: ""; } #mm .o-radio input[type="radio"] { display: none; } #mm .o-radio input[type="radio"]:checked + label:before { background-color: #428bca; border-color: #428bca; } #mm .o-radio input[type="radio"]:checked + label:after { font-family: FontAwesome; font-weight: normal; font-style: normal; display: inline-block; text-decoration: inherit; } #mm .o-radio input[type="radio"]:disabled + label { cursor: not-allowed; } #mm .o-radio input[type="radio"]:disabled + label:before { background-color: #fff; cursor: not-allowed; } #mm .o-radio input[type="radio"]:disabled + label:after { cursor: not-allowed; } #mm .o-radio--sm label { font-size: 14px; } #mm .o-radio--inline { display: inline-block; margin-right: 8px; } #mm .o-radio--inline label { display: inline-block; } #mm .o-switch { position: relative; width: 40px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } #mm .o-switch__checkbox { display: none; } #mm .o-switch__label { display: block; overflow: hidden; cursor: pointer; height: 10px; border: 1px solid transparent; border-radius: 6px; } #mm .o-switch__inner { display: block; width: 200%; height: 20px; margin-left: -100%; transition: margin 0.3s ease-in 0s; } #mm .o-switch__inner:before, #mm .o-switch__inner:after { display: block; float: left; width: 50%; height: 8px; padding: 0; line-height: 20px; font-size: 10px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold; box-sizing: border-box; } #mm .o-switch__inner:before { content: ""; padding-left: 10px; background-color: #cbefd0; color: #fff; } #mm .o-switch__inner:after { content: ""; padding-right: 10px; background-color: #f1f1f1; color: #ccc; text-align: right; } #mm .o-switch__switch { display: block; width: 20px; height: 22px; margin: 0px; background: #888; position: absolute; top: -6px; bottom: 0; right: 20px; border-radius: 50%; transition: all 0.3s ease-in 0s; } #mm .o-switch__checkbox:checked + .o-switch__label .o-switch__inner { margin-left: 0; } #mm .o-switch__checkbox:checked + .o-switch__label .o-switch__switch { right: 0px; background: #39b54a; } #mm.layout-full { position: fixed; bottom: 0; right: 0; width: 420px; height: 100%; overflow: hidden; visibility: visible; z-index: 1000; border: 0px; transition: transform 0.2s ease-in-out; backface-visibility: hidden; transform: translateY(0%); opacity: 1; background: transparent; } #mm.layout-full.is-hidden { transform: translateY(100%); transition: transform 0.2s ease-in-out; } #mm.is-loading .mm-preloader { display: block; } #mm.has-alert .mm-popup { display: flex; } #mm.layout-full { background-color: #fff; border-left: 1px solid #ccc; border-top: 1px solid #ccc; -webkit-box-shadow: 0 1px 14px rgba(0, 0, 0, 0.05); box-shadow: 0 1px 14px rgba(0, 0, 0, 0.05); } #mm.layout-compact { background: transparent; display: block; width: 240px; height: 85px; border: 0px; } #mm.layout-compact--tl { top: 0; left: 14px; } #mm.layout-compact--tr { top: 0; right: 14px; } #mm.layout-compact--bl { bottom: 0; left: 14px; } #mm.layout-compact--br { bottom: 0; right: 14px; } #mm .btn-toggle-mm { display: block; border-radius: 50%; position: fixed; bottom: 50px; } #mm .btn-toggle-mm.btn--base { right: 200px; } #mm .btn-toggle-mm.btn--tw { right: 30px; } #mm .btn-toggle-mm.btn--fb { right: 115px; } #mm .btn-toggle-mm img { -webkit-box-shadow: -4px 4px 15px rgba(0, 0, 0, 0.2); box-shadow: -4px 4px 15px rgba(0, 0, 0, 0.2); } #mm .btn-toggle-mm img:hover { opacity: 0.8; } #mm .mm-container { background: #fff; width: 100%; height: 100%; position: absolute; top: 0; left: 0; display: flex; flex-direction: column; } #mm .mm-container__hd:before, #mm .mm-container__bd:before, #mm .mm-container__ft:before, #mm .mm-container__hd:after, #mm .mm-container__bd:after, #mm .mm-container__ft:after { content: " "; display: table; } #mm .mm-container__hd:after, #mm .mm-container__bd:after, #mm .mm-container__ft:after { clear: both; } #mm .mm-container__hd { flex: 1 1 auto; box-shadow: 0 8px 6px -6px rgba(0, 0, 0, 0.05); overflow: hidden; position: relative; } #mm .mm-container__bd { padding: 20px; flex: 1 1 100%; display: flex; flex-direction: column; border-top: 1px solid #ccc; overflow: auto; position: relative; -webkit-overflow-scrolling: touch; } #mm .mm-container__ft { background: red; width: 100%; border-top: 1px solid #ccc; background-color: #fff; flex: 0 0 60px; display: flex; } #mm .mm-icon { display: block; margin: 0 auto; width: 60px; height: 60px; border-radius: 50%; border-style: solid; border-width: 3px; border-color: #b0bec5; } #mm .mm-icon--fb { background: #3f51bf; } #mm .mm-icon--tw { background: #2196f3; } #mm .mm-icon--base { background: #455861; } #mm .mm-icon--default { border-color: #b0bec5; } #mm .mm-icon--danger { border-color: #ff7366; } #mm .mm-icon--warning { border-color: #ffb74d; } #mm .mm-icon--success { border-color: #8fce75; } @media (max-width: 767px) { #mm.layout-compact, #mm.layout-full { width: 100%; } } #mm .mm-preloader { background: #f1f1f1; display: none; width: 100%; height: 5px; } #mm .mm-preloader__bar { width: 100%; height: 3px; margin: 1px 0; position: absolute; animation: loadfull 1s ease-out; } #mm .mm-preloader__bar--danger { background: #ff7366; } #mm .mm-preloader__bar--warning { background: #ffb74d; } #mm .mm-preloader__bar--success { background: #8fce75; } @-moz-keyframes loadfull { 0% { width: 0px; } 100% { width: 100%; } } @-webkit-keyframes loadfull { 0% { width: 0px; } 100% { width: 100%; } } #mm .mm-page-header .btn-group { margin-bottom: 0; } #mm .mm-page-header .btn-group .btn { text-decoration: none; border-radius: 0; } #mm .mm-page-header .btn-group .btn--mm { background: #03a9f4; color: #fff; font-weight: bold; text-decoration: none; width: 100%; } #mm .mm-page-header .btn-group .btn--mm:hover, #mm .mm-page-header .btn-group .btn--mm:focus { background: #0398db; } #mm .mm-page-header .btn-group .btn--close { background: #fff; color: #888; width: 50px; } #mm .mm-page-header .btn-group .btn--close:hover, #mm .mm-page-header .btn-group .btn--close:focus { background: #f2f2f2; } #mm .mm-page-header .btn-group .btn--close > i { margin: 0; width: auto; } #mm.has-notice .mm-page-notice { display: block; } #mm .mm-page-notice { padding: 10px; border-top: 1px solid #d7d7d7; font-size: 12px; display: none; } #mm .mm-page-notice__success { background-color: #dff0d8; color: #3c763d; } #mm .mm-page-notice__danger { color: #ff7366; } #mm .mm-page-listing__item { display: block; } #mm .mm-page-listing__item .form-group { margin-bottom: 20px; } #mm .mm-page-listing__item .form-group label { color: #455a64; } #mm .mm-page-listing__item .form-group label.mm-file-upload { color: #90a4ae; font-size: 12px; font-weight: normal; text-overflow: ellipsis; display: inline-block; width: 100%; border: 1px solid #ccc; border-radius: 2px; white-space: nowrap; overflow: hidden; } #mm .mm-page-listing__item .form-group label.mm-file-upload span { color: #428bca; font-size: 14px; font-weight: bold; display: inline-block; margin-top: 0; margin-bottom: 0; margin-right: 20px; padding: 16px 20px; border-right: 1px solid #ccc; cursor: pointer; } #mm .mm-page-listing__item .form-group input[type="file"] { display: none; } #mm .mm-page-listing__item .form-group > span { color: #90a4ae; font-size: 12px; display: inline-block; margin: 4px 0; } #mm .mm-page-listing__item .form-group > span.mm-char-count { margin: 0; } #mm .mm-page-listing__item .form-group .mm-composer__textarea { height: 120px !important; resize: none; } #mm .mm-page-listing input.form-control, #mm .mm-page-listing textarea.form-control { font-size: 14px; } #mm .mm-page-listing input.form-control { font-size: 14px; height: auto; padding-top: 8px; padding-bottom: 8px; border-radius: 2px; box-shadow: none; } #mm .mm-page-listing select.form-control { box-shadow: none; } #mm .mm-page-listing select.form-control:focus { border-color: #ccc; } #mm .mm-page-listing a { font-size: 12px; text-align: center; width: 100%; } #mm .mm-page-listing .mm-file-preview { display: block; width: 100%; } #mm .mm-page-listing .mm-file-preview label { color: #455a64; } #mm .mm-page-listing .mm-file-preview > span { color: #90a4ae; font-size: 12px; display: inline-block; margin: 4px 0; } #mm .mm-page-listing .mm-file-preview__container { border: 1px solid #ccc; border-radius: 2px; } #mm .mm-page-listing .mm-file-preview__img { background: #f1f1f1 url('//placehold.it/700x500') no-repeat; background-position: center center; background-size: cover; display: block; width: 100%; height: 200px; overflow: hidden; border-radius: 1px 1px 0 0; } #mm .mm-page-listing .mm-file-preview__item { border-top: 1px solid #ccc; padding: 8px; } #mm .mm-page-listing .mm-file-preview__item--title { font-weight: bold; } #mm .mm-page-listing .mm-file-preview__item--text { color: #455a64; } #mm .mm-page-listing .mm-file-preview__item a { text-align: left; text-decoration: none; text-transform: uppercase; display: inline; } #mm .btn { margin: 16px 0; width: 100%; border-radius: 2px; } #mm .mm-revert { text-align: center; padding-bottom: 25px; } #mm .mm-revert a { font-size: 14px; } #mm .mm-popup { background: rgba(255, 255, 255, 0.9); display: none; align-items: center; justify-content: center; width: 100%; height: 100%; position: absolute; top: 0; left: 0; } #mm .mm-popup__container .delete-confirmation { color: #666; padding: 0 20px; margin-bottom: 25px; } #mm .mm-popup__button .btn { margin: 4px; width: 150px; } #mm .mm-popup__button .btn-default { color: #888 !important; } #mm h1, #mm h2, #mm h3, #mm h4, #mm h5, #mm h6, #mm .h1, #mm .h2, #mm .h3, #mm .h4, #mm .h5, #mm .h6 { font-family: inherit; font-weight: 500; line-height: 1.1; color: inherit; } #mm h1 small, #mm h2 small, #mm h3 small, #mm h4 small, #mm h5 small, #mm h6 small, #mm .h1 small, #mm .h2 small, #mm .h3 small, #mm .h4 small, #mm .h5 small, #mm .h6 small, #mm h1 .small, #mm h2 .small, #mm h3 .small, #mm h4 .small, #mm h5 .small, #mm h6 .small, #mm .h1 .small, #mm .h2 .small, #mm .h3 .small, #mm .h4 .small, #mm .h5 .small, #mm .h6 .small { font-weight: normal; line-height: 1; color: #777777; } #mm h1, #mm .h1, #mm h2, #mm .h2, #mm h3, #mm .h3 { margin-top: 20px; margin-bottom: 10px; } #mm h1 small, #mm .h1 small, #mm h2 small, #mm .h2 small, #mm h3 small, #mm .h3 small, #mm h1 .small, #mm .h1 .small, #mm h2 .small, #mm .h2 .small, #mm h3 .small, #mm .h3 .small { font-size: 65%; } #mm h4, #mm .h4, #mm h5, #mm .h5, #mm h6, #mm .h6 { margin-top: 10px; margin-bottom: 10px; } #mm h4 small, #mm .h4 small, #mm h5 small, #mm .h5 small, #mm h6 small, #mm .h6 small, #mm h4 .small, #mm .h4 .small, #mm h5 .small, #mm .h5 .small, #mm h6 .small, #mm .h6 .small { font-size: 75%; } #mm h1, #mm .h1 { font-size: 31px; } #mm h2, #mm .h2 { font-size: 25px; } #mm h3, #mm .h3 { font-size: 21px; } #mm h4, #mm .h4 { font-size: 15px; } #mm h5, #mm .h5 { font-size: 12px; } #mm h6, #mm .h6 { font-size: 11px; } #mm p { margin: 0 0 10px; } #mm .lead { margin-bottom: 20px; font-size: 13px; font-weight: 300; line-height: 1.4; } @media (min-width: 768px) { #mm .lead { font-size: 18px; } } #mm small, #mm .small { font-size: 91%; } #mm mark, #mm .mark { background-color: #fcf8e3; padding: 0.2em; } #mm .text-left { text-align: left; } #mm .text-right { text-align: right; } #mm .text-center { text-align: center; } #mm .text-justify { text-align: justify; } #mm .text-nowrap { white-space: nowrap; } #mm .text-lowercase { text-transform: lowercase; } #mm .text-uppercase { text-transform: uppercase; } #mm .text-capitalize { text-transform: capitalize; } #mm .text-muted { color: #777777; } #mm .text-primary { color: #428bca; } a#mm .text-primary:hover, a#mm .text-primary:focus { color: #3071a9; } #mm .text-success { color: #3c763d; } a#mm .text-success:hover, a#mm .text-success:focus { color: #2b542c; } #mm .text-info { color: #31708f; } a#mm .text-info:hover, a#mm .text-info:focus { color: #245269; } #mm .text-warning { color: #8a6d3b; } a#mm .text-warning:hover, a#mm .text-warning:focus { color: #66512c; } #mm .text-danger { color: #a94442; } a#mm .text-danger:hover, a#mm .text-danger:focus { color: #843534; } #mm .bg-primary { color: #fff; background-color: #428bca; } a#mm .bg-primary:hover, a#mm .bg-primary:focus { background-color: #3071a9; } #mm .bg-success { background-color: #dff0d8; } a#mm .bg-success:hover, a#mm .bg-success:focus { background-color: #c1e2b3; } #mm .bg-info { background-color: #d9edf7; } a#mm .bg-info:hover, a#mm .bg-info:focus { background-color: #afd9ee; } #mm .bg-warning { background-color: #fcf8e3; } a#mm .bg-warning:hover, a#mm .bg-warning:focus { background-color: #f7ecb5; } #mm .bg-danger { background-color: #f2dede; } a#mm .bg-danger:hover, a#mm .bg-danger:focus { background-color: #e4b9b9; } #mm .page-header { padding-bottom: 9px; margin: 40px 0 20px; border-bottom: 1px solid #eeeeee; } #mm ul, #mm ol { margin-top: 0; margin-bottom: 10px; } #mm ul ul, #mm ol ul, #mm ul ol, #mm ol ol { margin-bottom: 0; } #mm .list-unstyled { padding-left: 0; list-style: none; } #mm .list-inline { padding-left: 0; list-style: none; margin-left: -5px; } #mm .list-inline > li { display: inline-block; padding-left: 5px; padding-right: 5px; } #mm dl { margin-top: 0; margin-bottom: 20px; } #mm dt, #mm dd { line-height: 1.66666667; } #mm dt { font-weight: bold; } #mm dd { margin-left: 0; } @media (min-width: 768px) { #mm .dl-horizontal dt { float: left; width: 160px; clear: left; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } #mm .dl-horizontal dd { margin-left: 180px; } } #mm abbr[title], #mm abbr[data-original-title] { cursor: help; border-bottom: 1px dotted #777777; } #mm .initialism { font-size: 90%; text-transform: uppercase; } #mm blockquote { padding: 10px 20px; margin: 0 0 20px; font-size: 15px; border-left: 5px solid #eeeeee; } #mm blockquote p:last-child, #mm blockquote ul:last-child, #mm blockquote ol:last-child { margin-bottom: 0; } #mm blockquote footer, #mm blockquote small, #mm blockquote .small { display: block; font-size: 80%; line-height: 1.66666667; color: #777777; } #mm blockquote footer:before, #mm blockquote small:before, #mm blockquote .small:before { content: '\2014 \00A0'; } #mm .blockquote-reverse, #mm blockquote.pull-right { padding-right: 15px; padding-left: 0; border-right: 5px solid #eeeeee; border-left: 0; text-align: right; } #mm .blockquote-reverse footer:before, #mm blockquote.pull-right footer:before, #mm .blockquote-reverse small:before, #mm blockquote.pull-right small:before, #mm .blockquote-reverse .small:before, #mm blockquote.pull-right .small:before { content: ''; } #mm .blockquote-reverse footer:after, #mm blockquote.pull-right footer:after, #mm .blockquote-reverse small:after, #mm blockquote.pull-right small:after, #mm .blockquote-reverse .small:after, #mm blockquote.pull-right .small:after { content: '\00A0 \2014'; } #mm address { margin-bottom: 20px; font-style: normal; line-height: 1.66666667; } #mm table { background-color: transparent; } #mm caption { padding-top: 8px; padding-bottom: 8px; color: #777777; text-align: left; } #mm th { text-align: left; } #mm .table { width: 100%; max-width: 100%; margin-bottom: 20px; } #mm .table > thead > tr > th, #mm .table > tbody > tr > th, #mm .table > tfoot > tr > th, #mm .table > thead > tr > td, #mm .table > tbody > tr > td, #mm .table > tfoot > tr > td { padding: 8px; line-height: 1.66666667; vertical-align: top; border-top: 1px solid #ddd; } #mm .table > thead > tr > th { vertical-align: bottom; border-bottom: 2px solid #ddd; } #mm .table > caption + thead > tr:first-child > th, #mm .table > colgroup + thead > tr:first-child > th, #mm .table > thead:first-child > tr:first-child > th, #mm .table > caption + thead > tr:first-child > td, #mm .table > colgroup + thead > tr:first-child > td, #mm .table > thead:first-child > tr:first-child > td { border-top: 0; } #mm .table > tbody + tbody { border-top: 2px solid #ddd; } #mm .table .table { background-color: #fff; } #mm .table-condensed > thead > tr > th, #mm .table-condensed > tbody > tr > th, #mm .table-condensed > tfoot > tr > th, #mm .table-condensed > thead > tr > td, #mm .table-condensed > tbody > tr > td, #mm .table-condensed > tfoot > tr > td { padding: 5px; } #mm .table-bordered { border: 1px solid #ddd; } #mm .table-bordered > thead > tr > th, #mm .table-bordered > tbody > tr > th, #mm .table-bordered > tfoot > tr > th, #mm .table-bordered > thead > tr > td, #mm .table-bordered > tbody > tr > td, #mm .table-bordered > tfoot > tr > td { border: 1px solid #ddd; } #mm .table-bordered > thead > tr > th, #mm .table-bordered > thead > tr > td { border-bottom-width: 2px; } #mm .table-striped > tbody > tr:nth-of-type(odd) { background-color: #f9f9f9; } #mm .table-hover > tbody > tr:hover { background-color: #f5f5f5; } #mm table col[class*="col-"] { position: static; float: none; display: table-column; } #mm table td[class*="col-"], #mm table th[class*="col-"] { position: static; float: none; display: table-cell; } #mm .table > thead > tr > td.active, #mm .table > tbody > tr > td.active, #mm .table > tfoot > tr > td.active, #mm .table > thead > tr > th.active, #mm .table > tbody > tr > th.active, #mm .table > tfoot > tr > th.active, #mm .table > thead > tr.active > td, #mm .table > tbody > tr.active > td, #mm .table > tfoot > tr.active > td, #mm .table > thead > tr.active > th, #mm .table > tbody > tr.active > th, #mm .table > tfoot > tr.active > th { background-color: #f5f5f5; } #mm .table-hover > tbody > tr > td.active:hover, #mm .table-hover > tbody > tr > th.active:hover, #mm .table-hover > tbody > tr.active:hover > td, #mm .table-hover > tbody > tr:hover > .active, #mm .table-hover > tbody > tr.active:hover > th { background-color: #e8e8e8; } #mm .table > thead > tr > td.success, #mm .table > tbody > tr > td.success, #mm .table > tfoot > tr > td.success, #mm .table > thead > tr > th.success, #mm .table > tbody > tr > th.success, #mm .table > tfoot > tr > th.success, #mm .table > thead > tr.success > td, #mm .table > tbody > tr.success > td, #mm .table > tfoot > tr.success > td, #mm .table > thead > tr.success > th, #mm .table > tbody > tr.success > th, #mm .table > tfoot > tr.success > th { background-color: #dff0d8; } #mm .table-hover > tbody > tr > td.success:hover, #mm .table-hover > tbody > tr > th.success:hover, #mm .table-hover > tbody > tr.success:hover > td, #mm .table-hover > tbody > tr:hover > .success, #mm .table-hover > tbody > tr.success:hover > th { background-color: #d0e9c6; } #mm .table > thead > tr > td.info, #mm .table > tbody > tr > td.info, #mm .table > tfoot > tr > td.info, #mm .table > thead > tr > th.info, #mm .table > tbody > tr > th.info, #mm .table > tfoot > tr > th.info, #mm .table > thead > tr.info > td, #mm .table > tbody > tr.info > td, #mm .table > tfoot > tr.info > td, #mm .table > thead > tr.info > th, #mm .table > tbody > tr.info > th, #mm .table > tfoot > tr.info > th { background-color: #d9edf7; } #mm .table-hover > tbody > tr > td.info:hover, #mm .table-hover > tbody > tr > th.info:hover, #mm .table-hover > tbody > tr.info:hover > td, #mm .table-hover > tbody > tr:hover > .info, #mm .table-hover > tbody > tr.info:hover > th { background-color: #c4e3f3; } #mm .table > thead > tr > td.warning, #mm .table > tbody > tr > td.warning, #mm .table > tfoot > tr > td.warning, #mm .table > thead > tr > th.warning, #mm .table > tbody > tr > th.warning, #mm .table > tfoot > tr > th.warning, #mm .table > thead > tr.warning > td, #mm .table > tbody > tr.warning > td, #mm .table > tfoot > tr.warning > td, #mm .table > thead > tr.warning > th, #mm .table > tbody > tr.warning > th, #mm .table > tfoot > tr.warning > th { background-color: #fcf8e3; } #mm .table-hover > tbody > tr > td.warning:hover, #mm .table-hover > tbody > tr > th.warning:hover, #mm .table-hover > tbody > tr.warning:hover > td, #mm .table-hover > tbody > tr:hover > .warning, #mm .table-hover > tbody > tr.warning:hover > th { background-color: #faf2cc; } #mm .table > thead > tr > td.danger, #mm .table > tbody > tr > td.danger, #mm .table > tfoot > tr > td.danger, #mm .table > thead > tr > th.danger, #mm .table > tbody > tr > th.danger, #mm .table > tfoot > tr > th.danger, #mm .table > thead > tr.danger > td, #mm .table > tbody > tr.danger > td, #mm .table > tfoot > tr.danger > td, #mm .table > thead > tr.danger > th, #mm .table > tbody > tr.danger > th, #mm .table > tfoot > tr.danger > th { background-color: #f2dede; } #mm .table-hover > tbody > tr > td.danger:hover, #mm .table-hover > tbody > tr > th.danger:hover, #mm .table-hover > tbody > tr.danger:hover > td, #mm .table-hover > tbody > tr:hover > .danger, #mm .table-hover > tbody > tr.danger:hover > th { background-color: #ebcccc; } #mm .table-responsive { overflow-x: auto; min-height: 0.01%; } @media screen and (max-width: 767px) { #mm .table-responsive { width: 100%; margin-bottom: 15px; overflow-y: hidden; -ms-overflow-style: -ms-autohiding-scrollbar; border: 1px solid #ddd; } #mm .table-responsive > .table { margin-bottom: 0; } #mm .table-responsive > .table > thead > tr > th, #mm .table-responsive > .table > tbody > tr > th, #mm .table-responsive > .table > tfoot > tr > th, #mm .table-responsive > .table > thead > tr > td, #mm .table-responsive > .table > tbody > tr > td, #mm .table-responsive > .table > tfoot > tr > td { white-space: nowrap; } #mm .table-responsive > .table-bordered { border: 0; } #mm .table-responsive > .table-bordered > thead > tr > th:first-child, #mm .table-responsive > .table-bordered > tbody > tr > th:first-child, #mm .table-responsive > .table-bordered > tfoot > tr > th:first-child, #mm .table-responsive > .table-bordered > thead > tr > td:first-child, #mm .table-responsive > .table-bordered > tbody > tr > td:first-child, #mm .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } #mm .table-responsive > .table-bordered > thead > tr > th:last-child, #mm .table-responsive > .table-bordered > tbody > tr > th:last-child, #mm .table-responsive > .table-bordered > tfoot > tr > th:last-child, #mm .table-responsive > .table-bordered > thead > tr > td:last-child, #mm .table-responsive > .table-bordered > tbody > tr > td:last-child, #mm .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } #mm .table-responsive > .table-bordered > tbody > tr:last-child > th, #mm .table-responsive > .table-bordered > tfoot > tr:last-child > th, #mm .table-responsive > .table-bordered > tbody > tr:last-child > td, #mm .table-responsive > .table-bordered > tfoot > tr:last-child > td { border-bottom: 0; } } #mm fieldset { padding: 0; margin: 0; border: 0; min-width: 0; } #mm legend { display: block; width: 100%; padding: 0; margin-bottom: 20px; font-size: 18px; line-height: inherit; color: #333333; border: 0; border-bottom: 1px solid #e5e5e5; } #mm label { display: inline-block; max-width: 100%; margin-bottom: 5px; font-weight: bold; } #mm input[type="search"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } #mm input[type="radio"], #mm input[type="checkbox"] { margin: 4px 0 0; margin-top: 1px \9; line-height: normal; } #mm input[type="file"] { display: block; border: 0; box-shadow: none; } #mm input[type="range"] { display: block; width: 100%; } #mm select[multiple], #mm select[size] { height: auto; } #mm input[type="file"]:focus, #mm input[type="radio"]:focus, #mm input[type="checkbox"]:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } #mm output { display: block; padding-top: 7px; font-size: 12px; line-height: 1.66666667; color: #555555; } #mm .form-control { display: block; width: 100%; height: 34px; padding: 6px 12px; margin: 0; font-size: 12px; line-height: 1.66666667; color: #555555; background-color: #fff; background-image: none; border: 1px solid #ccc; border-radius: 3px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; } #mm .form-control:focus { border-color: #66afe9; outline: 0; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); } #mm .form-control::-moz-placeholder { color: #999; opacity: 1; } #mm .form-control:-ms-input-placeholder { color: #999; } #mm .form-control::-webkit-input-placeholder { color: #999; } #mm .form-control[disabled], #mm .form-control[readonly], fieldset[disabled] #mm .form-control { background-color: #eeeeee; opacity: 1; } #mm .form-control[disabled], fieldset[disabled] #mm .form-control { cursor: not-allowed; } #mm textarea.form-control { height: auto; } #mm input[type="search"] { -webkit-appearance: none; } @media screen and (-webkit-min-device-pixel-ratio: 0) { #mm input[type="date"].form-control, #mm input[type="time"].form-control, #mm input[type="datetime-local"].form-control, #mm input[type="month"].form-control { line-height: 34px; } #mm input[type="date"].input-sm, #mm input[type="time"].input-sm, #mm input[type="datetime-local"].input-sm, #mm input[type="month"].input-sm, .input-group-sm #mm input[type="date"], .input-group-sm #mm input[type="time"], .input-group-sm #mm input[type="datetime-local"], .input-group-sm #mm input[type="month"] { line-height: 28px; } #mm input[type="date"].input-lg, #mm input[type="time"].input-lg, #mm input[type="datetime-local"].input-lg, #mm input[type="month"].input-lg, .input-group-lg #mm input[type="date"], .input-group-lg #mm input[type="time"], .input-group-lg #mm input[type="datetime-local"], .input-group-lg #mm input[type="month"] { line-height: 42px; } } #mm .form-group { margin-bottom: 15px; } #mm .radio, #mm .checkbox { position: relative; display: block; margin-top: 10px; margin-bottom: 10px; } #mm .radio label, #mm .checkbox label { min-height: 20px; padding-left: 20px; margin-bottom: 0; font-weight: normal; cursor: pointer; } #mm .radio input[type="radio"], #mm .radio-inline input[type="radio"], #mm .checkbox input[type="checkbox"], #mm .checkbox-inline input[type="checkbox"] { position: absolute; margin-left: -20px; margin-top: 4px \9; } #mm .radio + .radio, #mm .checkbox + .checkbox { margin-top: -5px; } #mm .radio-inline, #mm .checkbox-inline { position: relative; display: inline-block; padding-left: 20px; margin-bottom: 0; vertical-align: middle; font-weight: normal; cursor: pointer; } #mm .radio-inline + .radio-inline, #mm .checkbox-inline + .checkbox-inline { margin-top: 0; margin-left: 10px; } #mm input[type="radio"][disabled], #mm input[type="checkbox"][disabled], #mm input[type="radio"].disabled, #mm input[type="checkbox"].disabled, fieldset[disabled] #mm input[type="radio"], fieldset[disabled] #mm input[type="checkbox"] { cursor: not-allowed; } #mm .radio-inline.disabled, #mm .checkbox-inline.disabled, fieldset[disabled] #mm .radio-inline, fieldset[disabled] #mm .checkbox-inline { cursor: not-allowed; } #mm .radio.disabled label, #mm .checkbox.disabled label, fieldset[disabled] #mm .radio label, fieldset[disabled] #mm .checkbox label { cursor: not-allowed; } #mm .form-control-static { padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; min-height: 32px; } #mm .form-control-static.input-lg, #mm .form-control-static.input-sm { padding-left: 0; padding-right: 0; } #mm .input-sm { height: 28px; padding: 5px 10px; font-size: 11px; line-height: 1.5; border-radius: 2px; } select#mm .input-sm { height: 28px; line-height: 28px; } textarea#mm .input-sm, select[multiple]#mm .input-sm { height: auto; } #mm .form-group-sm .form-control { height: 28px; padding: 5px 10px; font-size: 11px; line-height: 1.5; border-radius: 2px; } #mm .form-group-sm select.form-control { height: 28px; line-height: 28px; } #mm .form-group-sm textarea.form-control, #mm .form-group-sm select[multiple].form-control { height: auto; } #mm .form-group-sm .form-control-static { height: 28px; min-height: 31px; padding: 6px 10px; font-size: 11px; line-height: 1.5; } #mm .input-lg { height: 42px; padding: 10px 16px; font-size: 15px; line-height: 1.3333333; border-radius: 5px; } select#mm .input-lg { height: 42px; line-height: 42px; } textarea#mm .input-lg, select[multiple]#mm .input-lg { height: auto; } #mm .form-group-lg .form-control { height: 42px; padding: 10px 16px; font-size: 15px; line-height: 1.3333333; border-radius: 5px; } #mm .form-group-lg select.form-control { height: 42px; line-height: 42px; } #mm .form-group-lg textarea.form-control, #mm .form-group-lg select[multiple].form-control { height: auto; } #mm .form-group-lg .form-control-static { height: 42px; min-height: 35px; padding: 11px 16px; font-size: 15px; line-height: 1.3333333; } #mm .has-feedback { position: relative; } #mm .has-feedback .form-control { padding-right: 42.5px; } #mm .form-control-feedback { position: absolute; top: 0; right: 0; z-index: 2; display: block; width: 34px; height: 34px; line-height: 34px; text-align: center; pointer-events: none; } #mm .input-lg + .form-control-feedback, #mm .input-group-lg + .form-control-feedback, #mm .form-group-lg .form-control + .form-control-feedback { width: 42px; height: 42px; line-height: 42px; } #mm .input-sm + .form-control-feedback, #mm .input-group-sm + .form-control-feedback, #mm .form-group-sm .form-control + .form-control-feedback { width: 28px; height: 28px; line-height: 28px; } #mm .has-success .help-block, #mm .has-success .control-label, #mm .has-success .radio, #mm .has-success .checkbox, #mm .has-success .radio-inline, #mm .has-success .checkbox-inline, #mm .has-success.radio label, #mm .has-success.checkbox label, #mm .has-success.radio-inline label, #mm .has-success.checkbox-inline label { color: #3c763d; } #mm .has-success .form-control { border-color: #3c763d; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } #mm .has-success .form-control:focus { border-color: #2b542c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; } #mm .has-success .input-group-addon { color: #3c763d; border-color: #3c763d; background-color: #dff0d8; } #mm .has-success .form-control-feedback { color: #3c763d; } #mm .has-warning .help-block, #mm .has-warning .control-label, #mm .has-warning .radio, #mm .has-warning .checkbox, #mm .has-warning .radio-inline, #mm .has-warning .checkbox-inline, #mm .has-warning.radio label, #mm .has-warning.checkbox label, #mm .has-warning.radio-inline label, #mm .has-warning.checkbox-inline label { color: #8a6d3b; } #mm .has-warning .form-control { border-color: #8a6d3b; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } #mm .has-warning .form-control:focus { border-color: #66512c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; } #mm .has-warning .input-group-addon { color: #8a6d3b; border-color: #8a6d3b; background-color: #fcf8e3; } #mm .has-warning .form-control-feedback { color: #8a6d3b; } #mm .has-error .help-block, #mm .has-error .control-label, #mm .has-error .radio, #mm .has-error .checkbox, #mm .has-error .radio-inline, #mm .has-error .checkbox-inline, #mm .has-error.radio label, #mm .has-error.checkbox label, #mm .has-error.radio-inline label, #mm .has-error.checkbox-inline label { color: #a94442; } #mm .has-error .form-control { border-color: #a94442; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } #mm .has-error .form-control:focus { border-color: #843534; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; } #mm .has-error .input-group-addon { color: #a94442; border-color: #a94442; background-color: #f2dede; } #mm .has-error .form-control-feedback { color: #a94442; } #mm .has-feedback label ~ .form-control-feedback { top: 25px; } #mm .has-feedback label.sr-only ~ .form-control-feedback { top: 0; } #mm .help-block { display: block; margin-top: 5px; margin-bottom: 10px; color: #737373; } @media (min-width: 768px) { #mm .form-inline .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } #mm .form-inline .form-control { display: inline-block; width: auto; vertical-align: middle; } #mm .form-inline .form-control-static { display: inline-block; } #mm .form-inline .input-group { display: inline-table; vertical-align: middle; } #mm .form-inline .input-group .input-group-addon, #mm .form-inline .input-group .input-group-btn, #mm .form-inline .input-group .form-control { width: auto; } #mm .form-inline .input-group > .form-control { width: 100%; } #mm .form-inline .control-label { margin-bottom: 0; vertical-align: middle; } #mm .form-inline .radio, #mm .form-inline .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } #mm .form-inline .radio label, #mm .form-inline .checkbox label { padding-left: 0; } #mm .form-inline .radio input[type="radio"], #mm .form-inline .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } #mm .form-inline .has-feedback .form-control-feedback { top: 0; } } #mm .form-horizontal .radio, #mm .form-horizontal .checkbox, #mm .form-horizontal .radio-inline, #mm .form-horizontal .checkbox-inline { margin-top: 0; margin-bottom: 0; padding-top: 7px; } #mm .form-horizontal .radio, #mm .form-horizontal .checkbox { min-height: 27px; } #mm .form-horizontal .form-group { margin-left: -15px; margin-right: -15px; } @media (min-width: 768px) { #mm .form-horizontal .control-label { text-align: right; margin-bottom: 0; padding-top: 7px; } } #mm .form-horizontal .has-feedback .form-control-feedback { right: 15px; } @media (min-width: 768px) { #mm .form-horizontal .form-group-lg .control-label { padding-top: 14.333333px; font-size: 15px; } } @media (min-width: 768px) { #mm .form-horizontal .form-group-sm .control-label { padding-top: 6px; font-size: 11px; } } #mm .fade { opacity: 0; -webkit-transition: opacity 0.15s linear; -o-transition: opacity 0.15s linear; transition: opacity 0.15s linear; } #mm .fade.in { opacity: 1; } #mm .collapse { display: none; } #mm .collapse.in { display: block; } tr#mm .collapse.in { display: table-row; } tbody#mm .collapse.in { display: table-row-group; } #mm .collapsing { position: relative; height: 0; overflow: hidden; -webkit-transition-property: height, visibility; transition-property: height, visibility; -webkit-transition-duration: 0.35s; transition-duration: 0.35s; -webkit-transition-timing-function: ease; transition-timing-function: ease; } #mm .caret { display: inline-block; width: 0; height: 0; margin-left: 2px; vertical-align: middle; border-top: 4px dashed; border-top: 4px solid \9; border-right: 4px solid transparent; border-left: 4px solid transparent; } #mm .dropup, #mm .dropdown { position: relative; } #mm .dropdown-toggle:focus { outline: 0; } #mm .dropdown-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; list-style: none; font-size: 12px; text-align: left; background-color: #fff; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 3px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); background-clip: padding-box; } #mm .dropdown-menu.pull-right { right: 0; left: auto; } #mm .dropdown-menu .divider { height: 1px; margin: 9px 0; overflow: hidden; background-color: #ccc; } #mm .dropdown-menu > li > a { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.66666667; color: #333; white-space: nowrap; } #mm .dropdown-menu > li > a:hover, #mm .dropdown-menu > li > a:focus { text-decoration: none; color: #262626; background-color: #f1f1f1; } #mm .dropdown-menu > .active > a, #mm .dropdown-menu > .active > a:hover, #mm .dropdown-menu > .active > a:focus { color: #fff; text-decoration: none; outline: 0; background-color: #428bca; } #mm .dropdown-menu > .disabled > a, #mm .dropdown-menu > .disabled > a:hover, #mm .dropdown-menu > .disabled > a:focus { color: #777777; } #mm .dropdown-menu > .disabled > a:hover, #mm .dropdown-menu > .disabled > a:focus { text-decoration: none; background-color: transparent; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); cursor: not-allowed; } #mm .open > .dropdown-menu { display: block; } #mm .open > a { outline: 0; } #mm .dropdown-menu-right { left: auto; right: 0; } #mm .dropdown-menu-left { left: 0; right: auto; } #mm .dropdown-header { display: block; padding: 3px 20px; font-size: 11px; line-height: 1.66666667; color: #777777; white-space: nowrap; } #mm .dropdown-backdrop { position: fixed; left: 0; right: 0; bottom: 0; top: 0; z-index: 990; } #mm .pull-right > .dropdown-menu { right: 0; left: auto; } #mm .dropup .caret, #mm .navbar-fixed-bottom .dropdown .caret { border-top: 0; border-bottom: 4px dashed; border-bottom: 4px solid \9; content: ""; } #mm .dropup .dropdown-menu, #mm .navbar-fixed-bottom .dropdown .dropdown-menu { top: auto; bottom: 100%; margin-bottom: 2px; } @media (min-width: 768px) { #mm .navbar-right .dropdown-menu { left: auto; right: 0; } #mm .navbar-right .dropdown-menu-left { left: 0; right: auto; } } #mm .btn-group, #mm .btn-group-vertical { position: relative; display: inline-block; vertical-align: middle; } #mm .btn-group > .btn, #mm .btn-group-vertical > .btn { position: relative; float: left; } #mm .btn-group > .btn:hover, #mm .btn-group-vertical > .btn:hover, #mm .btn-group > .btn:focus, #mm .btn-group-vertical > .btn:focus, #mm .btn-group > .btn:active, #mm .btn-group-vertical > .btn:active, #mm .btn-group > .btn.active, #mm .btn-group-vertical > .btn.active { z-index: 2; } #mm .btn-group .btn + .btn, #mm .btn-group .btn + .btn-group, #mm .btn-group .btn-group + .btn, #mm .btn-group .btn-group + .btn-group { margin-left: -1px; } #mm .btn-toolbar { margin-left: -5px; } #mm .btn-toolbar .btn, #mm .btn-toolbar .btn-group, #mm .btn-toolbar .input-group { float: left; } #mm .btn-toolbar > .btn, #mm .btn-toolbar > .btn-group, #mm .btn-toolbar > .input-group { margin-left: 5px; } #mm .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { border-radius: 0; } #mm .btn-group > .btn:first-child { margin-left: 0; } #mm .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { border-bottom-right-radius: 0; border-top-right-radius: 0; } #mm .btn-group > .btn:last-child:not(:first-child), #mm .btn-group > .dropdown-toggle:not(:first-child) { border-bottom-left-radius: 0; border-top-left-radius: 0; } #mm .btn-group > .btn-group { float: left; } #mm .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } #mm .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, #mm .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-top-right-radius: 0; } #mm .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { border-bottom-left-radius: 0; border-top-left-radius: 0; } #mm .btn-group .dropdown-toggle:active, #mm .btn-group.open .dropdown-toggle { outline: 0; } #mm .btn-group > .btn + .dropdown-toggle { padding-left: 8px; padding-right: 8px; } #mm .btn-group > .btn-lg + .dropdown-toggle { padding-left: 12px; padding-right: 12px; } #mm .btn-group.open .dropdown-toggle { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } #mm .btn-group.open .dropdown-toggle.btn-link { -webkit-box-shadow: none; box-shadow: none; } #mm .btn .caret { margin-left: 0; } #mm .btn-lg .caret { border-width: 5px 5px 0; border-bottom-width: 0; } #mm .dropup .btn-lg .caret { border-width: 0 5px 5px; } #mm .btn-group-vertical > .btn, #mm .btn-group-vertical > .btn-group, #mm .btn-group-vertical > .btn-group > .btn { display: block; float: none; width: 100%; max-width: 100%; } #mm .btn-group-vertical > .btn-group > .btn { float: none; } #mm .btn-group-vertical > .btn + .btn, #mm .btn-group-vertical > .btn + .btn-group, #mm .btn-group-vertical > .btn-group + .btn, #mm .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0; } #mm .btn-group-vertical > .btn:not(:first-child):not(:last-child) { border-radius: 0; } #mm .btn-group-vertical > .btn:first-child:not(:last-child) { border-top-right-radius: 3px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } #mm .btn-group-vertical > .btn:last-child:not(:first-child) { border-bottom-left-radius: 3px; border-top-right-radius: 0; border-top-left-radius: 0; } #mm .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } #mm .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, #mm .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0; } #mm .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-right-radius: 0; border-top-left-radius: 0; } #mm .btn-group-justified { display: table; width: 100%; table-layout: fixed; border-collapse: separate; } #mm .btn-group-justified > .btn, #mm .btn-group-justified > .btn-group { float: none; display: table-cell; width: 1%; } #mm .btn-group-justified > .btn-group .btn { width: 100%; } #mm .btn-group-justified > .btn-group .dropdown-menu { left: auto; } #mm [data-toggle="buttons"] > .btn input[type="radio"], #mm [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], #mm [data-toggle="buttons"] > .btn input[type="checkbox"], #mm [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none; } #mm .input-group { position: relative; display: table; border-collapse: separate; } #mm .input-group[class*="col-"] { float: none; padding-left: 0; padding-right: 0; } #mm .input-group .form-control { position: relative; z-index: 2; float: left; width: 100%; margin-bottom: 0; } #mm .input-group-lg > .form-control, #mm .input-group-lg > .input-group-addon, #mm .input-group-lg > .input-group-btn > .btn { height: 42px; padding: 10px 16px; font-size: 15px; line-height: 1.3333333; border-radius: 5px; } select#mm .input-group-lg > .form-control, select#mm .input-group-lg > .input-group-addon, select#mm .input-group-lg > .input-group-btn > .btn { height: 42px; line-height: 42px; } textarea#mm .input-group-lg > .form-control, textarea#mm .input-group-lg > .input-group-addon, textarea#mm .input-group-lg > .input-group-btn > .btn, select[multiple]#mm .input-group-lg > .form-control, select[multiple]#mm .input-group-lg > .input-group-addon, select[multiple]#mm .input-group-lg > .input-group-btn > .btn { height: auto; } #mm .input-group-sm > .form-control, #mm .input-group-sm > .input-group-addon, #mm .input-group-sm > .input-group-btn > .btn { height: 28px; padding: 5px 10px; font-size: 11px; line-height: 1.5; border-radius: 2px; } select#mm .input-group-sm > .form-control, select#mm .input-group-sm > .input-group-addon, select#mm .input-group-sm > .input-group-btn > .btn { height: 28px; line-height: 28px; } textarea#mm .input-group-sm > .form-control, textarea#mm .input-group-sm > .input-group-addon, textarea#mm .input-group-sm > .input-group-btn > .btn, select[multiple]#mm .input-group-sm > .form-control, select[multiple]#mm .input-group-sm > .input-group-addon, select[multiple]#mm .input-group-sm > .input-group-btn > .btn { height: auto; } #mm .input-group-addon, #mm .input-group-btn, #mm .input-group .form-control { display: table-cell; } #mm .input-group-addon:not(:first-child):not(:last-child), #mm .input-group-btn:not(:first-child):not(:last-child), #mm .input-group .form-control:not(:first-child):not(:last-child) { border-radius: 0; } #mm .input-group-addon, #mm .input-group-btn { width: 1%; white-space: nowrap; vertical-align: middle; } #mm .input-group-addon { padding: 6px 12px; font-size: 12px; font-weight: normal; line-height: 1; color: #555555; text-align: center; background-color: #eeeeee; border: 1px solid #ccc; border-radius: 3px; } #mm .input-group-addon.input-sm { padding: 5px 10px; font-size: 11px; border-radius: 2px; } #mm .input-group-addon.input-lg { padding: 10px 16px; font-size: 15px; border-radius: 5px; } #mm .input-group-addon input[type="radio"], #mm .input-group-addon input[type="checkbox"] { margin-top: 0; } #mm .input-group .form-control:first-child, #mm .input-group-addon:first-child, #mm .input-group-btn:first-child > .btn, #mm .input-group-btn:first-child > .btn-group > .btn, #mm .input-group-btn:first-child > .dropdown-toggle, #mm .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), #mm .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { border-bottom-right-radius: 0; border-top-right-radius: 0; } #mm .input-group-addon:first-child { border-right: 0; } #mm .input-group .form-control:last-child, #mm .input-group-addon:last-child, #mm .input-group-btn:last-child > .btn, #mm .input-group-btn:last-child > .btn-group > .btn, #mm .input-group-btn:last-child > .dropdown-toggle, #mm .input-group-btn:first-child > .btn:not(:first-child), #mm .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { border-bottom-left-radius: 0; border-top-left-radius: 0; } #mm .input-group-addon:last-child { border-left: 0; } #mm .input-group-btn { position: relative; font-size: 0; white-space: nowrap; } #mm .input-group-btn > .btn { position: relative; height: 34px; } #mm .input-group-btn > .btn + .btn { margin-left: -1px; } #mm .input-group-btn > .btn:hover, #mm .input-group-btn > .btn:focus, #mm .input-group-btn > .btn:active { z-index: 2; } #mm .input-group-btn:first-child > .btn, #mm .input-group-btn:first-child > .btn-group { margin-right: -1px; } #mm .input-group-btn:last-child > .btn, #mm .input-group-btn:last-child > .btn-group { z-index: 2; margin-left: -1px; } #mm .badge { display: inline-block; min-width: 10px; padding: 3px 7px; font-size: 11px; font-weight: bold; color: #fff; line-height: 1; vertical-align: middle; white-space: nowrap; text-align: center; background-color: #777777; border-radius: 10px; } #mm .badge:empty { display: none; } .btn #mm .badge { position: relative; top: -1px; } .btn-xs #mm .badge, .btn-group-xs > .btn #mm .badge { top: 0; padding: 1px 5px; } a#mm .badge:hover, a#mm .badge:focus { color: #fff; text-decoration: none; cursor: pointer; } .list-group-item.active > #mm .badge, .nav-pills > .active > a > #mm .badge { color: #428bca; background-color: #fff; } .list-group-item > #mm .badge { float: right; } .list-group-item > #mm .badge + #mm .badge { margin-right: 5px; } .nav-pills > li > a > #mm .badge { margin-left: 3px; } @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } #mm .progress { overflow: hidden; height: 20px; margin-bottom: 20px; background-color: #f5f5f5; border-radius: 3px; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } #mm .progress-bar { float: left; width: 0%; height: 100%; font-size: 11px; line-height: 20px; color: #fff; text-align: center; background-color: #428bca; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); -webkit-transition: width 0.6s ease; -o-transition: width 0.6s ease; transition: width 0.6s ease; } #mm .progress-striped .progress-bar, #mm .progress-bar-striped { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-size: 40px 40px; } #mm .progress.active .progress-bar, #mm .progress-bar.active { -webkit-animation: progress-bar-stripes 2s linear infinite; -o-animation: progress-bar-stripes 2s linear infinite; animation: progress-bar-stripes 2s linear infinite; } #mm .progress-bar-success { background-color: #5cb85c; } .progress-striped #mm .progress-bar-success { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } #mm .progress-bar-info { background-color: #5bc0de; } .progress-striped #mm .progress-bar-info { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } #mm .progress-bar-warning { background-color: #f0ad4e; } .progress-striped #mm .progress-bar-warning { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } #mm .progress-bar-danger { background-color: #d9534f; } .progress-striped #mm .progress-bar-danger { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } @font-face { font-family: 'font-awesome-mm'; src: url('../fonts/font-awesome-mm.eot?63801362'); src: url('../fonts/font-awesome-mm.eot?63801362#iefix') format('embedded-opentype'), url('../fonts/font-awesome-mm.woff2?63801362') format('woff2'), url('../fonts/font-awesome-mm.woff?63801362') format('woff'), url('../fonts/font-awesome-mm.ttf?63801362') format('truetype'), url('../fonts/font-awesome-mm.svg?63801362#font-awesome-mm') format('svg'); font-weight: normal; font-style: normal; } #mm [class^="icon-"]:before, #mm [class*=" icon-"]:before { font-family: "font-awesome-mm"; font-style: normal; font-weight: normal; speak: none; display: inline-block; text-decoration: inherit; width: 1em; margin-right: 0.2em; text-align: center; /* opacity: .8; */ /* For safety - reset parent styles, that can break glyph codes*/ font-variant: normal; text-transform: none; /* fix buttons height, for twitter bootstrap */ line-height: 1em; /* Animation center compensation - margins should be symmetric */ /* remove if not needed */ margin-left: 0.2em; /* you can be more comfortable with increased icons size */ /* font-size: 120%; */ /* Font smoothing. That was taken from TWBS */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; /* Uncomment for 3D effect */ /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ } #mm .icon-cancel:before { content: '\e800'; } #mm .icon-twitter:before { content: '\f099'; } #mm .icon-angle-left:before { content: '\f104'; } #mm .icon-angle-right:before { content: '\f105'; } #mm .icon-facebook-official:before { content: '\f230'; } #mm .t-mt-no { margin-top: 0 !important; } #mm .t-mr-no { margin-right: 0 !important; } #mm .t-mb-no { margin-bottom: 0 !important; } #mm .t-ml-no { margin-left: 0 !important; } #mm .t-mt--lg { margin-top: 16px !important; } #mm .t-mr--lg { margin-right: 16px !important; } #mm .t-mb--lg { margin-bottom: 16px !important; } #mm .t-ml--lg { margin-left: 16px !important; } #mm .t-mt--xl { margin-top: 20px !important; } #mm .t-mr--xl { margin-right: 20px !important; } #mm .t-mb--xl { margin-bottom: 20px !important; } #mm .t-ml--xl { margin-left: 20px !important; } #mm .t-lg-p--no { padding: 0 !important; } #mm .t-lg-pt--no { padding-top: 0 !important; } #mm .t-lg-pl--no { padding-left: 0 !important; } #mm .t-lg-pr--no { padding-right: 0 !important; } #mm .t-lg-pb--no { padding-bottom: 0 !important; } #mm .t-lg-m--no { margin: 0 !important; } #mm .t-lg-mt--no { margin-top: 0 !important; } #mm .t-lg-ml--no { margin-left: 0 !important; } #mm .t-lg-mr--no { margin-right: 0 !important; } #mm .t-lg-mb--no { margin-bottom: 0 !important; } #mm .t-lg-p--md { padding: 8px !important; } #mm .t-lg-pt--md { padding-top: 8px !important; } #mm .t-lg-pl--md { padding-left: 8px !important; } #mm .t-lg-pr--md { padding-right: 8px !important; } #mm .t-lg-pb--md { padding-bottom: 8px !important; } #mm .t-lg-m--md { margin: 8px !important; } #mm .t-lg-mt--md { margin-top: 8px !important; } #mm .t-lg-ml--md { margin-left: 8px !important; } #mm .t-lg-mr--md { margin-right: 8px !important; } #mm .t-lg-mb--md { margin-bottom: 8px !important; } #mm .t-lg-p--xs { padding: 2px !important; } #mm .t-lg-pt--xs { padding-top: 2px !important; } #mm .t-lg-pl--xs { padding-left: 2px !important; } #mm .t-lg-pr--xs { padding-right: 2px !important; } #mm .t-lg-pb--xs { padding-bottom: 2px !important; } #mm .t-lg-m--xs { margin: 2px !important; } #mm .t-lg-mt--xs { margin-top: 2px !important; } #mm .t-lg-ml--xs { margin-left: 2px !important; } #mm .t-lg-mr--xs { margin-right: 2px !important; } #mm .t-lg-mb--xs { margin-bottom: 2px !important; } #mm .t-lg-p--sm { padding: 4px !important; } #mm .t-lg-pt--sm { padding-top: 4px !important; } #mm .t-lg-pl--sm { padding-left: 4px !important; } #mm .t-lg-pr--sm { padding-right: 4px !important; } #mm .t-lg-pb--sm { padding-bottom: 4px !important; } #mm .t-lg-m--sm { margin: 4px !important; } #mm .t-lg-mt--sm { margin-top: 4px !important; } #mm .t-lg-ml--sm { margin-left: 4px !important; } #mm .t-lg-mr--sm { margin-right: 4px !important; } #mm .t-lg-mb--sm { margin-bottom: 4px !important; } #mm .t-lg-p--lg { padding: 16px !important; } #mm .t-lg-pt--lg { padding-top: 16px !important; } #mm .t-lg-pl--lg { padding-left: 16px !important; } #mm .t-lg-pr--lg { padding-right: 16px !important; } #mm .t-lg-pb--lg { padding-bottom: 16px !important; } #mm .t-lg-m--lg { margin: 16px !important; } #mm .t-lg-mt--lg { margin-top: 16px !important; } #mm .t-lg-ml--lg { margin-left: 16px !important; } #mm .t-lg-mr--lg { margin-right: 16px !important; } #mm .t-lg-mb--lg { margin-bottom: 16px !important; } #mm .t-lg-p--xl { padding: 20px !important; } #mm .t-lg-pt--xl { padding-top: 20px !important; } #mm .t-lg-pl--xl { padding-left: 20px !important; } #mm .t-lg-pr--xl { padding-right: 20px !important; } #mm .t-lg-pb--xl { padding-bottom: 20px !important; } #mm .t-lg-m--xl { margin: 20px !important; } #mm .t-lg-mt--xl { margin-top: 20px !important; } #mm .t-lg-ml--xl { margin-left: 20px !important; } #mm .t-lg-mr--xl { margin-right: 20px !important; } #mm .t-lg-mb--xl { margin-bottom: 20px !important; } #mm.w640 .t-md-p--no { padding: 0 !important; } #mm.w640 .t-md-pt--no { padding-top: 0 !important; } #mm.w640 .t-md-pl--no { padding-left: 0 !important; } #mm.w640 .t-md-pr--no { padding-right: 0 !important; } #mm.w640 .t-md-pb--no { padding-bottom: 0 !important; } #mm.w640 .t-md-m--no { margin: 0 !important; } #mm.w640 .t-md-mt--no { margin-top: 0 !important; } #mm.w640 .t-md-ml--no { margin-left: 0 !important; } #mm.w640 .t-md-mr--no { margin-right: 0 !important; } #mm.w640 .t-md-mb--no { margin-bottom: 0 !important; } #mm.w640 .t-md-p--md { padding: 8px !important; } #mm.w640 .t-md-pt--md { padding-top: 8px !important; } #mm.w640 .t-md-pl--md { padding-left: 8px !important; } #mm.w640 .t-md-pr--md { padding-right: 8px !important; } #mm.w640 .t-md-pb--md { padding-bottom: 8px !important; } #mm.w640 .t-md-m--md { margin: 8px !important; } #mm.w640 .t-md-mt--md { margin-top: 8px !important; } #mm.w640 .t-md-ml--md { margin-left: 8px !important; } #mm.w640 .t-md-mr--md { margin-right: 8px !important; } #mm.w640 .t-md-mb--md { margin-bottom: 8px !important; } #mm.w640 .t-md-p--xs { padding: 2px !important; } #mm.w640 .t-md-pt--xs { padding-top: 2px !important; } #mm.w640 .t-md-pl--xs { padding-left: 2px !important; } #mm.w640 .t-md-pr--xs { padding-right: 2px !important; } #mm.w640 .t-md-pb--xs { padding-bottom: 2px !important; } #mm.w640 .t-md-m--xs { margin: 2px !important; } #mm.w640 .t-md-mt--xs { margin-top: 2px !important; } #mm.w640 .t-md-ml--xs { margin-left: 2px !important; } #mm.w640 .t-md-mr--xs { margin-right: 2px !important; } #mm.w640 .t-md-mb--xs { margin-bottom: 2px !important; } #mm.w640 .t-md-p--sm { padding: 4px !important; } #mm.w640 .t-md-pt--sm { padding-top: 4px !important; } #mm.w640 .t-md-pl--sm { padding-left: 4px !important; } #mm.w640 .t-md-pr--sm { padding-right: 4px !important; } #mm.w640 .t-md-pb--sm { padding-bottom: 4px !important; } #mm.w640 .t-md-m--sm { margin: 4px !important; } #mm.w640 .t-md-mt--sm { margin-top: 4px !important; } #mm.w640 .t-md-ml--sm { margin-left: 4px !important; } #mm.w640 .t-md-mr--sm { margin-right: 4px !important; } #mm.w640 .t-md-mb--sm { margin-bottom: 4px !important; } #mm.w640 .t-md-p--lg { padding: 16px !important; } #mm.w640 .t-md-pt--lg { padding-top: 16px !important; } #mm.w640 .t-md-pl--lg { padding-left: 16px !important; } #mm.w640 .t-md-pr--lg { padding-right: 16px !important; } #mm.w640 .t-md-pb--lg { padding-bottom: 16px !important; } #mm.w640 .t-md-m--lg { margin: 16px !important; } #mm.w640 .t-md-mt--lg { margin-top: 16px !important; } #mm.w640 .t-md-ml--lg { margin-left: 16px !important; } #mm.w640 .t-md-mr--lg { margin-right: 16px !important; } #mm.w640 .t-md-mb--lg { margin-bottom: 16px !important; } #mm.w640 .t-md-p--xl { padding: 20px !important; } #mm.w640 .t-md-pt--xl { padding-top: 20px !important; } #mm.w640 .t-md-pl--xl { padding-left: 20px !important; } #mm.w640 .t-md-pr--xl { padding-right: 20px !important; } #mm.w640 .t-md-pb--xl { padding-bottom: 20px !important; } #mm.w640 .t-md-m--xl { margin: 20px !important; } #mm.w640 .t-md-mt--xl { margin-top: 20px !important; } #mm.w640 .t-md-ml--xl { margin-left: 20px !important; } #mm.w640 .t-md-mr--xl { margin-right: 20px !important; } #mm.w640 .t-md-mb--xl { margin-bottom: 20px !important; } #mm.w480 .t-xs-p--no { padding: 0 !important; } #mm.w480 .t-xs-pt--no { padding-top: 0 !important; } #mm.w480 .t-xs-pl--no { padding-left: 0 !important; } #mm.w480 .t-xs-pr--no { padding-right: 0 !important; } #mm.w480 .t-xs-pb--no { padding-bottom: 0 !important; } #mm.w480 .t-xs-m--no { margin: 0 !important; } #mm.w480 .t-xs-mt--no { margin-top: 0 !important; } #mm.w480 .t-xs-ml--no { margin-left: 0 !important; } #mm.w480 .t-xs-mr--no { margin-right: 0 !important; } #mm.w480 .t-xs-mb--no { margin-bottom: 0 !important; } #mm.w480 .t-xs-p--md { padding: 8px !important; } #mm.w480 .t-xs-pt--md { padding-top: 8px !important; } #mm.w480 .t-xs-pl--md { padding-left: 8px !important; } #mm.w480 .t-xs-pr--md { padding-right: 8px !important; } #mm.w480 .t-xs-pb--md { padding-bottom: 8px !important; } #mm.w480 .t-xs-m--md { margin: 8px !important; } #mm.w480 .t-xs-mt--md { margin-top: 8px !important; } #mm.w480 .t-xs-ml--md { margin-left: 8px !important; } #mm.w480 .t-xs-mr--md { margin-right: 8px !important; } #mm.w480 .t-xs-mb--md { margin-bottom: 8px !important; } #mm.w480 .t-xs-p--xs { padding: 2px !important; } #mm.w480 .t-xs-pt--xs { padding-top: 2px !important; } #mm.w480 .t-xs-pl--xs { padding-left: 2px !important; } #mm.w480 .t-xs-pr--xs { padding-right: 2px !important; } #mm.w480 .t-xs-pb--xs { padding-bottom: 2px !important; } #mm.w480 .t-xs-m--xs { margin: 2px !important; } #mm.w480 .t-xs-mt--xs { margin-top: 2px !important; } #mm.w480 .t-xs-ml--xs { margin-left: 2px !important; } #mm.w480 .t-xs-mr--xs { margin-right: 2px !important; } #mm.w480 .t-xs-mb--xs { margin-bottom: 2px !important; } #mm.w480 .t-xs-p--sm { padding: 4px !important; } #mm.w480 .t-xs-pt--sm { padding-top: 4px !important; } #mm.w480 .t-xs-pl--sm { padding-left: 4px !important; } #mm.w480 .t-xs-pr--sm { padding-right: 4px !important; } #mm.w480 .t-xs-pb--sm { padding-bottom: 4px !important; } #mm.w480 .t-xs-m--sm { margin: 4px !important; } #mm.w480 .t-xs-mt--sm { margin-top: 4px !important; } #mm.w480 .t-xs-ml--sm { margin-left: 4px !important; } #mm.w480 .t-xs-mr--sm { margin-right: 4px !important; } #mm.w480 .t-xs-mb--sm { margin-bottom: 4px !important; } #mm.w480 .t-xs-p--lg { padding: 16px !important; } #mm.w480 .t-xs-pt--lg { padding-top: 16px !important; } #mm.w480 .t-xs-pl--lg { padding-left: 16px !important; } #mm.w480 .t-xs-pr--lg { padding-right: 16px !important; } #mm.w480 .t-xs-pb--lg { padding-bottom: 16px !important; } #mm.w480 .t-xs-m--lg { margin: 16px !important; } #mm.w480 .t-xs-mt--lg { margin-top: 16px !important; } #mm.w480 .t-xs-ml--lg { margin-left: 16px !important; } #mm.w480 .t-xs-mr--lg { margin-right: 16px !important; } #mm.w480 .t-xs-mb--lg { margin-bottom: 16px !important; } #mm.w480 .t-xs-p--xl { padding: 20px !important; } #mm.w480 .t-xs-pt--xl { padding-top: 20px !important; } #mm.w480 .t-xs-pl--xl { padding-left: 20px !important; } #mm.w480 .t-xs-pr--xl { padding-right: 20px !important; } #mm.w480 .t-xs-pb--xl { padding-bottom: 20px !important; } #mm.w480 .t-xs-m--xl { margin: 20px !important; } #mm.w480 .t-xs-mt--xl { margin-top: 20px !important; } #mm.w480 .t-xs-ml--xl { margin-left: 20px !important; } #mm.w480 .t-xs-mr--xl { margin-right: 20px !important; } #mm.w480 .t-xs-mb--xl { margin-bottom: 20px !important; } #mm .t-icon--primary { color: #428bca; } #mm .t-icon--success { color: #39b54a; } #mm .t-icon--danger { color: #d9534f; } #mm .t-icon--default { color: #fff; } #mm .t-icon--info { color: #5BC0DE; } #mm .t-icon--warning { color: #EC971F; } #mm .t-hidden { display: none !important; } #mm .t-block { display: block !important; } #mm .t-inline { display: inline !important; } #mm .t-inline-block { display: inline-block !important; } #mm .pull-left, #mm .t-lg-pull-left { float: left !important; } #mm .pull-right, #mm .t-lg-pull-right { float: right !important; } #mm.w480 .t-lg-pull-left, #mm.w480 .t-lg-pull-right { float: none !important; } #mm .t-lg-pull-right { float: right !important; } #mm .t-xs-visible { display: none; } #mm.w480 .t-xs-visible { display: inline-block; } #mm .t-fs--sm { font-size: 12px !important; } #mm .t-fs--lg { font-size: 16px !important; } #mm .t-text--left { text-align: left !important; } #mm .t-text--right { text-align: right !important; } #mm .t-text--center { text-align: center !important; } #mm .t-text--justify { text-align: justify !important; } #mm .t-text--nowrap { white-space: nowrap !important; } #mm .t-text--lowercase { text-transform: lowercase !important; } #mm .t-text--uppercase { text-transform: uppercase !important; } #mm .t-text--capitalize { text-transform: capitalize !important; } #mm .t-text--muted { color: #888 !important; } #mm .t-text-version { color: #90a4ae !important; } #mm .t-bdt-no { border-top: none !important; } #mm .t-bdr-no { border-right: none !important; } #mm .t-bdb-no { border-bottom: none !important; } #mm .t-bdl-no { border-left: none !important; } PK!61D1D'system/metaman/assets/scripts/script.jsnu[ jQuery(document).ready(function($) { // Our own serializeObject method $.fn.toObject = $.fn.serializeObject = function() { var obj = {}; $.each($(this).serializeArray(), function(i, prop) { if (obj.hasOwnProperty(prop.name)) { // Convert it into an array if (!$.isArray(obj[prop.name])) { obj[prop.name] = [obj[prop.name]]; } obj[prop.name].push(prop.value); } else { obj[prop.name] = prop.value; } }); return obj; }; var MM = { baseUrl: '', ajaxUrl: "", metas: '', toggleLoading: function() { var wrapper = this.getFormWrapper(); if (wrapper.hasClass('is-loading')) { wrapper.removeClass('is-loading'); } wrapper.addClass('is-loading'); }, computeCard: function() { var score = 100; var data = this.metas.card; if (!data.card) { score -= 40; } if (!data.site) { score -= 10; } if (!data.title) { score -= 10; } if (!data.description) { score -= 10; } if (!data.description) { score -= 5; } return this.getScoreClass(score); }, computeMeta: function() { var score = 100; var data = this.metas.meta; if (!data.title) { score -= 40; } if (!data.description) { score -= 30; } // If the meta description is too large, we should warn the user if (data.description.length > 160) { score -= 15; } var className = this.getScoreClass(score); return className; }, computeOpengraph: function() { var score = 100; var data = this.metas.opengraph; if (!data.type) { score -= 20; } if (!data.title) { score -= 10; } if (!data.description) { score -= 10; } // If the meta description is too large, we should warn the user if (!data.description.image) { score -= 25; } return this.getScoreClass(score); }, initialize: function() { this.baseUrl = this.getSettings('base_url'); this.ajaxUrl = this.getSettings('ajax_url'); this.initializeMetas(); // Append the buttons var template = '
    '; if (this.getSettings('card')) { template += 'mm tw'; } if (this.getSettings('opengraph')) { template += 'mm fb'; } if (this.getSettings('meta')) { template += 'mm base'; } template += '
    '; $('body').append(template); // Calculate the progress of each of the meta buttons this.updateButtonProgress(); }, initializeMetas: function() { this.metas = { "card": { "card": this.getCardContent('card'), "site": this.getCardContent('site'), "title": this.getCardContent('title'), "description": this.getCardContent('description'), "image": this.getCardContent('image') }, "meta": { "title": $('title').html(), "description": this.getMetaContent('description'), "keywords": this.getMetaContent('keywords'), "author": this.getMetaContent('author'), "generator": this.getMetaContent('generator'), "canonical": this.getCanonical() }, "opengraph": { "type": this.getOpengraphContent('type'), "url": this.getOpengraphContent('url'), "site_name": this.getOpengraphContent('site_name'), "title": this.getOpengraphContent('title'), "description": this.getOpengraphContent('description'), "image": this.getOpengraphContent('image'), "image_width": this.getOpengraphContent('image_width'), "image_height": this.getOpengraphContent('image_height'), "profile_id": this.getOpengraphContent('profile_id'), "app_id": this.getOpengraphContent('app_id'), "video": this.getOpengraphContent('video'), "video_type": this.getOpengraphContent('video_type'), "video_width": this.getOpengraphContent('video_width'), "video_height": this.getOpengraphContent('video_height') } }; }, getSettings: function(name) { return this.getMetaContent('mm_' + name); }, getScoreClass: function(score) { var className; if (score <= 35) { className = 'danger'; } if (score > 35 && score <= 70) { className = 'warning'; } if (score > 70) { className = 'success'; } return "mm-icon--" + className; }, getFormWrapper: function() { return $('[data-mm-form]'); }, getButton: function(type) { return $('[data-mm-button-' + type + ']'); }, getCurrentUrl: function() { return this.getMetaContent('mm_url'); }, getCurrentHash: function() { return this.getMetaContent('mm_hash'); }, setMeta: function(name, value) { var selector = 'meta[name=' + name + ']'; $(selector).attr('content', value); }, getMetaContent: function(name, prefix, attribute) { var selector = 'meta[name=' + name + ']'; var attribute = attribute == undefined ? 'name' : attribute; if (prefix !== undefined) { selector = 'meta[' + attribute + '=' + prefix + '\\:' + name + ']'; } var content = $(selector).attr('content'); if (content === undefined) { return ''; } // Sanitize the content var value = $('",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;d0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K); if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=e<0?h:f?e:0;i-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(""; foreach ($this->data as $g => $glyph) { if ($n-- <= 0) { break; } $glyph->parseData(); $shape = array( "SVGContours" => $glyph->getSVGContours(), "xMin" => $glyph->xMin, "yMin" => $glyph->yMin, "xMax" => $glyph->xMax, "yMax" => $glyph->yMax, ); $shape_json = json_encode($shape); $type = ($glyph instanceof OutlineSimple ? "simple" : "composite"); $char = isset($glyphIndexArray[$g]) ? $glyphIndexArray[$g] : 0; $name = isset($names[$g]) ? $names[$g] : sprintf("uni%04x", $char); $char = $char ? "&#{$glyphIndexArray[$g]};" : ""; $s .= "
    $g $char $name "; if ($type == "composite") { foreach ($glyph->getGlyphIDs() as $_id) { $s .= "$_id "; } } $s .= "
    "; } return $s; } protected function _encode() { $font = $this->getFont(); $subset = $font->getSubset(); $data = $this->data; $loca = array(); $length = 0; foreach ($subset as $gid) { $loca[] = $length; $length += $data[$gid]->encode(); } $loca[] = $length; // dummy loca $font->getTableObject("loca")->data = $loca; return $length; } }PK!~Hconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Autoloader.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace FontLib; /** * Autoloads FontLib classes * * @package php-font-lib */ class Autoloader { const PREFIX = 'FontLib'; /** * Register the autoloader */ public static function register() { spl_autoload_register(array(new self, 'autoload')); } /** * Autoloader * * @param string */ public static function autoload($class) { $prefixLength = strlen(self::PREFIX); if (0 === strncmp(self::PREFIX, $class, $prefixLength)) { $file = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, $prefixLength)); $file = realpath(__DIR__ . (empty($file) ? '' : DIRECTORY_SEPARATOR) . $file . '.php'); if (file_exists($file)) { require_once $file; } } } } Autoloader::register();PK!Z܁Nconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/AdobeFontMetrics.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace FontLib; use FontLib\Table\Type\name; use FontLib\TrueType\File; /** * Adobe Font Metrics file creation utility class. * * @package php-font-lib */ class AdobeFontMetrics { private $f; /** * @var File */ private $font; function __construct(File $font) { $this->font = $font; } function write($file, $encoding = null) { $map_data = array(); if ($encoding) { $encoding = preg_replace("/[^a-z0-9-_]/", "", $encoding); $map_file = dirname(__FILE__) . "/../maps/$encoding.map"; if (!file_exists($map_file)) { throw new \Exception("Unknown encoding ($encoding)"); } $map = new EncodingMap($map_file); $map_data = $map->parse(); } $this->f = fopen($file, "w+"); $font = $this->font; $this->startSection("FontMetrics", 4.1); $this->addPair("Notice", "Converted by PHP-font-lib"); $this->addPair("Comment", "https://github.com/PhenX/php-font-lib"); $encoding_scheme = ($encoding ? $encoding : "FontSpecific"); $this->addPair("EncodingScheme", $encoding_scheme); $records = $font->getData("name", "records"); foreach ($records as $id => $record) { if (!isset(name::$nameIdCodes[$id]) || preg_match("/[\r\n]/", $record->string)) { continue; } $this->addPair(name::$nameIdCodes[$id], $record->string); } $os2 = $font->getData("OS/2"); $this->addPair("Weight", ($os2["usWeightClass"] > 400 ? "Bold" : "Medium")); $post = $font->getData("post"); $this->addPair("ItalicAngle", $post["italicAngle"]); $this->addPair("IsFixedPitch", ($post["isFixedPitch"] ? "true" : "false")); $this->addPair("UnderlineThickness", $font->normalizeFUnit($post["underlineThickness"])); $this->addPair("UnderlinePosition", $font->normalizeFUnit($post["underlinePosition"])); $hhea = $font->getData("hhea"); if (isset($hhea["ascent"])) { $this->addPair("FontHeightOffset", $font->normalizeFUnit($hhea["lineGap"])); $this->addPair("Ascender", $font->normalizeFUnit($hhea["ascent"])); $this->addPair("Descender", $font->normalizeFUnit($hhea["descent"])); } else { $this->addPair("FontHeightOffset", $font->normalizeFUnit($os2["typoLineGap"])); $this->addPair("Ascender", $font->normalizeFUnit($os2["typoAscender"])); $this->addPair("Descender", -abs($font->normalizeFUnit($os2["typoDescender"]))); } $head = $font->getData("head"); $this->addArray("FontBBox", array( $font->normalizeFUnit($head["xMin"]), $font->normalizeFUnit($head["yMin"]), $font->normalizeFUnit($head["xMax"]), $font->normalizeFUnit($head["yMax"]), )); $glyphIndexArray = $font->getUnicodeCharMap(); if ($glyphIndexArray) { $hmtx = $font->getData("hmtx"); $names = $font->getData("post", "names"); $this->startSection("CharMetrics", count($hmtx)); if ($encoding) { foreach ($map_data as $code => $value) { list($c, $name) = $value; if (!isset($glyphIndexArray[$c])) { continue; } $g = $glyphIndexArray[$c]; if (!isset($hmtx[$g])) { $hmtx[$g] = $hmtx[0]; } $this->addMetric(array( "C" => ($code > 255 ? -1 : $code), "WX" => $font->normalizeFUnit($hmtx[$g][0]), "N" => $name, )); } } else { foreach ($glyphIndexArray as $c => $g) { if (!isset($hmtx[$g])) { $hmtx[$g] = $hmtx[0]; } $this->addMetric(array( "U" => $c, "WX" => $font->normalizeFUnit($hmtx[$g][0]), "N" => (isset($names[$g]) ? $names[$g] : sprintf("uni%04x", $c)), "G" => $g, )); } } $this->endSection("CharMetrics"); $kern = $font->getData("kern", "subtable"); $tree = is_array($kern) ? $kern["tree"] : null; if (!$encoding && is_array($tree)) { $this->startSection("KernData"); $this->startSection("KernPairs", count($tree, COUNT_RECURSIVE) - count($tree)); foreach ($tree as $left => $values) { if (!is_array($values)) { continue; } if (!isset($glyphIndexArray[$left])) { continue; } $left_gid = $glyphIndexArray[$left]; if (!isset($names[$left_gid])) { continue; } $left_name = $names[$left_gid]; $this->addLine(""); foreach ($values as $right => $value) { if (!isset($glyphIndexArray[$right])) { continue; } $right_gid = $glyphIndexArray[$right]; if (!isset($names[$right_gid])) { continue; } $right_name = $names[$right_gid]; $this->addPair("KPX", "$left_name $right_name $value"); } } $this->endSection("KernPairs"); $this->endSection("KernData"); } } $this->endSection("FontMetrics"); } function addLine($line) { fwrite($this->f, "$line\n"); } function addPair($key, $value) { $this->addLine("$key $value"); } function addArray($key, $array) { $this->addLine("$key " . implode(" ", $array)); } function addMetric($data) { $array = array(); foreach ($data as $key => $value) { $array[] = "$key $value"; } $this->addLine(implode(" ; ", $array)); } function startSection($name, $value = "") { $this->addLine("Start$name $value"); } function endSection($name) { $this->addLine("End$name"); } } PK!@Kconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/OpenType/File.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace FontLib\OpenType; /** * Open Type font, the same as a TrueType one. * * @package php-font-lib */ class File extends \FontLib\TrueType\File { // } PK!8Zconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace FontLib\OpenType; /** * Open Type Table directory entry, the same as a TrueType one. * * @package php-font-lib */ class TableDirectoryEntry extends \FontLib\TrueType\TableDirectoryEntry { } PK!"buuTconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Glyph/OutlineComposite.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ */ namespace FontLib\Glyph; /** * Composite glyph outline * * @package php-font-lib */ class OutlineComposite extends Outline { const ARG_1_AND_2_ARE_WORDS = 0x0001; const ARGS_ARE_XY_VALUES = 0x0002; const ROUND_XY_TO_GRID = 0x0004; const WE_HAVE_A_SCALE = 0x0008; const MORE_COMPONENTS = 0x0020; const WE_HAVE_AN_X_AND_Y_SCALE = 0x0040; const WE_HAVE_A_TWO_BY_TWO = 0x0080; const WE_HAVE_INSTRUCTIONS = 0x0100; const USE_MY_METRICS = 0x0200; const OVERLAP_COMPOUND = 0x0400; /** * @var OutlineComponent[] */ public $components = array(); function getGlyphIDs() { if (empty($this->components)) { $this->parseData(); } $glyphIDs = array(); foreach ($this->components as $_component) { $glyphIDs[] = $_component->glyphIndex; $_glyph = $this->table->data[$_component->glyphIndex]; if ($_glyph !== $this) { $glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs()); } } return $glyphIDs; } /*function parse() { //$this->parseData(); }*/ function parseData() { parent::parseData(); $font = $this->getFont(); do { $flags = $font->readUInt16(); $glyphIndex = $font->readUInt16(); $a = 1.0; $b = 0.0; $c = 0.0; $d = 1.0; $e = 0.0; $f = 0.0; $point_compound = null; $point_component = null; $instructions = null; if ($flags & self::ARG_1_AND_2_ARE_WORDS) { if ($flags & self::ARGS_ARE_XY_VALUES) { $e = $font->readInt16(); $f = $font->readInt16(); } else { $point_compound = $font->readUInt16(); $point_component = $font->readUInt16(); } } else { if ($flags & self::ARGS_ARE_XY_VALUES) { $e = $font->readInt8(); $f = $font->readInt8(); } else { $point_compound = $font->readUInt8(); $point_component = $font->readUInt8(); } } if ($flags & self::WE_HAVE_A_SCALE) { $a = $d = $font->readInt16(); } elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) { $a = $font->readInt16(); $d = $font->readInt16(); } elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) { $a = $font->readInt16(); $b = $font->readInt16(); $c = $font->readInt16(); $d = $font->readInt16(); } //if ($flags & self::WE_HAVE_INSTRUCTIONS) { // //} $component = new OutlineComponent(); $component->flags = $flags; $component->glyphIndex = $glyphIndex; $component->a = $a; $component->b = $b; $component->c = $c; $component->d = $d; $component->e = $e; $component->f = $f; $component->point_compound = $point_compound; $component->point_component = $point_component; $component->instructions = $instructions; $this->components[] = $component; } while ($flags & self::MORE_COMPONENTS); } function encode() { $font = $this->getFont(); $gids = $font->getSubset(); $size = $font->writeInt16(-1); $size += $font->writeFWord($this->xMin); $size += $font->writeFWord($this->yMin); $size += $font->writeFWord($this->xMax); $size += $font->writeFWord($this->yMax); foreach ($this->components as $_i => $_component) { $flags = 0; if ($_component->point_component === null && $_component->point_compound === null) { $flags |= self::ARGS_ARE_XY_VALUES; if (abs($_component->e) > 0x7F || abs($_component->f) > 0x7F) { $flags |= self::ARG_1_AND_2_ARE_WORDS; } } elseif ($_component->point_component > 0xFF || $_component->point_compound > 0xFF) { $flags |= self::ARG_1_AND_2_ARE_WORDS; } if ($_component->b == 0 && $_component->c == 0) { if ($_component->a == $_component->d) { if ($_component->a != 1.0) { $flags |= self::WE_HAVE_A_SCALE; } } else { $flags |= self::WE_HAVE_AN_X_AND_Y_SCALE; } } else { $flags |= self::WE_HAVE_A_TWO_BY_TWO; } if ($_i < count($this->components) - 1) { $flags |= self::MORE_COMPONENTS; } $size += $font->writeUInt16($flags); $new_gid = array_search($_component->glyphIndex, $gids); $size += $font->writeUInt16($new_gid); if ($flags & self::ARG_1_AND_2_ARE_WORDS) { if ($flags & self::ARGS_ARE_XY_VALUES) { $size += $font->writeInt16($_component->e); $size += $font->writeInt16($_component->f); } else { $size += $font->writeUInt16($_component->point_compound); $size += $font->writeUInt16($_component->point_component); } } else { if ($flags & self::ARGS_ARE_XY_VALUES) { $size += $font->writeInt8($_component->e); $size += $font->writeInt8($_component->f); } else { $size += $font->writeUInt8($_component->point_compound); $size += $font->writeUInt8($_component->point_component); } } if ($flags & self::WE_HAVE_A_SCALE) { $size += $font->writeInt16($_component->a); } elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) { $size += $font->writeInt16($_component->a); $size += $font->writeInt16($_component->d); } elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) { $size += $font->writeInt16($_component->a); $size += $font->writeInt16($_component->b); $size += $font->writeInt16($_component->c); $size += $font->writeInt16($_component->d); } } return $size; } public function getSVGContours() { $contours = array(); /** @var \FontLib\Table\Type\glyf $glyph_data */ $glyph_data = $this->getFont()->getTableObject("glyf"); /** @var Outline[] $glyphs */ $glyphs = $glyph_data->data; foreach ($this->components as $component) { $_glyph = $glyphs[$component->glyphIndex]; if ($_glyph !== $this) { $contours[] = array( "contours" => $_glyph->getSVGContours(), "transform" => $component->getMatrix(), ); } } return $contours; } }PK!9Kconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Glyph/Outline.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ */ namespace FontLib\Glyph; use FontLib\Table\Type\glyf; use FontLib\TrueType\File; use FontLib\BinaryStream; /** * `glyf` font table. * * @package php-font-lib */ class Outline extends BinaryStream { /** * @var \FontLib\Table\Type\glyf */ protected $table; protected $offset; protected $size; // Data public $numberOfContours; public $xMin; public $yMin; public $xMax; public $yMax; /** * @var string|null */ public $raw; /** * @param glyf $table * @param $offset * @param $size * * @return Outline */ static function init(glyf $table, $offset, $size, BinaryStream $font) { $font->seek($offset); if ($font->readInt16() > -1) { /** @var OutlineSimple $glyph */ $glyph = new OutlineSimple($table, $offset, $size); } else { /** @var OutlineComposite $glyph */ $glyph = new OutlineComposite($table, $offset, $size); } $glyph->parse($font); return $glyph; } /** * @return File */ function getFont() { return $this->table->getFont(); } function __construct(glyf $table, $offset = null, $size = null) { $this->table = $table; $this->offset = $offset; $this->size = $size; } function parse(BinaryStream $font) { $font->seek($this->offset); $this->raw = $font->read($this->size); } function parseData() { $font = $this->getFont(); $font->seek($this->offset); $this->numberOfContours = $font->readInt16(); $this->xMin = $font->readFWord(); $this->yMin = $font->readFWord(); $this->xMax = $font->readFWord(); $this->yMax = $font->readFWord(); } function encode() { $font = $this->getFont(); return $font->write($this->raw, mb_strlen((string) $this->raw, '8bit')); } function getSVGContours() { // Inherit } function getGlyphIDs() { return array(); } } PK!yF|Tconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Glyph/OutlineComponent.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ */ namespace FontLib\Glyph; /** * Glyph outline component * * @package php-font-lib */ class OutlineComponent { public $flags; public $glyphIndex; public $a, $b, $c, $d, $e, $f; public $point_compound; public $point_component; public $instructions; function getMatrix() { return array( $this->a, $this->b, $this->c, $this->d, $this->e, $this->f, ); } }PK!f Qconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Glyph/OutlineSimple.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ */ namespace FontLib\Glyph; /** * `glyf` font table. * * @package php-font-lib */ class OutlineSimple extends Outline { const ON_CURVE = 0x01; const X_SHORT_VECTOR = 0x02; const Y_SHORT_VECTOR = 0x04; const REPEAT = 0x08; const THIS_X_IS_SAME = 0x10; const THIS_Y_IS_SAME = 0x20; public $instructions; public $points; function parseData() { parent::parseData(); if (!$this->size) { return; } $font = $this->getFont(); $noc = $this->numberOfContours; if ($noc == 0) { return; } $endPtsOfContours = $font->r(array(self::uint16, $noc)); $instructionLength = $font->readUInt16(); $this->instructions = $font->r(array(self::uint8, $instructionLength)); $count = $endPtsOfContours[$noc - 1] + 1; // Flags $flags = array(); for ($index = 0; $index < $count; $index++) { $flags[$index] = $font->readUInt8(); if ($flags[$index] & self::REPEAT) { $repeats = $font->readUInt8(); for ($i = 1; $i <= $repeats; $i++) { $flags[$index + $i] = $flags[$index]; } $index += $repeats; } } $points = array(); foreach ($flags as $i => $flag) { $points[$i]["onCurve"] = $flag & self::ON_CURVE; $points[$i]["endOfContour"] = in_array($i, $endPtsOfContours); } // X Coords $x = 0; for ($i = 0; $i < $count; $i++) { $flag = $flags[$i]; if ($flag & self::THIS_X_IS_SAME) { if ($flag & self::X_SHORT_VECTOR) { $x += $font->readUInt8(); } } else { if ($flag & self::X_SHORT_VECTOR) { $x -= $font->readUInt8(); } else { $x += $font->readInt16(); } } $points[$i]["x"] = $x; } // Y Coords $y = 0; for ($i = 0; $i < $count; $i++) { $flag = $flags[$i]; if ($flag & self::THIS_Y_IS_SAME) { if ($flag & self::Y_SHORT_VECTOR) { $y += $font->readUInt8(); } } else { if ($flag & self::Y_SHORT_VECTOR) { $y -= $font->readUInt8(); } else { $y += $font->readInt16(); } } $points[$i]["y"] = $y; } $this->points = $points; } public function splitSVGPath($path) { preg_match_all('/([a-z])|(-?\d+(?:\.\d+)?)/i', $path, $matches, PREG_PATTERN_ORDER); return $matches[0]; } public function makePoints($path) { $path = $this->splitSVGPath($path); $l = count($path); $i = 0; $points = array(); while ($i < $l) { switch ($path[$i]) { // moveTo case "M": $points[] = array( "onCurve" => true, "x" => $path[++$i], "y" => $path[++$i], "endOfContour" => false, ); break; // lineTo case "L": $points[] = array( "onCurve" => true, "x" => $path[++$i], "y" => $path[++$i], "endOfContour" => false, ); break; // quadraticCurveTo case "Q": $points[] = array( "onCurve" => false, "x" => $path[++$i], "y" => $path[++$i], "endOfContour" => false, ); $points[] = array( "onCurve" => true, "x" => $path[++$i], "y" => $path[++$i], "endOfContour" => false, ); break; // closePath /** @noinspection PhpMissingBreakStatementInspection */ case "z": $points[count($points) - 1]["endOfContour"] = true; default: $i++; break; } } return $points; } function encode() { if (empty($this->points)) { return parent::encode(); } return $this->size = $this->encodePoints($this->points); } public function encodePoints($points) { $endPtsOfContours = array(); $flags = array(); $coords_x = array(); $coords_y = array(); $last_x = 0; $last_y = 0; $xMin = $yMin = 0xFFFF; $xMax = $yMax = -0xFFFF; foreach ($points as $i => $point) { $flag = 0; if ($point["onCurve"]) { $flag |= self::ON_CURVE; } if ($point["endOfContour"]) { $endPtsOfContours[] = $i; } // Simplified, we could do some optimizations if ($point["x"] == $last_x) { $flag |= self::THIS_X_IS_SAME; } else { $x = intval($point["x"]); $xMin = min($x, $xMin); $xMax = max($x, $xMax); $coords_x[] = $x - $last_x; // int16 } // Simplified, we could do some optimizations if ($point["y"] == $last_y) { $flag |= self::THIS_Y_IS_SAME; } else { $y = intval($point["y"]); $yMin = min($y, $yMin); $yMax = max($y, $yMax); $coords_y[] = $y - $last_y; // int16 } $flags[] = $flag; $last_x = $point["x"]; $last_y = $point["y"]; } $font = $this->getFont(); $l = 0; $l += $font->writeInt16(count($endPtsOfContours)); // endPtsOfContours $l += $font->writeFWord(isset($this->xMin) ? $this->xMin : $xMin); // xMin $l += $font->writeFWord(isset($this->yMin) ? $this->yMin : $yMin); // yMin $l += $font->writeFWord(isset($this->xMax) ? $this->xMax : $xMax); // xMax $l += $font->writeFWord(isset($this->yMax) ? $this->yMax : $yMax); // yMax // Simple glyf $l += $font->w(array(self::uint16, count($endPtsOfContours)), $endPtsOfContours); // endPtsOfContours $l += $font->writeUInt16(0); // instructionLength $l += $font->w(array(self::uint8, count($flags)), $flags); // flags $l += $font->w(array(self::int16, count($coords_x)), $coords_x); // xCoordinates $l += $font->w(array(self::int16, count($coords_y)), $coords_y); // yCoordinates return $l; } public function getSVGContours($points = null) { $path = ""; if (!$points) { if (empty($this->points)) { $this->parseData(); } $points = $this->points; } $length = (empty($points) ? 0 : count($points)); $firstIndex = 0; $count = 0; for ($i = 0; $i < $length; $i++) { $count++; if ($points[$i]["endOfContour"]) { $path .= $this->getSVGPath($points, $firstIndex, $count); $firstIndex = $i + 1; $count = 0; } } return $path; } protected function getSVGPath($points, $startIndex, $count) { $offset = 0; $path = ""; while ($offset < $count) { $point = $points[$startIndex + $offset % $count]; $point_p1 = $points[$startIndex + ($offset + 1) % $count]; if ($offset == 0) { $path .= "M{$point['x']},{$point['y']} "; } if ($point["onCurve"]) { if ($point_p1["onCurve"]) { $path .= "L{$point_p1['x']},{$point_p1['y']} "; $offset++; } else { $point_p2 = $points[$startIndex + ($offset + 2) % $count]; if ($point_p2["onCurve"]) { $path .= "Q{$point_p1['x']},{$point_p1['y']},{$point_p2['x']},{$point_p2['y']} "; } else { $path .= "Q{$point_p1['x']},{$point_p1['y']}," . $this->midValue($point_p1['x'], $point_p2['x']) . "," . $this->midValue($point_p1['y'], $point_p2['y']) . " "; } $offset += 2; } } else { if ($point_p1["onCurve"]) { $path .= "Q{$point['x']},{$point['y']},{$point_p1['x']},{$point_p1['y']} "; } else { $path .= "Q{$point['x']},{$point['y']}," . $this->midValue($point['x'], $point_p1['x']) . "," . $this->midValue($point['y'], $point_p1['y']) . " "; } $offset++; } } $path .= "z "; return $path; } function midValue($a, $b) { return $a + ($b - $a) / 2; } } PK!AQ=convertformstools/pdf/dompdf/lib/php-svg-lib/src/autoload.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ spl_autoload_register(function($class) { if (0 === strpos($class, "Svg")) { $file = str_replace('\\', DIRECTORY_SEPARATOR, $class); $file = realpath(__DIR__ . DIRECTORY_SEPARATOR . $file . '.php'); if (file_exists($file)) { include_once $file; } } });PK!7Econvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/DefaultStyle.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg; class DefaultStyle extends Style { public $color = ''; public $opacity = 1.0; public $display = 'inline'; public $fill = 'black'; public $fillOpacity = 1.0; public $fillRule = 'nonzero'; public $stroke = 'none'; public $strokeOpacity = 1.0; public $strokeLinecap = 'butt'; public $strokeLinejoin = 'miter'; public $strokeMiterlimit = 4; public $strokeWidth = 1.0; public $strokeDasharray = 0; public $strokeDashoffset = 0; } PK!ʘiGRGREconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Surface/CPdf.phpnu[ * @author Orion Richardson * @author Helmut Tischer * @author Ryan H. Masten * @author Brian Sweeney * @author Fabien Ménager * @license Public Domain http://creativecommons.org/licenses/publicdomain/ * @package Cpdf */ namespace Svg\Surface; class CPdf { const PDF_VERSION = '1.7'; const ACROFORM_SIG_SIGNATURESEXISTS = 0x0001; const ACROFORM_SIG_APPENDONLY = 0x0002; const ACROFORM_FIELD_BUTTON = 'Btn'; const ACROFORM_FIELD_TEXT = 'Tx'; const ACROFORM_FIELD_CHOICE = 'Ch'; const ACROFORM_FIELD_SIG = 'Sig'; const ACROFORM_FIELD_READONLY = 0x0001; const ACROFORM_FIELD_REQUIRED = 0x0002; const ACROFORM_FIELD_TEXT_MULTILINE = 0x1000; const ACROFORM_FIELD_TEXT_PASSWORD = 0x2000; const ACROFORM_FIELD_TEXT_RICHTEXT = 0x10000; const ACROFORM_FIELD_CHOICE_COMBO = 0x20000; const ACROFORM_FIELD_CHOICE_EDIT = 0x40000; const ACROFORM_FIELD_CHOICE_SORT = 0x80000; const ACROFORM_FIELD_CHOICE_MULTISELECT = 0x200000; const XOBJECT_SUBTYPE_FORM = 'Form'; /** * @var integer The current number of pdf objects in the document */ public $numObj = 0; /** * @var array This array contains all of the pdf objects, ready for final assembly */ public $objects = []; /** * @var integer The objectId (number within the objects array) of the document catalog */ public $catalogId; /** * @var integer The objectId (number within the objects array) of indirect references (Javascript EmbeddedFiles) */ protected $indirectReferenceId = 0; /** * @var integer The objectId (number within the objects array) */ protected $embeddedFilesId = 0; /** * AcroForm objectId * * @var integer */ public $acroFormId; /** * @var int */ public $signatureMaxLen = 5000; /** * @var array Array carrying information about the fonts that the system currently knows about * Used to ensure that a font is not loaded twice, among other things */ public $fonts = []; /** * @var string The default font metrics file to use if no other font has been loaded. * The path to the directory containing the font metrics should be included */ public $defaultFont = './fonts/Helvetica.afm'; /** * @string A record of the current font */ public $currentFont = ''; /** * @var string The current base font */ public $currentBaseFont = ''; /** * @var integer The number of the current font within the font array */ public $currentFontNum = 0; /** * @var integer */ public $currentNode; /** * @var integer Object number of the current page */ public $currentPage; /** * @var integer Object number of the currently active contents block */ public $currentContents; /** * @var integer Number of fonts within the system */ public $numFonts = 0; /** * @var integer Number of graphic state resources used */ private $numStates = 0; /** * @var array Number of graphic state resources used */ private $gstates = []; /** * @var array Current color for fill operations, defaults to inactive value, * all three components should be between 0 and 1 inclusive when active */ public $currentColor = null; /** * @var array Current color for stroke operations (lines etc.) */ public $currentStrokeColor = null; /** * @var string Fill rule (nonzero or evenodd) */ public $fillRule = "nonzero"; /** * @var string Current style that lines are drawn in */ public $currentLineStyle = ''; /** * @var array Current line transparency (partial graphics state) */ public $currentLineTransparency = ["mode" => "Normal", "opacity" => 1.0]; /** * array Current fill transparency (partial graphics state) */ public $currentFillTransparency = ["mode" => "Normal", "opacity" => 1.0]; /** * @var array An array which is used to save the state of the document, mainly the colors and styles * it is used to temporarily change to another state, then change back to what it was before */ public $stateStack = []; /** * @var integer Number of elements within the state stack */ public $nStateStack = 0; /** * @var integer Number of page objects within the document */ public $numPages = 0; /** * @var array Object Id storage stack */ public $stack = []; /** * @var integer Number of elements within the object Id storage stack */ public $nStack = 0; /** * an array which contains information about the objects which are not firmly attached to pages * these have been added with the addObject function */ public $looseObjects = []; /** * array contains information about how the loose objects are to be added to the document */ public $addLooseObjects = []; /** * @var integer The objectId of the information object for the document * this contains authorship, title etc. */ public $infoObject = 0; /** * @var integer Number of images being tracked within the document */ public $numImages = 0; /** * @var array An array containing options about the document * it defaults to turning on the compression of the objects */ public $options = ['compression' => true]; /** * @var integer The objectId of the first page of the document */ public $firstPageId; /** * @var integer The object Id of the procset object */ public $procsetObjectId; /** * @var array Store the information about the relationship between font families * this used so that the code knows which font is the bold version of another font, etc. * the value of this array is initialised in the constructor function. */ public $fontFamilies = []; /** * @var string Folder for php serialized formats of font metrics files. * If empty string, use same folder as original metrics files. * This can be passed in from class creator. * If this folder does not exist or is not writable, Cpdf will be **much** slower. * Because of potential trouble with php safe mode, folder cannot be created at runtime. */ public $fontcache = ''; /** * @var integer The version of the font metrics cache file. * This value must be manually incremented whenever the internal font data structure is modified. */ public $fontcacheVersion = 6; /** * @var string Temporary folder. * If empty string, will attempt system tmp folder. * This can be passed in from class creator. */ public $tmp = ''; /** * @var string Track if the current font is bolded or italicised */ public $currentTextState = ''; /** * @var string Messages are stored here during processing, these can be selected afterwards to give some useful debug information */ public $messages = ''; /** * @var string The encryption array for the document encryption is stored here */ public $arc4 = ''; /** * @var integer The object Id of the encryption information */ public $arc4_objnum = 0; /** * @var string The file identifier, used to uniquely identify a pdf document */ public $fileIdentifier = ''; /** * @var boolean A flag to say if a document is to be encrypted or not */ public $encrypted = false; /** * @var string The encryption key for the encryption of all the document content (structure is not encrypted) */ public $encryptionKey = ''; /** * @var array Array which forms a stack to keep track of nested callback functions */ public $callback = []; /** * @var integer The number of callback functions in the callback array */ public $nCallback = 0; /** * @var array Store label->id pairs for named destinations, these will be used to replace internal links * done this way so that destinations can be defined after the location that links to them */ public $destinations = []; /** * @var array Store the stack for the transaction commands, each item in here is a record of the values of all the * publiciables within the class, so that the user can rollback at will (from each 'start' command) * note that this includes the objects array, so these can be large. */ public $checkpoint = ''; /** * @var array Table of Image origin filenames and image labels which were already added with o_image(). * Allows to merge identical images */ public $imagelist = []; /** * @var array Table of already added alpha and plain image files for transparent PNG images. */ protected $imageAlphaList = []; /** * @var array List of temporary image files to be deleted after processing. */ protected $imageCache = []; /** * @var boolean Whether the text passed in should be treated as Unicode or just local character set. */ public $isUnicode = false; /** * @var string the JavaScript code of the document */ public $javascript = ''; /** * @var boolean whether the compression is possible */ protected $compressionReady = false; /** * @var array Current page size */ protected $currentPageSize = ["width" => 0, "height" => 0]; /** * @var array All the chars that will be required in the font subsets */ protected $stringSubsets = []; /** * @var string The target internal encoding */ protected static $targetEncoding = 'Windows-1252'; /** * @var array */ protected $byteRange = array(); /** * @var array The list of the core fonts */ protected static $coreFonts = [ 'courier', 'courier-bold', 'courier-oblique', 'courier-boldoblique', 'helvetica', 'helvetica-bold', 'helvetica-oblique', 'helvetica-boldoblique', 'times-roman', 'times-bold', 'times-italic', 'times-bolditalic', 'symbol', 'zapfdingbats' ]; /** * Class constructor * This will start a new document * * @param array $pageSize Array of 4 numbers, defining the bottom left and upper right corner of the page. first two are normally zero. * @param boolean $isUnicode Whether text will be treated as Unicode or not. * @param string $fontcache The font cache folder * @param string $tmp The temporary folder */ function __construct($pageSize = [0, 0, 612, 792], $isUnicode = false, $fontcache = '', $tmp = '') { $this->isUnicode = $isUnicode; $this->fontcache = rtrim($fontcache, DIRECTORY_SEPARATOR."/\\"); $this->tmp = ($tmp !== '' ? $tmp : sys_get_temp_dir()); $this->newDocument($pageSize); $this->compressionReady = function_exists('gzcompress'); if (in_array('Windows-1252', mb_list_encodings())) { self::$targetEncoding = 'Windows-1252'; } // also initialize the font families that are known about already $this->setFontFamily('init'); } public function __destruct() { foreach ($this->imageCache as $file) { if (file_exists($file)) { unlink($file); } } } /** * Document object methods (internal use only) * * There is about one object method for each type of object in the pdf document * Each function has the same call list ($id,$action,$options). * $id = the object ID of the object, or what it is to be if it is being created * $action = a string specifying the action to be performed, though ALL must support: * 'new' - create the object with the id $id * 'out' - produce the output for the pdf object * $options = optional, a string or array containing the various parameters for the object * * These, in conjunction with the output function are the ONLY way for output to be produced * within the pdf 'file'. */ /** * Destination object, used to specify the location for the user to jump to, presently on opening * * @param $id * @param $action * @param string $options * @return string|null */ protected function o_destination($id, $action, $options = '') { switch ($action) { case 'new': $this->objects[$id] = ['t' => 'destination', 'info' => []]; $tmp = ''; switch ($options['type']) { case 'XYZ': /** @noinspection PhpMissingBreakStatementInspection */ case 'FitR': $tmp = ' ' . $options['p3'] . $tmp; case 'FitH': case 'FitV': case 'FitBH': /** @noinspection PhpMissingBreakStatementInspection */ case 'FitBV': $tmp = ' ' . $options['p1'] . ' ' . $options['p2'] . $tmp; case 'Fit': case 'FitB': $tmp = $options['type'] . $tmp; $this->objects[$id]['info']['string'] = $tmp; $this->objects[$id]['info']['page'] = $options['page']; } break; case 'out': $o = &$this->objects[$id]; $tmp = $o['info']; $res = "\n$id 0 obj\n" . '[' . $tmp['page'] . ' 0 R /' . $tmp['string'] . "]\nendobj"; return $res; } return null; } /** * set the viewer preferences * * @param $id * @param $action * @param string|array $options * @return string|null */ protected function o_viewerPreferences($id, $action, $options = '') { switch ($action) { case 'new': $this->objects[$id] = ['t' => 'viewerPreferences', 'info' => []]; break; case 'add': $o = &$this->objects[$id]; foreach ($options as $k => $v) { switch ($k) { // Boolean keys case 'HideToolbar': case 'HideMenubar': case 'HideWindowUI': case 'FitWindow': case 'CenterWindow': case 'DisplayDocTitle': case 'PickTrayByPDFSize': $o['info'][$k] = (bool)$v; break; // Integer keys case 'NumCopies': $o['info'][$k] = (int)$v; break; // Name keys case 'ViewArea': case 'ViewClip': case 'PrintClip': case 'PrintArea': $o['info'][$k] = (string)$v; break; // Named with limited valid values case 'NonFullScreenPageMode': if (!in_array($v, ['UseNone', 'UseOutlines', 'UseThumbs', 'UseOC'])) { break; } $o['info'][$k] = $v; break; case 'Direction': if (!in_array($v, ['L2R', 'R2L'])) { break; } $o['info'][$k] = $v; break; case 'PrintScaling': if (!in_array($v, ['None', 'AppDefault'])) { break; } $o['info'][$k] = $v; break; case 'Duplex': if (!in_array($v, ['None', 'Simplex', 'DuplexFlipShortEdge', 'DuplexFlipLongEdge'])) { break; } $o['info'][$k] = $v; break; // Integer array case 'PrintPageRange': // Cast to integer array foreach ($v as $vK => $vV) { $v[$vK] = (int)$vV; } $o['info'][$k] = array_values($v); break; } } break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< "; foreach ($o['info'] as $k => $v) { if (is_string($v)) { $v = '/' . $v; } elseif (is_int($v)) { $v = (string) $v; } elseif (is_bool($v)) { $v = ($v ? 'true' : 'false'); } elseif (is_array($v)) { $v = '[' . implode(' ', $v) . ']'; } $res .= "\n/$k $v"; } $res .= "\n>>\nendobj"; return $res; } return null; } /** * define the document catalog, the overall controller for the document * * @param $id * @param $action * @param string|array $options * @return string|null */ protected function o_catalog($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'catalog', 'info' => []]; $this->catalogId = $id; break; case 'acroform': case 'outlines': case 'pages': case 'openHere': case 'names': $o['info'][$action] = $options; break; case 'viewerPreferences': if (!isset($o['info']['viewerPreferences'])) { $this->numObj++; $this->o_viewerPreferences($this->numObj, 'new'); $o['info']['viewerPreferences'] = $this->numObj; } $vp = $o['info']['viewerPreferences']; $this->o_viewerPreferences($vp, 'add', $options); break; case 'out': $res = "\n$id 0 obj\n<< /Type /Catalog"; foreach ($o['info'] as $k => $v) { switch ($k) { case 'outlines': $res .= "\n/Outlines $v 0 R"; break; case 'pages': $res .= "\n/Pages $v 0 R"; break; case 'viewerPreferences': $res .= "\n/ViewerPreferences $v 0 R"; break; case 'openHere': $res .= "\n/OpenAction $v 0 R"; break; case 'names': $res .= "\n/Names $v 0 R"; break; case 'acroform': $res .= "\n/AcroForm $v 0 R"; break; } } $res .= " >>\nendobj"; return $res; } return null; } /** * object which is a parent to the pages in the document * * @param $id * @param $action * @param string $options * @return string|null */ protected function o_pages($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'pages', 'info' => []]; $this->o_catalog($this->catalogId, 'pages', $id); break; case 'page': if (!is_array($options)) { // then it will just be the id of the new page $o['info']['pages'][] = $options; } else { // then it should be an array having 'id','rid','pos', where rid=the page to which this one will be placed relative // and pos is either 'before' or 'after', saying where this page will fit. if (isset($options['id']) && isset($options['rid']) && isset($options['pos'])) { $i = array_search($options['rid'], $o['info']['pages']); if (isset($o['info']['pages'][$i]) && $o['info']['pages'][$i] == $options['rid']) { // then there is a match // make a space switch ($options['pos']) { case 'before': $k = $i; break; case 'after': $k = $i + 1; break; default: $k = -1; break; } if ($k >= 0) { for ($j = count($o['info']['pages']) - 1; $j >= $k; $j--) { $o['info']['pages'][$j + 1] = $o['info']['pages'][$j]; } $o['info']['pages'][$k] = $options['id']; } } } } break; case 'procset': $o['info']['procset'] = $options; break; case 'mediaBox': $o['info']['mediaBox'] = $options; // which should be an array of 4 numbers $this->currentPageSize = ['width' => $options[2], 'height' => $options[3]]; break; case 'font': $o['info']['fonts'][] = ['objNum' => $options['objNum'], 'fontNum' => $options['fontNum']]; break; case 'extGState': $o['info']['extGStates'][] = ['objNum' => $options['objNum'], 'stateNum' => $options['stateNum']]; break; case 'xObject': $o['info']['xObjects'][] = ['objNum' => $options['objNum'], 'label' => $options['label']]; break; case 'out': if (count($o['info']['pages'])) { $res = "\n$id 0 obj\n<< /Type /Pages\n/Kids ["; foreach ($o['info']['pages'] as $v) { $res .= "$v 0 R\n"; } $res .= "]\n/Count " . count($this->objects[$id]['info']['pages']); if ((isset($o['info']['fonts']) && count($o['info']['fonts'])) || isset($o['info']['procset']) || (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) ) { $res .= "\n/Resources <<"; if (isset($o['info']['procset'])) { $res .= "\n/ProcSet " . $o['info']['procset'] . " 0 R"; } if (isset($o['info']['fonts']) && count($o['info']['fonts'])) { $res .= "\n/Font << "; foreach ($o['info']['fonts'] as $finfo) { $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; } $res .= "\n>>"; } if (isset($o['info']['xObjects']) && count($o['info']['xObjects'])) { $res .= "\n/XObject << "; foreach ($o['info']['xObjects'] as $finfo) { $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; } $res .= "\n>>"; } if (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) { $res .= "\n/ExtGState << "; foreach ($o['info']['extGStates'] as $gstate) { $res .= "\n/GS" . $gstate['stateNum'] . " " . $gstate['objNum'] . " 0 R"; } $res .= "\n>>"; } $res .= "\n>>"; if (isset($o['info']['mediaBox'])) { $tmp = $o['info']['mediaBox']; $res .= "\n/MediaBox [" . sprintf( '%.3F %.3F %.3F %.3F', $tmp[0], $tmp[1], $tmp[2], $tmp[3] ) . ']'; } } $res .= "\n >>\nendobj"; } else { $res = "\n$id 0 obj\n<< /Type /Pages\n/Count 0\n>>\nendobj"; } return $res; } return null; } /** * define the outlines in the doc, empty for now * * @param $id * @param $action * @param string $options * @return string|null */ protected function o_outlines($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'outlines', 'info' => ['outlines' => []]]; $this->o_catalog($this->catalogId, 'outlines', $id); break; case 'outline': $o['info']['outlines'][] = $options; break; case 'out': if (count($o['info']['outlines'])) { $res = "\n$id 0 obj\n<< /Type /Outlines /Kids ["; foreach ($o['info']['outlines'] as $v) { $res .= "$v 0 R "; } $res .= "] /Count " . count($o['info']['outlines']) . " >>\nendobj"; } else { $res = "\n$id 0 obj\n<< /Type /Outlines /Count 0 >>\nendobj"; } return $res; } return null; } /** * an object to hold the font description * * @param $id * @param $action * @param string|array $options * @return string|null * @throws FontNotFoundException */ protected function o_font($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'font', 'info' => [ 'name' => $options['name'], 'fontFileName' => $options['fontFileName'], 'SubType' => 'Type1', 'isSubsetting' => $options['isSubsetting'] ] ]; $fontNum = $this->numFonts; $this->objects[$id]['info']['fontNum'] = $fontNum; // deal with the encoding and the differences if (isset($options['differences'])) { // then we'll need an encoding dictionary $this->numObj++; $this->o_fontEncoding($this->numObj, 'new', $options); $this->objects[$id]['info']['encodingDictionary'] = $this->numObj; } else { if (isset($options['encoding'])) { // we can specify encoding here switch ($options['encoding']) { case 'WinAnsiEncoding': case 'MacRomanEncoding': case 'MacExpertEncoding': $this->objects[$id]['info']['encoding'] = $options['encoding']; break; case 'none': break; default: $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; break; } } else { $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; } } if ($this->fonts[$options['fontFileName']]['isUnicode']) { // For Unicode fonts, we need to incorporate font data into // sub-sections that are linked from the primary font section. // Look at o_fontGIDtoCID and o_fontDescendentCID functions // for more information. // // All of this code is adapted from the excellent changes made to // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) $toUnicodeId = ++$this->numObj; $this->o_toUnicode($toUnicodeId, 'new'); $this->objects[$id]['info']['toUnicode'] = $toUnicodeId; $cidFontId = ++$this->numObj; $this->o_fontDescendentCID($cidFontId, 'new', $options); $this->objects[$id]['info']['cidFont'] = $cidFontId; } // also tell the pages node about the new font $this->o_pages($this->currentNode, 'font', ['fontNum' => $fontNum, 'objNum' => $id]); break; case 'add': $font_options = $this->processFont($id, $o['info']); if ($font_options !== false) { foreach ($font_options as $k => $v) { switch ($k) { case 'BaseFont': $o['info']['name'] = $v; break; case 'FirstChar': case 'LastChar': case 'Widths': case 'FontDescriptor': case 'SubType': $this->addMessage('o_font ' . $k . " : " . $v); $o['info'][$k] = $v; break; } } // pass values down to descendent font if (isset($o['info']['cidFont'])) { $this->o_fontDescendentCID($o['info']['cidFont'], 'add', $font_options); } } break; case 'out': if ($this->fonts[$this->objects[$id]['info']['fontFileName']]['isUnicode']) { // For Unicode fonts, we need to incorporate font data into // sub-sections that are linked from the primary font section. // Look at o_fontGIDtoCID and o_fontDescendentCID functions // for more information. // // All of this code is adapted from the excellent changes made to // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) $res = "\n$id 0 obj\n<fonts[$fontFileName])) { return false; } $font = &$this->fonts[$fontFileName]; $fileSuffix = $font['fileSuffix']; $fileSuffixLower = strtolower($font['fileSuffix']); $fbfile = "$fontFileName.$fileSuffix"; $isTtfFont = $fileSuffixLower === 'ttf'; $isPfbFont = $fileSuffixLower === 'pfb'; $this->addMessage('selectFont: checking for - ' . $fbfile); if (!$fileSuffix) { $this->addMessage( 'selectFont: pfb or ttf file not found, ok if this is one of the 14 standard fonts' ); return false; } else { $adobeFontName = isset($font['PostScriptName']) ? $font['PostScriptName'] : $font['FontName']; // $fontObj = $this->numObj; $this->addMessage("selectFont: adding font file - $fbfile - $adobeFontName"); // find the array of font widths, and put that into an object. $firstChar = -1; $lastChar = 0; $widths = []; $cid_widths = []; foreach ($font['C'] as $num => $d) { if (intval($num) > 0 || $num == '0') { if (!$font['isUnicode']) { // With Unicode, widths array isn't used if ($lastChar > 0 && $num > $lastChar + 1) { for ($i = $lastChar + 1; $i < $num; $i++) { $widths[] = 0; } } } $widths[] = $d; if ($font['isUnicode']) { $cid_widths[$num] = $d; } if ($firstChar == -1) { $firstChar = $num; } $lastChar = $num; } } // also need to adjust the widths for the differences array if (isset($object['differences'])) { foreach ($object['differences'] as $charNum => $charName) { if ($charNum > $lastChar) { if (!$object['isUnicode']) { // With Unicode, widths array isn't used for ($i = $lastChar + 1; $i <= $charNum; $i++) { $widths[] = 0; } } $lastChar = $charNum; } if (isset($font['C'][$charName])) { $widths[$charNum - $firstChar] = $font['C'][$charName]; if ($font['isUnicode']) { $cid_widths[$charName] = $font['C'][$charName]; } } } } if ($font['isUnicode']) { $font['CIDWidths'] = $cid_widths; } $this->addMessage('selectFont: FirstChar = ' . $firstChar); $this->addMessage('selectFont: LastChar = ' . $lastChar); $widthid = -1; if (!$font['isUnicode']) { // With Unicode, widths array isn't used $this->numObj++; $this->o_contents($this->numObj, 'new', 'raw'); $this->objects[$this->numObj]['c'] .= '[' . implode(' ', $widths) . ']'; $widthid = $this->numObj; } $missing_width = 500; $stemV = 70; if (isset($font['MissingWidth'])) { $missing_width = $font['MissingWidth']; } if (isset($font['StdVW'])) { $stemV = $font['StdVW']; } else { if (isset($font['Weight']) && preg_match('!(bold|black)!i', $font['Weight'])) { $stemV = 120; } } // load the pfb file, and put that into an object too. // note that pdf supports only binary format type 1 font files, though there is a // simple utility to convert them from pfa to pfb. $data = file_get_contents($fbfile); // create the font descriptor $this->numObj++; $fontDescriptorId = $this->numObj; $this->numObj++; $pfbid = $this->numObj; // determine flags (more than a little flakey, hopefully will not matter much) $flags = 0; if ($font['ItalicAngle'] != 0) { $flags += pow(2, 6); } if ($font['IsFixedPitch'] === 'true') { $flags += 1; } $flags += pow(2, 5); // assume non-sybolic $list = [ 'Ascent' => 'Ascender', 'CapHeight' => 'Ascender', //FIXME: php-font-lib is not grabbing this value, so we'll fake it and use the Ascender value // 'CapHeight' 'MissingWidth' => 'MissingWidth', 'Descent' => 'Descender', 'FontBBox' => 'FontBBox', 'ItalicAngle' => 'ItalicAngle' ]; $fdopt = [ 'Flags' => $flags, 'FontName' => $adobeFontName, 'StemV' => $stemV ]; foreach ($list as $k => $v) { if (isset($font[$v])) { $fdopt[$k] = $font[$v]; } } if ($isPfbFont) { $fdopt['FontFile'] = $pfbid; } elseif ($isTtfFont) { $fdopt['FontFile2'] = $pfbid; } $this->o_fontDescriptor($fontDescriptorId, 'new', $fdopt); // embed the font program $this->o_contents($this->numObj, 'new'); $this->objects[$pfbid]['c'] .= $data; // determine the cruicial lengths within this file if ($isPfbFont) { $l1 = strpos($data, 'eexec') + 6; $l2 = strpos($data, '00000000') - $l1; $l3 = mb_strlen($data, '8bit') - $l2 - $l1; $this->o_contents( $this->numObj, 'add', ['Length1' => $l1, 'Length2' => $l2, 'Length3' => $l3] ); } elseif ($isTtfFont) { $l1 = mb_strlen($data, '8bit'); $this->o_contents($this->numObj, 'add', ['Length1' => $l1]); } // tell the font object about all this new stuff $options = [ 'BaseFont' => $adobeFontName, 'MissingWidth' => $missing_width, 'Widths' => $widthid, 'FirstChar' => $firstChar, 'LastChar' => $lastChar, 'FontDescriptor' => $fontDescriptorId ]; if ($isTtfFont) { $options['SubType'] = 'TrueType'; } $this->addMessage("adding extra info to font.($fontObjId)"); foreach ($options as $fk => $fv) { $this->addMessage("$fk : $fv"); } } return $options; } /** * A toUnicode section, needed for unicode fonts * * @param $id * @param $action * @return null|string */ protected function o_toUnicode($id, $action) { switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'toUnicode' ]; break; case 'add': break; case 'out': $ordering = 'UCS'; $registry = 'Adobe'; if ($this->encrypted) { $this->encryptInit($id); $ordering = $this->ARC4($ordering); $registry = $this->filterText($this->ARC4($registry), false, false); } $stream = <<> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 1 beginbfrange <0000> <0000> endbfrange endcmap CMapName currentdict /CMap defineresource pop end end EOT; $res = "\n$id 0 obj\n"; $res .= "<>\n"; $res .= "stream\n" . $stream . "\nendstream" . "\nendobj";; return $res; } return null; } /** * a font descriptor, needed for including additional fonts * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_fontDescriptor($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'fontDescriptor', 'info' => $options]; break; case 'out': $res = "\n$id 0 obj\n<< /Type /FontDescriptor\n"; foreach ($o['info'] as $label => $value) { switch ($label) { case 'Ascent': case 'CapHeight': case 'Descent': case 'Flags': case 'ItalicAngle': case 'StemV': case 'AvgWidth': case 'Leading': case 'MaxWidth': case 'MissingWidth': case 'StemH': case 'XHeight': case 'CharSet': if (mb_strlen($value, '8bit')) { $res .= "/$label $value\n"; } break; case 'FontFile': case 'FontFile2': case 'FontFile3': $res .= "/$label $value 0 R\n"; break; case 'FontBBox': $res .= "/$label [$value[0] $value[1] $value[2] $value[3]]\n"; break; case 'FontName': $res .= "/$label /$value\n"; break; } } $res .= ">>\nendobj"; return $res; } return null; } /** * the font encoding * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_fontEncoding($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': // the options array should contain 'differences' and maybe 'encoding' $this->objects[$id] = ['t' => 'fontEncoding', 'info' => $options]; break; case 'out': $res = "\n$id 0 obj\n<< /Type /Encoding\n"; if (!isset($o['info']['encoding'])) { $o['info']['encoding'] = 'WinAnsiEncoding'; } if ($o['info']['encoding'] !== 'none') { $res .= "/BaseEncoding /" . $o['info']['encoding'] . "\n"; } $res .= "/Differences \n["; $onum = -100; foreach ($o['info']['differences'] as $num => $label) { if ($num != $onum + 1) { // we cannot make use of consecutive numbering $res .= "\n$num /$label"; } else { $res .= " /$label"; } $onum = $num; } $res .= "\n]\n>>\nendobj"; return $res; } return null; } /** * a descendent cid font, needed for unicode fonts * * @param $id * @param $action * @param string|array $options * @return null|string */ protected function o_fontDescendentCID($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'fontDescendentCID', 'info' => $options]; // we need a CID system info section $cidSystemInfoId = ++$this->numObj; $this->o_cidSystemInfo($cidSystemInfoId, 'new'); $this->objects[$id]['info']['cidSystemInfo'] = $cidSystemInfoId; // and a CID to GID map $cidToGidMapId = ++$this->numObj; $this->o_fontGIDtoCIDMap($cidToGidMapId, 'new', $options); $this->objects[$id]['info']['cidToGidMap'] = $cidToGidMapId; break; case 'add': foreach ($options as $k => $v) { switch ($k) { case 'BaseFont': $o['info']['name'] = $v; break; case 'FirstChar': case 'LastChar': case 'MissingWidth': case 'FontDescriptor': case 'SubType': $this->addMessage("o_fontDescendentCID $k : $v"); $o['info'][$k] = $v; break; } } // pass values down to cid to gid map $this->o_fontGIDtoCIDMap($o['info']['cidToGidMap'], 'add', $options); break; case 'out': $res = "\n$id 0 obj\n"; $res .= "<fonts[$o['info']['fontFileName']]['CIDWidths'])) { $cid_widths = &$this->fonts[$o['info']['fontFileName']]['CIDWidths']; $w = ''; foreach ($cid_widths as $cid => $width) { $w .= "$cid [$width] "; } $res .= "/W [$w]\n"; } $res .= "/CIDToGIDMap " . $o['info']['cidToGidMap'] . " 0 R\n"; $res .= ">>\n"; $res .= "endobj"; return $res; } return null; } /** * CID system info section, needed for unicode fonts * * @param $id * @param $action * @return null|string */ protected function o_cidSystemInfo($id, $action) { switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'cidSystemInfo' ]; break; case 'add': break; case 'out': $ordering = 'UCS'; $registry = 'Adobe'; if ($this->encrypted) { $this->encryptInit($id); $ordering = $this->ARC4($ordering); $registry = $this->ARC4($registry); } $res = "\n$id 0 obj\n"; $res .= '<objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'fontGIDtoCIDMap', 'info' => $options]; break; case 'out': $res = "\n$id 0 obj\n"; $fontFileName = $o['info']['fontFileName']; $tmp = $this->fonts[$fontFileName]['CIDtoGID'] = base64_decode($this->fonts[$fontFileName]['CIDtoGID']); $compressed = isset($this->fonts[$fontFileName]['CIDtoGID_Compressed']) && $this->fonts[$fontFileName]['CIDtoGID_Compressed']; if (!$compressed && isset($o['raw'])) { $res .= $tmp; } else { $res .= "<<"; if (!$compressed && $this->compressionReady && $this->options['compression']) { // then implement ZLIB based compression on this content stream $compressed = true; $tmp = gzcompress($tmp, 6); } if ($compressed) { $res .= "\n/Filter /FlateDecode"; } if ($this->encrypted) { $this->encryptInit($id); $tmp = $this->ARC4($tmp); } $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream"; } $res .= "\nendobj"; return $res; } return null; } /** * the document procset, solves some problems with printing to old PS printers * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_procset($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'procset', 'info' => ['PDF' => 1, 'Text' => 1]]; $this->o_pages($this->currentNode, 'procset', $id); $this->procsetObjectId = $id; break; case 'add': // this is to add new items to the procset list, despite the fact that this is considered // obsolete, the items are required for printing to some postscript printers switch ($options) { case 'ImageB': case 'ImageC': case 'ImageI': $o['info'][$options] = 1; break; } break; case 'out': $res = "\n$id 0 obj\n["; foreach ($o['info'] as $label => $val) { $res .= "/$label "; } $res .= "]\nendobj"; return $res; } return null; } /** * define the document information * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_info($id, $action, $options = '') { switch ($action) { case 'new': $this->infoObject = $id; $date = 'D:' . @date('Ymd'); $this->objects[$id] = [ 't' => 'info', 'info' => [ 'Producer' => 'CPDF (dompdf)', 'CreationDate' => $date ] ]; break; case 'Title': case 'Author': case 'Subject': case 'Keywords': case 'Creator': case 'Producer': case 'CreationDate': case 'ModDate': case 'Trapped': $this->objects[$id]['info'][$action] = $options; break; case 'out': $encrypted = $this->encrypted; if ($encrypted) { $this->encryptInit($id); } $res = "\n$id 0 obj\n<<\n"; $o = &$this->objects[$id]; foreach ($o['info'] as $k => $v) { $res .= "/$k ("; // dates must be outputted as-is, without Unicode transformations if ($k !== 'CreationDate' && $k !== 'ModDate') { $v = $this->filterText($v, true, false); } if ($encrypted) { $v = $this->ARC4($v); } $res .= $v; $res .= ")\n"; } $res .= ">>\nendobj"; return $res; } return null; } /** * an action object, used to link to URLS initially * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_action($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': if (is_array($options)) { $this->objects[$id] = ['t' => 'action', 'info' => $options, 'type' => $options['type']]; } else { // then assume a URI action $this->objects[$id] = ['t' => 'action', 'info' => $options, 'type' => 'URI']; } break; case 'out': if ($this->encrypted) { $this->encryptInit($id); } $res = "\n$id 0 obj\n<< /Type /Action"; switch ($o['type']) { case 'ilink': if (!isset($this->destinations[(string)$o['info']['label']])) { break; } // there will be an 'label' setting, this is the name of the destination $res .= "\n/S /GoTo\n/D " . $this->destinations[(string)$o['info']['label']] . " 0 R"; break; case 'URI': $res .= "\n/S /URI\n/URI ("; if ($this->encrypted) { $res .= $this->filterText($this->ARC4($o['info']), false, false); } else { $res .= $this->filterText($o['info'], false, false); } $res .= ")"; break; } $res .= "\n>>\nendobj"; return $res; } return null; } /** * an annotation object, this will add an annotation to the current page. * initially will support just link annotations * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_annotation($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': // add the annotation to the current page $pageId = $this->currentPage; $this->o_page($pageId, 'annot', $id); // and add the action object which is going to be required switch ($options['type']) { case 'link': $this->objects[$id] = ['t' => 'annotation', 'info' => $options]; $this->numObj++; $this->o_action($this->numObj, 'new', $options['url']); $this->objects[$id]['info']['actionId'] = $this->numObj; break; case 'ilink': // this is to a named internal link $label = $options['label']; $this->objects[$id] = ['t' => 'annotation', 'info' => $options]; $this->numObj++; $this->o_action($this->numObj, 'new', ['type' => 'ilink', 'label' => $label]); $this->objects[$id]['info']['actionId'] = $this->numObj; break; } break; case 'out': $res = "\n$id 0 obj\n<< /Type /Annot"; switch ($o['info']['type']) { case 'link': case 'ilink': $res .= "\n/Subtype /Link"; break; } $res .= "\n/A " . $o['info']['actionId'] . " 0 R"; $res .= "\n/Border [0 0 0]"; $res .= "\n/H /I"; $res .= "\n/Rect [ "; foreach ($o['info']['rect'] as $v) { $res .= sprintf("%.4F ", $v); } $res .= "]"; $res .= "\n>>\nendobj"; return $res; } return null; } /** * a page object, it also creates a contents object to hold its contents * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_page($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->numPages++; $this->objects[$id] = [ 't' => 'page', 'info' => [ 'parent' => $this->currentNode, 'pageNum' => $this->numPages, 'mediaBox' => $this->objects[$this->currentNode]['info']['mediaBox'] ] ]; if (is_array($options)) { // then this must be a page insertion, array should contain 'rid','pos'=[before|after] $options['id'] = $id; $this->o_pages($this->currentNode, 'page', $options); } else { $this->o_pages($this->currentNode, 'page', $id); } $this->currentPage = $id; //make a contents object to go with this page $this->numObj++; $this->o_contents($this->numObj, 'new', $id); $this->currentContents = $this->numObj; $this->objects[$id]['info']['contents'] = []; $this->objects[$id]['info']['contents'][] = $this->numObj; $match = ($this->numPages % 2 ? 'odd' : 'even'); foreach ($this->addLooseObjects as $oId => $target) { if ($target === 'all' || $match === $target) { $this->objects[$id]['info']['contents'][] = $oId; } } break; case 'content': $o['info']['contents'][] = $options; break; case 'annot': // add an annotation to this page if (!isset($o['info']['annot'])) { $o['info']['annot'] = []; } // $options should contain the id of the annotation dictionary $o['info']['annot'][] = $options; break; case 'out': $res = "\n$id 0 obj\n<< /Type /Page"; if (isset($o['info']['mediaBox'])) { $tmp = $o['info']['mediaBox']; $res .= "\n/MediaBox [" . sprintf( '%.3F %.3F %.3F %.3F', $tmp[0], $tmp[1], $tmp[2], $tmp[3] ) . ']'; } $res .= "\n/Parent " . $o['info']['parent'] . " 0 R"; if (isset($o['info']['annot'])) { $res .= "\n/Annots ["; foreach ($o['info']['annot'] as $aId) { $res .= " $aId 0 R"; } $res .= " ]"; } $count = count($o['info']['contents']); if ($count == 1) { $res .= "\n/Contents " . $o['info']['contents'][0] . " 0 R"; } else { if ($count > 1) { $res .= "\n/Contents [\n"; // reverse the page contents so added objects are below normal content //foreach (array_reverse($o['info']['contents']) as $cId) { // Back to normal now that I've got transparency working --Benj foreach ($o['info']['contents'] as $cId) { $res .= "$cId 0 R\n"; } $res .= "]"; } } $res .= "\n>>\nendobj"; return $res; } return null; } /** * the contents objects hold all of the content which appears on pages * * @param $id * @param $action * @param string|array $options * @return null|string */ protected function o_contents($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'contents', 'c' => '', 'info' => []]; if (mb_strlen($options, '8bit') && intval($options)) { // then this contents is the primary for a page $this->objects[$id]['onPage'] = $options; } else { if ($options === 'raw') { // then this page contains some other type of system object $this->objects[$id]['raw'] = 1; } } break; case 'add': // add more options to the declaration foreach ($options as $k => $v) { $o['info'][$k] = $v; } case 'out': $tmp = $o['c']; $res = "\n$id 0 obj\n"; if (isset($this->objects[$id]['raw'])) { $res .= $tmp; } else { $res .= "<<"; if ($this->compressionReady && $this->options['compression']) { // then implement ZLIB based compression on this content stream $res .= " /Filter /FlateDecode"; $tmp = gzcompress($tmp, 6); } if ($this->encrypted) { $this->encryptInit($id); $tmp = $this->ARC4($tmp); } foreach ($o['info'] as $k => $v) { $res .= "\n/$k $v"; } $res .= "\n/Length " . mb_strlen($tmp, '8bit') . " >>\nstream\n$tmp\nendstream"; } $res .= "\nendobj"; return $res; } return null; } /** * @param $id * @param $action * @return string|null */ protected function o_embedjs($id, $action) { switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'embedjs', 'info' => [ 'Names' => '[(EmbeddedJS) ' . ($id + 1) . ' 0 R]' ] ]; break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< "; foreach ($o['info'] as $k => $v) { $res .= "\n/$k $v"; } $res .= "\n>>\nendobj"; return $res; } return null; } /** * @param $id * @param $action * @param string $code * @return null|string */ protected function o_javascript($id, $action, $code = '') { switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'javascript', 'info' => [ 'S' => '/JavaScript', 'JS' => '(' . $this->filterText($code, true, false) . ')', ] ]; break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< "; foreach ($o['info'] as $k => $v) { $res .= "\n/$k $v"; } $res .= "\n>>\nendobj"; return $res; } return null; } /** * an image object, will be an XObject in the document, includes description and data * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_image($id, $action, $options = '') { switch ($action) { case 'new': // make the new object $this->objects[$id] = ['t' => 'image', 'data' => &$options['data'], 'info' => []]; $info =& $this->objects[$id]['info']; $info['Type'] = '/XObject'; $info['Subtype'] = '/Image'; $info['Width'] = $options['iw']; $info['Height'] = $options['ih']; if (isset($options['masked']) && $options['masked']) { $info['SMask'] = ($this->numObj - 1) . ' 0 R'; } if (!isset($options['type']) || $options['type'] === 'jpg') { if (!isset($options['channels'])) { $options['channels'] = 3; } switch ($options['channels']) { case 1: $info['ColorSpace'] = '/DeviceGray'; break; case 4: $info['ColorSpace'] = '/DeviceCMYK'; break; default: $info['ColorSpace'] = '/DeviceRGB'; break; } if ($info['ColorSpace'] === '/DeviceCMYK') { $info['Decode'] = '[1 0 1 0 1 0 1 0]'; } $info['Filter'] = '/DCTDecode'; $info['BitsPerComponent'] = 8; } else { if ($options['type'] === 'png') { $info['Filter'] = '/FlateDecode'; $info['DecodeParms'] = '<< /Predictor 15 /Colors ' . $options['ncolor'] . ' /Columns ' . $options['iw'] . ' /BitsPerComponent ' . $options['bitsPerComponent'] . '>>'; if ($options['isMask']) { $info['ColorSpace'] = '/DeviceGray'; } else { if (mb_strlen($options['pdata'], '8bit')) { $tmp = ' [ /Indexed /DeviceRGB ' . (mb_strlen($options['pdata'], '8bit') / 3 - 1) . ' '; $this->numObj++; $this->o_contents($this->numObj, 'new'); $this->objects[$this->numObj]['c'] = $options['pdata']; $tmp .= $this->numObj . ' 0 R'; $tmp .= ' ]'; $info['ColorSpace'] = $tmp; if (isset($options['transparency'])) { $transparency = $options['transparency']; switch ($transparency['type']) { case 'indexed': $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; $info['Mask'] = $tmp; break; case 'color-key': $tmp = ' [ ' . $transparency['r'] . ' ' . $transparency['r'] . $transparency['g'] . ' ' . $transparency['g'] . $transparency['b'] . ' ' . $transparency['b'] . ' ] '; $info['Mask'] = $tmp; break; } } } else { if (isset($options['transparency'])) { $transparency = $options['transparency']; switch ($transparency['type']) { case 'indexed': $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; $info['Mask'] = $tmp; break; case 'color-key': $tmp = ' [ ' . $transparency['r'] . ' ' . $transparency['r'] . ' ' . $transparency['g'] . ' ' . $transparency['g'] . ' ' . $transparency['b'] . ' ' . $transparency['b'] . ' ] '; $info['Mask'] = $tmp; break; } } $info['ColorSpace'] = '/' . $options['color']; } } $info['BitsPerComponent'] = $options['bitsPerComponent']; } } // assign it a place in the named resource dictionary as an external object, according to // the label passed in with it. $this->o_pages($this->currentNode, 'xObject', ['label' => $options['label'], 'objNum' => $id]); // also make sure that we have the right procset object for it. $this->o_procset($this->procsetObjectId, 'add', 'ImageC'); break; case 'out': $o = &$this->objects[$id]; $tmp = &$o['data']; $res = "\n$id 0 obj\n<<"; foreach ($o['info'] as $k => $v) { $res .= "\n/$k $v"; } if ($this->encrypted) { $this->encryptInit($id); $tmp = $this->ARC4($tmp); } $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream\nendobj"; return $res; } return null; } /** * graphics state object * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_extGState($id, $action, $options = "") { static $valid_params = [ "LW", "LC", "LC", "LJ", "ML", "D", "RI", "OP", "op", "OPM", "Font", "BG", "BG2", "UCR", "TR", "TR2", "HT", "FL", "SM", "SA", "BM", "SMask", "CA", "ca", "AIS", "TK" ]; switch ($action) { case "new": $this->objects[$id] = ['t' => 'extGState', 'info' => $options]; // Tell the pages about the new resource $this->numStates++; $this->o_pages($this->currentNode, 'extGState', ["objNum" => $id, "stateNum" => $this->numStates]); break; case "out": $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< /Type /ExtGState\n"; foreach ($o["info"] as $k => $v) { if (!in_array($k, $valid_params)) { continue; } $res .= "/$k $v\n"; } $res .= ">>\nendobj"; return $res; } return null; } /** * @param integer $id * @param string $action * @param mixed $options * @return string */ protected function o_xobject($id, $action, $options = '') { switch ($action) { case 'new': $this->objects[$id] = ['t' => 'xobject', 'info' => $options, 'c' => '']; break; case 'procset': $this->objects[$id]['procset'] = $options; break; case 'font': $this->objects[$id]['fonts'][$options['fontNum']] = [ 'objNum' => $options['objNum'], 'fontNum' => $options['fontNum'] ]; break; case 'xObject': $this->objects[$id]['xObjects'][] = ['objNum' => $options['objNum'], 'label' => $options['label']]; break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< /Type /XObject\n"; foreach ($o["info"] as $k => $v) { switch($k) { case 'Subtype': $res .= "/Subtype /$v\n"; break; case 'bbox': $res .= "/BBox ["; foreach ($v as $value) { $res .= sprintf("%.4F ", $value); } $res .= "]\n"; break; default: $res .= "/$k $v\n"; break; } } $res .= "/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]\n"; $res .= "/Resources <<"; if (isset($o['procset'])) { $res .= "\n/ProcSet " . $o['procset'] . " 0 R"; } else { $res .= "\n/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"; } if (isset($o['fonts']) && count($o['fonts'])) { $res .= "\n/Font << "; foreach ($o['fonts'] as $finfo) { $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; } $res .= "\n>>"; } if (isset($o['xObjects']) && count($o['xObjects'])) { $res .= "\n/XObject << "; foreach ($o['xObjects'] as $finfo) { $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; } $res .= "\n>>"; } $res .= "\n>>\n"; $tmp = $o["c"]; if ($this->compressionReady && $this->options['compression']) { // then implement ZLIB based compression on this content stream $res .= " /Filter /FlateDecode\n"; $tmp = gzcompress($tmp, 6); } if ($this->encrypted) { $this->encryptInit($id); $tmp = $this->ARC4($tmp); } $res .= "/Length " . mb_strlen($tmp, '8bit') . " >>\n"; $res .= "stream\n" . $tmp . "\nendstream" . "\nendobj";; return $res; } return null; } /** * @param $id * @param $action * @param string $options * @return null|string */ protected function o_acroform($id, $action, $options = '') { switch ($action) { case "new": $this->o_catalog($this->catalogId, 'acroform', $id); $this->objects[$id] = array('t' => 'acroform', 'info' => $options); break; case 'addfield': $this->objects[$id]['info']['Fields'][] = $options; break; case 'font': $this->objects[$id]['fonts'][$options['fontNum']] = [ 'objNum' => $options['objNum'], 'fontNum' => $options['fontNum'] ]; break; case "out": $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<<"; foreach ($o["info"] as $k => $v) { switch($k) { case 'Fields': $res .= " /Fields ["; foreach ($v as $i) { $res .= "$i 0 R "; } $res .= "]\n"; break; default: $res .= "/$k $v\n"; } } $res .= "/DR <<\n"; if (isset($o['fonts']) && count($o['fonts'])) { $res .= "/Font << \n"; foreach ($o['fonts'] as $finfo) { $res .= "/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R\n"; } $res .= ">>\n"; } $res .= ">>\n"; $res .= ">>\nendobj"; return $res; } return null; } /** * @param $id * @param $action * @param mixed $options * @return null|string */ protected function o_field($id, $action, $options = '') { switch ($action) { case "new": $this->o_page($options['pageid'], 'annot', $id); $this->o_acroform($this->acroFormId, 'addfield', $id); $this->objects[$id] = ['t' => 'field', 'info' => $options]; break; case 'set': $this->objects[$id]['info'] = array_merge($this->objects[$id]['info'], $options); break; case "out": $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< /Type /Annot /Subtype /Widget \n"; $encrypted = $this->encrypted; if ($encrypted) { $this->encryptInit($id); } foreach ($o["info"] as $k => $v) { switch ($k) { case 'pageid': $res .= "/P $v 0 R\n"; break; case 'value': if ($encrypted) { $v = $this->filterText($this->ARC4($v), false, false); } $res .= "/V ($v)\n"; break; case 'refvalue': $res .= "/V $v 0 R\n"; break; case 'da': if ($encrypted) { $v = $this->filterText($this->ARC4($v), false, false); } $res .= "/DA ($v)\n"; break; case 'options': $res .= "/Opt [\n"; foreach ($v as $opt) { if ($encrypted) { $opt = $this->filterText($this->ARC4($opt), false, false); } $res .= "($opt)\n"; } $res .= "]\n"; break; case 'rect': $res .= "/Rect ["; foreach ($v as $value) { $res .= sprintf("%.4F ", $value); } $res .= "]\n"; break; case 'appearance': $res .= "/AP << "; foreach ($v as $a => $ref) { $res .= "/$a $ref 0 R "; } $res .= ">>\n"; break; case 'T': if($encrypted) { $v = $this->filterText($this->ARC4($v), false, false); } $res .= "/T ($v)\n"; break; default: $res .= "/$k $v\n"; } } $res .= ">>\nendobj"; return $res; } return null; } /** * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_sig($id, $action, $options = '') { $sign_maxlen = $this->signatureMaxLen; switch ($action) { case "new": $this->objects[$id] = array('t' => 'sig', 'info' => $options); $this->byteRange[$id] = ['t' => 'sig']; break; case 'byterange': $o = &$this->objects[$id]; $content =& $options['content']; $content_len = strlen($content); $pos = strpos($content, sprintf("/ByteRange [ %'.010d", $id)); $len = strlen('/ByteRange [ ********** ********** ********** ********** ]'); $rangeStartPos = $pos + $len + 1 + 10; // before '<' $content = substr_replace($content, str_pad(sprintf('/ByteRange [ 0 %u %u %u ]', $rangeStartPos, $rangeStartPos + $sign_maxlen + 2, $content_len - 2 - $sign_maxlen - $rangeStartPos ), $len, ' ', STR_PAD_RIGHT), $pos, $len); $fuid = uniqid(); $tmpInput = $this->tmp . "/pkcs7.tmp." . $fuid . '.in'; $tmpOutput = $this->tmp . "/pkcs7.tmp." . $fuid . '.out'; if (file_put_contents($tmpInput, substr($content, 0, $rangeStartPos)) === false) { throw new \Exception("Unable to write temporary file for signing."); } if (file_put_contents($tmpInput, substr($content, $rangeStartPos + 2 + $sign_maxlen), FILE_APPEND) === false) { throw new \Exception("Unable to write temporary file for signing."); } if (openssl_pkcs7_sign($tmpInput, $tmpOutput, $o['info']['SignCert'], array($o['info']['PrivKey'], $o['info']['Password']), array(), PKCS7_BINARY | PKCS7_DETACHED) === false) { throw new \Exception("Failed to prepare signature."); } $signature = file_get_contents($tmpOutput); unlink($tmpInput); unlink($tmpOutput); $sign = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13)); list($head, $signature) = explode("\n\n", $sign); $signature = base64_decode(trim($signature)); $signature = current(unpack('H*', $signature)); $signature = str_pad($signature, $sign_maxlen, '0'); $siglen = strlen($signature); if (strlen($signature) > $sign_maxlen) { throw new \Exception("Signature length ($siglen) exceeds the $sign_maxlen limit."); } $content = substr_replace($content, $signature, $rangeStartPos + 1, $sign_maxlen); break; case "out": $res = "\n$id 0 obj\n<<\n"; $encrypted = $this->encrypted; if ($encrypted) { $this->encryptInit($id); } $res .= "/ByteRange " .sprintf("[ %'.010d ********** ********** ********** ]\n", $id); $res .= "/Contents <" . str_pad('', $sign_maxlen, '0') . ">\n"; $res .= "/Filter/Adobe.PPKLite\n"; //PPKMS \n"; $res .= "/Type/Sig/SubFilter/adbe.pkcs7.detached \n"; $date = "D:" . substr_replace(date('YmdHisO'), '\'', -2, 0) . '\''; if ($encrypted) { $date = $this->ARC4($date); } $res .= "/M ($date)\n"; $res .= "/Prop_Build << /App << /Name /DomPDF >> /Filter << /Name /Adobe.PPKLite >> >>\n"; $o = &$this->objects[$id]; foreach ($o['info'] as $k => $v) { switch($k) { case 'Name': case 'Location': case 'Reason': case 'ContactInfo': if ($v !== null && $v !== '') { $res .= "/$k (" . ($encrypted ? $this->filterText($this->ARC4($v), false, false) : $v) . ") \n"; } break; } } $res .= ">>\nendobj"; return $res; } return null; } /** * encryption object. * * @param $id * @param $action * @param string $options * @return string|null */ protected function o_encryption($id, $action, $options = '') { switch ($action) { case 'new': // make the new object $this->objects[$id] = ['t' => 'encryption', 'info' => $options]; $this->arc4_objnum = $id; break; case 'keys': // figure out the additional parameters required $pad = chr(0x28) . chr(0xBF) . chr(0x4E) . chr(0x5E) . chr(0x4E) . chr(0x75) . chr(0x8A) . chr(0x41) . chr(0x64) . chr(0x00) . chr(0x4E) . chr(0x56) . chr(0xFF) . chr(0xFA) . chr(0x01) . chr(0x08) . chr(0x2E) . chr(0x2E) . chr(0x00) . chr(0xB6) . chr(0xD0) . chr(0x68) . chr(0x3E) . chr(0x80) . chr(0x2F) . chr(0x0C) . chr(0xA9) . chr(0xFE) . chr(0x64) . chr(0x53) . chr(0x69) . chr(0x7A); $info = $this->objects[$id]['info']; $len = mb_strlen($info['owner'], '8bit'); if ($len > 32) { $owner = substr($info['owner'], 0, 32); } else { if ($len < 32) { $owner = $info['owner'] . substr($pad, 0, 32 - $len); } else { $owner = $info['owner']; } } $len = mb_strlen($info['user'], '8bit'); if ($len > 32) { $user = substr($info['user'], 0, 32); } else { if ($len < 32) { $user = $info['user'] . substr($pad, 0, 32 - $len); } else { $user = $info['user']; } } $tmp = $this->md5_16($owner); $okey = substr($tmp, 0, 5); $this->ARC4_init($okey); $ovalue = $this->ARC4($user); $this->objects[$id]['info']['O'] = $ovalue; // now make the u value, phew. $tmp = $this->md5_16( $user . $ovalue . chr($info['p']) . chr(255) . chr(255) . chr(255) . hex2bin($this->fileIdentifier) ); $ukey = substr($tmp, 0, 5); $this->ARC4_init($ukey); $this->encryptionKey = $ukey; $this->encrypted = true; $uvalue = $this->ARC4($pad); $this->objects[$id]['info']['U'] = $uvalue; // initialize the arc4 array break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<<"; $res .= "\n/Filter /Standard"; $res .= "\n/V 1"; $res .= "\n/R 2"; $res .= "\n/O (" . $this->filterText($o['info']['O'], false, false) . ')'; $res .= "\n/U (" . $this->filterText($o['info']['U'], false, false) . ')'; // and the p-value needs to be converted to account for the twos-complement approach $o['info']['p'] = (($o['info']['p'] ^ 255) + 1) * -1; $res .= "\n/P " . ($o['info']['p']); $res .= "\n>>\nendobj"; return $res; } return null; } protected function o_indirect_references($id, $action, $options = null) { switch ($action) { case 'new': case 'add': if ($id === 0) { $id = ++$this->numObj; $this->o_catalog($this->catalogId, 'names', $id); $this->objects[$id] = ['t' => 'indirect_references', 'info' => $options]; $this->indirectReferenceId = $id; } else { $this->objects[$id]['info'] = array_merge($this->objects[$id]['info'], $options); } break; case 'out': $res = "\n$id 0 obj << "; foreach($this->objects[$id]['info'] as $referenceObjName => $referenceObjId) { $res .= "/$referenceObjName $referenceObjId 0 R "; } $res .= ">> endobj"; return $res; } return null; } protected function o_names($id, $action, $options = null) { switch ($action) { case 'new': case 'add': if ($id === 0) { $id = ++$this->numObj; $this->objects[$id] = ['t' => 'names', 'info' => [$options]]; $this->o_indirect_references($this->indirectReferenceId, 'add', ['EmbeddedFiles' => $id]); $this->embeddedFilesId = $id; } else { $this->objects[$id]['info'][] = $options; } break; case 'out': $info = &$this->objects[$id]['info']; $res = ''; if (count($info) > 0) { $res = "\n$id 0 obj << /Names [ "; if ($this->encrypted) { $this->encryptInit($id); } foreach ($info as $entry) { if ($this->encrypted) { $filename = $this->ARC4($entry['filename']); } else { $filename = $entry['filename']; } $res .= "($filename) " . $entry['dict_reference'] . " 0 R "; } $res .= "] >> endobj"; } return $res; } return null; } protected function o_embedded_file_dictionary($id, $action, $options = null) { switch ($action) { case 'new': $embeddedFileId = ++$this->numObj; $options['embedded_reference'] = $embeddedFileId; $this->objects[$id] = ['t' => 'embedded_file_dictionary', 'info' => $options]; $this->o_embedded_file($embeddedFileId, 'new', $options); $options['dict_reference'] = $id; $this->o_names($this->embeddedFilesId, 'add', $options); break; case 'out': $info = &$this->objects[$id]['info']; if ($this->encrypted) { $this->encryptInit($id); $filename = $this->ARC4($info['filename']); $description = $this->ARC4($info['description']); } else { $filename = $info['filename']; $description = $info['description']; } $res = "\n$id 0 obj <>"; $res .= " /F ($filename) /UF ($filename) /Desc ($description)"; $res .= " >> endobj"; return $res; } return null; } protected function o_embedded_file($id, $action, $options = null): ?string { switch ($action) { case 'new': $this->objects[$id] = ['t' => 'embedded_file', 'info' => $options]; break; case 'out': $info = &$this->objects[$id]['info']; if ($this->compressionReady) { $filepath = $info['filepath']; $checksum = md5_file($filepath); $f = fopen($filepath, "rb"); $file_content_compressed = ''; $deflateContext = deflate_init(ZLIB_ENCODING_DEFLATE, ['level' => 6]); while (($block = fread($f, 8192))) { $file_content_compressed .= deflate_add($deflateContext, $block, ZLIB_NO_FLUSH); } $file_content_compressed .= deflate_add($deflateContext, '', ZLIB_FINISH); $file_size_uncompressed = ftell($f); fclose($f); } else { $file_content = file_get_contents($info['filepath']); $file_size_uncompressed = mb_strlen($file_content, '8bit'); $checksum = md5($file_content); } if ($this->encrypted) { $this->encryptInit($id); $checksum = $this->ARC4($checksum); $file_content_compressed = $this->ARC4($file_content_compressed); } $file_size_compressed = mb_strlen($file_content_compressed, '8bit'); $res = "\n$id 0 obj <>" . " /Type/EmbeddedFile /Filter/FlateDecode" . " /Length $file_size_compressed >> stream\n$file_content_compressed\nendstream\nendobj"; return $res; } return null; } /** * ARC4 functions * A series of function to implement ARC4 encoding in PHP */ /** * calculate the 16 byte version of the 128 bit md5 digest of the string * * @param $string * @return string */ function md5_16($string) { $tmp = md5($string); $out = ''; for ($i = 0; $i <= 30; $i = $i + 2) { $out .= chr(hexdec(substr($tmp, $i, 2))); } return $out; } /** * initialize the encryption for processing a particular object * * @param $id */ function encryptInit($id) { $tmp = $this->encryptionKey; $hex = dechex($id); if (mb_strlen($hex, '8bit') < 6) { $hex = substr('000000', 0, 6 - mb_strlen($hex, '8bit')) . $hex; } $tmp .= chr(hexdec(substr($hex, 4, 2))) . chr(hexdec(substr($hex, 2, 2))) . chr(hexdec(substr($hex, 0, 2))) . chr(0) . chr(0) ; $key = $this->md5_16($tmp); $this->ARC4_init(substr($key, 0, 10)); } /** * initialize the ARC4 encryption * * @param string $key */ function ARC4_init($key = '') { $this->arc4 = ''; // setup the control array if (mb_strlen($key, '8bit') == 0) { return; } $k = ''; while (mb_strlen($k, '8bit') < 256) { $k .= $key; } $k = substr($k, 0, 256); for ($i = 0; $i < 256; $i++) { $this->arc4 .= chr($i); } $j = 0; for ($i = 0; $i < 256; $i++) { $t = $this->arc4[$i]; $j = ($j + ord($t) + ord($k[$i])) % 256; $this->arc4[$i] = $this->arc4[$j]; $this->arc4[$j] = $t; } } /** * ARC4 encrypt a text string * * @param $text * @return string */ function ARC4($text) { $len = mb_strlen($text, '8bit'); $a = 0; $b = 0; $c = $this->arc4; $out = ''; for ($i = 0; $i < $len; $i++) { $a = ($a + 1) % 256; $t = $c[$a]; $b = ($b + ord($t)) % 256; $c[$a] = $c[$b]; $c[$b] = $t; $k = ord($c[(ord($c[$a]) + ord($c[$b])) % 256]); $out .= chr(ord($text[$i]) ^ $k); } return $out; } /** * functions which can be called to adjust or add to the document */ /** * add a link in the document to an external URL * * @param $url * @param $x0 * @param $y0 * @param $x1 * @param $y1 */ function addLink($url, $x0, $y0, $x1, $y1) { $this->numObj++; $info = ['type' => 'link', 'url' => $url, 'rect' => [$x0, $y0, $x1, $y1]]; $this->o_annotation($this->numObj, 'new', $info); } /** * add a link in the document to an internal destination (ie. within the document) * * @param $label * @param $x0 * @param $y0 * @param $x1 * @param $y1 */ function addInternalLink($label, $x0, $y0, $x1, $y1) { $this->numObj++; $info = ['type' => 'ilink', 'label' => $label, 'rect' => [$x0, $y0, $x1, $y1]]; $this->o_annotation($this->numObj, 'new', $info); } /** * set the encryption of the document * can be used to turn it on and/or set the passwords which it will have. * also the functions that the user will have are set here, such as print, modify, add * * @param string $userPass * @param string $ownerPass * @param array $pc */ function setEncryption($userPass = '', $ownerPass = '', $pc = []) { $p = bindec("11000000"); $options = ['print' => 4, 'modify' => 8, 'copy' => 16, 'add' => 32]; foreach ($pc as $k => $v) { if ($v && isset($options[$k])) { $p += $options[$k]; } else { if (isset($options[$v])) { $p += $options[$v]; } } } // implement encryption on the document if ($this->arc4_objnum == 0) { // then the block does not exist already, add it. $this->numObj++; if (mb_strlen($ownerPass) == 0) { $ownerPass = $userPass; } $this->o_encryption($this->numObj, 'new', ['user' => $userPass, 'owner' => $ownerPass, 'p' => $p]); } } /** * should be used for internal checks, not implemented as yet */ function checkAllHere() { } /** * return the pdf stream as a string returned from the function * * @param bool $debug * @return string */ function output($debug = false) { if ($debug) { // turn compression off $this->options['compression'] = false; } if ($this->javascript) { $this->numObj++; $js_id = $this->numObj; $this->o_embedjs($js_id, 'new'); $this->o_javascript(++$this->numObj, 'new', $this->javascript); $id = $this->catalogId; $this->o_indirect_references($this->indirectReferenceId, 'add', ['JavaScript' => $js_id]); } if ($this->fileIdentifier === '') { $tmp = implode('', $this->objects[$this->infoObject]['info']); $this->fileIdentifier = md5('DOMPDF' . __FILE__ . $tmp . microtime() . mt_rand()); } if ($this->arc4_objnum) { $this->o_encryption($this->arc4_objnum, 'keys'); $this->ARC4_init($this->encryptionKey); } $this->checkAllHere(); $xref = []; $content = '%PDF-' . self::PDF_VERSION; $pos = mb_strlen($content, '8bit'); // pre-process o_font objects before output of all objects foreach ($this->objects as $k => $v) { if ($v['t'] === 'font') { $this->o_font($k, 'add'); } } foreach ($this->objects as $k => $v) { $tmp = 'o_' . $v['t']; $cont = $this->$tmp($k, 'out'); $content .= $cont; $xref[] = $pos + 1; //+1 to account for \n at the start of each object $pos += mb_strlen($cont, '8bit'); } $content .= "\nxref\n0 " . (count($xref) + 1) . "\n0000000000 65535 f \n"; foreach ($xref as $p) { $content .= str_pad($p, 10, "0", STR_PAD_LEFT) . " 00000 n \n"; } $content .= "trailer\n<<\n" . '/Size ' . (count($xref) + 1) . "\n" . '/Root 1 0 R' . "\n" . '/Info ' . $this->infoObject . " 0 R\n" ; // if encryption has been applied to this document then add the marker for this dictionary if ($this->arc4_objnum > 0) { $content .= '/Encrypt ' . $this->arc4_objnum . " 0 R\n"; } $content .= '/ID[<' . $this->fileIdentifier . '><' . $this->fileIdentifier . ">]\n"; // account for \n added at start of xref table $pos++; $content .= ">>\nstartxref\n$pos\n%%EOF\n"; if (count($this->byteRange) > 0) { foreach ($this->byteRange as $k => $v) { $tmp = 'o_' . $v['t']; $this->$tmp($k, 'byterange', ['content' => &$content]); } } return $content; } /** * initialize a new document * if this is called on an existing document results may be unpredictable, but the existing document would be lost at minimum * this function is called automatically by the constructor function * * @param array $pageSize */ private function newDocument($pageSize = [0, 0, 612, 792]) { $this->numObj = 0; $this->objects = []; $this->numObj++; $this->o_catalog($this->numObj, 'new'); $this->numObj++; $this->o_outlines($this->numObj, 'new'); $this->numObj++; $this->o_pages($this->numObj, 'new'); $this->o_pages($this->numObj, 'mediaBox', $pageSize); $this->currentNode = 3; $this->numObj++; $this->o_procset($this->numObj, 'new'); $this->numObj++; $this->o_info($this->numObj, 'new'); $this->numObj++; $this->o_page($this->numObj, 'new'); // need to store the first page id as there is no way to get it to the user during // startup $this->firstPageId = $this->currentContents; } /** * open the font file and return a php structure containing it. * first check if this one has been done before and saved in a form more suited to php * note that if a php serialized version does not exist it will try and make one, but will * require write access to the directory to do it... it is MUCH faster to have these serialized * files. * * @param $font */ private function openFont($font) { // assume that $font contains the path and file but not the extension $name = basename($font); $dir = dirname($font) . '/'; $fontcache = $this->fontcache; if ($fontcache == '') { $fontcache = rtrim($dir, DIRECTORY_SEPARATOR."/\\"); } //$name filename without folder and extension of font metrics //$dir folder of font metrics //$fontcache folder of runtime created php serialized version of font metrics. // If this is not given, the same folder as the font metrics will be used. // Storing and reusing serialized versions improves speed much $this->addMessage("openFont: $font - $name"); if (!$this->isUnicode || in_array(mb_strtolower(basename($name)), self::$coreFonts)) { $metrics_name = "$name.afm"; } else { $metrics_name = "$name.ufm"; } $cache_name = "$metrics_name.php"; $this->addMessage("metrics: $metrics_name, cache: $cache_name"); if (file_exists($fontcache . '/' . $cache_name)) { $this->addMessage("openFont: php file exists $fontcache/$cache_name"); $this->fonts[$font] = require($fontcache . '/' . $cache_name); if (!isset($this->fonts[$font]['_version_']) || $this->fonts[$font]['_version_'] != $this->fontcacheVersion) { // if the font file is old, then clear it out and prepare for re-creation $this->addMessage('openFont: clear out, make way for new version.'); $this->fonts[$font] = null; unset($this->fonts[$font]); } } else { $old_cache_name = "php_$metrics_name"; if (file_exists($fontcache . '/' . $old_cache_name)) { $this->addMessage( "openFont: php file doesn't exist $fontcache/$cache_name, creating it from the old format" ); $old_cache = file_get_contents($fontcache . '/' . $old_cache_name); file_put_contents($fontcache . '/' . $cache_name, 'openFont($font); return; } } if (!isset($this->fonts[$font]) && file_exists($dir . $metrics_name)) { // then rebuild the php_.afm file from the .afm file $this->addMessage("openFont: build php file from $dir$metrics_name"); $data = []; // 20 => 'space' $data['codeToName'] = []; // Since we're not going to enable Unicode for the core fonts we need to use a font-based // setting for Unicode support rather than a global setting. $data['isUnicode'] = (strtolower(substr($metrics_name, -3)) !== 'afm'); $cidtogid = ''; if ($data['isUnicode']) { $cidtogid = str_pad('', 256 * 256 * 2, "\x00"); } $file = file($dir . $metrics_name); foreach ($file as $rowA) { $row = trim($rowA); $pos = strpos($row, ' '); if ($pos) { // then there must be some keyword $key = substr($row, 0, $pos); switch ($key) { case 'FontName': case 'FullName': case 'FamilyName': case 'PostScriptName': case 'Weight': case 'ItalicAngle': case 'IsFixedPitch': case 'CharacterSet': case 'UnderlinePosition': case 'UnderlineThickness': case 'Version': case 'EncodingScheme': case 'CapHeight': case 'XHeight': case 'Ascender': case 'Descender': case 'StdHW': case 'StdVW': case 'StartCharMetrics': case 'FontHeightOffset': // OAR - Added so we can offset the height calculation of a Windows font. Otherwise it's too big. $data[$key] = trim(substr($row, $pos)); break; case 'FontBBox': $data[$key] = explode(' ', trim(substr($row, $pos))); break; //C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; case 'C': // Found in AFM files $bits = explode(';', trim($row)); $dtmp = ['C' => null, 'N' => null, 'WX' => null, 'B' => []]; foreach ($bits as $bit) { $bits2 = explode(' ', trim($bit)); if (mb_strlen($bits2[0], '8bit') == 0) { continue; } if (count($bits2) > 2) { $dtmp[$bits2[0]] = []; for ($i = 1; $i < count($bits2); $i++) { $dtmp[$bits2[0]][] = $bits2[$i]; } } else { if (count($bits2) == 2) { $dtmp[$bits2[0]] = $bits2[1]; } } } $c = (int)$dtmp['C']; $n = $dtmp['N']; $width = floatval($dtmp['WX']); if ($c >= 0) { if (!ctype_xdigit($n) || $c != hexdec($n)) { $data['codeToName'][$c] = $n; } $data['C'][$c] = $width; } elseif (isset($n)) { $data['C'][$n] = $width; } if (!isset($data['MissingWidth']) && $c === -1 && $n === '.notdef') { $data['MissingWidth'] = $width; } break; // U 827 ; WX 0 ; N squaresubnosp ; G 675 ; case 'U': // Found in UFM files if (!$data['isUnicode']) { break; } $bits = explode(';', trim($row)); $dtmp = ['G' => null, 'N' => null, 'U' => null, 'WX' => null]; foreach ($bits as $bit) { $bits2 = explode(' ', trim($bit)); if (mb_strlen($bits2[0], '8bit') === 0) { continue; } if (count($bits2) > 2) { $dtmp[$bits2[0]] = []; for ($i = 1; $i < count($bits2); $i++) { $dtmp[$bits2[0]][] = $bits2[$i]; } } else { if (count($bits2) == 2) { $dtmp[$bits2[0]] = $bits2[1]; } } } $c = (int)$dtmp['U']; $n = $dtmp['N']; $glyph = $dtmp['G']; $width = floatval($dtmp['WX']); if ($c >= 0) { // Set values in CID to GID map if ($c >= 0 && $c < 0xFFFF && $glyph) { $cidtogid[$c * 2] = chr($glyph >> 8); $cidtogid[$c * 2 + 1] = chr($glyph & 0xFF); } if (!ctype_xdigit($n) || $c != hexdec($n)) { $data['codeToName'][$c] = $n; } $data['C'][$c] = $width; } elseif (isset($n)) { $data['C'][$n] = $width; } if (!isset($data['MissingWidth']) && $c === -1 && $n === '.notdef') { $data['MissingWidth'] = $width; } break; case 'KPX': break; // don't include them as they are not used yet //KPX Adieresis yacute -40 /*$bits = explode(' ', trim($row)); $data['KPX'][$bits[1]][$bits[2]] = $bits[3]; break;*/ } } } if ($this->compressionReady && $this->options['compression']) { // then implement ZLIB based compression on CIDtoGID string $data['CIDtoGID_Compressed'] = true; $cidtogid = gzcompress($cidtogid, 6); } $data['CIDtoGID'] = base64_encode($cidtogid); $data['_version_'] = $this->fontcacheVersion; $this->fonts[$font] = $data; //Because of potential trouble with php safe mode, expect that the folder already exists. //If not existing, this will hit performance because of missing cached results. if (is_dir($fontcache) && is_writable($fontcache)) { file_put_contents($fontcache . '/' . $cache_name, 'fonts[$font])) { $this->addMessage("openFont: no font file found for $font. Do you need to run load_font.php?"); } //pre_r($this->messages); } /** * if the font is not loaded then load it and make the required object * else just make it the current font * the encoding array can contain 'encoding'=> 'none','WinAnsiEncoding','MacRomanEncoding' or 'MacExpertEncoding' * note that encoding='none' will need to be used for symbolic fonts * and 'differences' => an array of mappings between numbers 0->255 and character names. * * @param $fontName * @param string $encoding * @param bool $set * @param bool $isSubsetting * @return int * @throws FontNotFoundException */ function selectFont($fontName, $encoding = '', $set = true, $isSubsetting = true) { if ($fontName === null || $fontName === '') { return $this->currentFontNum; } $ext = substr($fontName, -4); if ($ext === '.afm' || $ext === '.ufm') { $fontName = substr($fontName, 0, mb_strlen($fontName) - 4); } if (!isset($this->fonts[$fontName])) { $this->addMessage("selectFont: selecting - $fontName - $encoding, $set"); // load the file $this->openFont($fontName); if (isset($this->fonts[$fontName])) { $this->numObj++; $this->numFonts++; $font = &$this->fonts[$fontName]; $name = basename($fontName); $options = ['name' => $name, 'fontFileName' => $fontName, 'isSubsetting' => $isSubsetting]; if (is_array($encoding)) { // then encoding and differences might be set if (isset($encoding['encoding'])) { $options['encoding'] = $encoding['encoding']; } if (isset($encoding['differences'])) { $options['differences'] = $encoding['differences']; } } else { if (mb_strlen($encoding, '8bit')) { // then perhaps only the encoding has been set $options['encoding'] = $encoding; } } $this->o_font($this->numObj, 'new', $options); if (file_exists("$fontName.ttf")) { $fileSuffix = 'ttf'; } elseif (file_exists("$fontName.TTF")) { $fileSuffix = 'TTF'; } elseif (file_exists("$fontName.pfb")) { $fileSuffix = 'pfb'; } elseif (file_exists("$fontName.PFB")) { $fileSuffix = 'PFB'; } else { $fileSuffix = ''; } $font['fileSuffix'] = $fileSuffix; $font['fontNum'] = $this->numFonts; $font['isSubsetting'] = $isSubsetting && $font['isUnicode'] && strtolower($fileSuffix) === 'ttf'; // also set the differences here, note that this means that these will take effect only the //first time that a font is selected, else they are ignored if (isset($options['differences'])) { $font['differences'] = $options['differences']; } } } if ($set && isset($this->fonts[$fontName])) { // so if for some reason the font was not set in the last one then it will not be selected $this->currentBaseFont = $fontName; // the next lines mean that if a new font is selected, then the current text state will be // applied to it as well. $this->currentFont = $this->currentBaseFont; $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; } return $this->currentFontNum; } /** * sets up the current font, based on the font families, and the current text state * note that this system is quite flexible, a bold-italic font can be completely different to a * italic-bold font, and even bold-bold will have to be defined within the family to have meaning * This function is to be called whenever the currentTextState is changed, it will update * the currentFont setting to whatever the appropriate family one is. * If the user calls selectFont themselves then that will reset the currentBaseFont, and the currentFont * This function will change the currentFont to whatever it should be, but will not change the * currentBaseFont. */ private function setCurrentFont() { // if (strlen($this->currentBaseFont) == 0){ // // then assume an initial font // $this->selectFont($this->defaultFont); // } // $cf = substr($this->currentBaseFont,strrpos($this->currentBaseFont,'/')+1); // if (strlen($this->currentTextState) // && isset($this->fontFamilies[$cf]) // && isset($this->fontFamilies[$cf][$this->currentTextState])){ // // then we are in some state or another // // and this font has a family, and the current setting exists within it // // select the font, then return it // $nf = substr($this->currentBaseFont,0,strrpos($this->currentBaseFont,'/')+1).$this->fontFamilies[$cf][$this->currentTextState]; // $this->selectFont($nf,'',0); // $this->currentFont = $nf; // $this->currentFontNum = $this->fonts[$nf]['fontNum']; // } else { // // the this font must not have the right family member for the current state // // simply assume the base font $this->currentFont = $this->currentBaseFont; $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; // } } /** * function for the user to find out what the ID is of the first page that was created during * startup - useful if they wish to add something to it later. * * @return int */ function getFirstPageId() { return $this->firstPageId; } /** * add content to the currently active object * * @param $content */ private function addContent($content) { $this->objects[$this->currentContents]['c'] .= $content; } /** * sets the color for fill operations * * @param $color * @param bool $force */ function setColor($color, $force = false) { $new_color = [$color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null]; if (!$force && $this->currentColor == $new_color) { return; } if (isset($new_color[3])) { $this->currentColor = $new_color; $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F k", $this->currentColor)); } else { if (isset($new_color[2])) { $this->currentColor = $new_color; $this->addContent(vsprintf("\n%.3F %.3F %.3F rg", $this->currentColor)); } } } /** * sets the color for fill operations * * @param $fillRule */ function setFillRule($fillRule) { if (!in_array($fillRule, ["nonzero", "evenodd"])) { return; } $this->fillRule = $fillRule; } /** * sets the color for stroke operations * * @param $color * @param bool $force */ function setStrokeColor($color, $force = false) { $new_color = [$color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null]; if (!$force && $this->currentStrokeColor == $new_color) { return; } if (isset($new_color[3])) { $this->currentStrokeColor = $new_color; $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F K", $this->currentStrokeColor)); } else { if (isset($new_color[2])) { $this->currentStrokeColor = $new_color; $this->addContent(vsprintf("\n%.3F %.3F %.3F RG", $this->currentStrokeColor)); } } } /** * Set the graphics state for compositions * * @param $parameters */ function setGraphicsState($parameters) { // Create a new graphics state object if necessary if (($gstate = array_search($parameters, $this->gstates)) === false) { $this->numObj++; $this->o_extGState($this->numObj, 'new', $parameters); $gstate = $this->numStates; $this->gstates[$gstate] = $parameters; } $this->addContent("\n/GS$gstate gs"); } /** * Set current blend mode & opacity for lines. * * Valid blend modes are: * * Normal, Multiply, Screen, Overlay, Darken, Lighten, * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, * Exclusion * * @param string $mode the blend mode to use * @param float $opacity 0.0 fully transparent, 1.0 fully opaque */ function setLineTransparency($mode, $opacity) { static $blend_modes = [ "Normal", "Multiply", "Screen", "Overlay", "Darken", "Lighten", "ColorDogde", "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion" ]; if (!in_array($mode, $blend_modes)) { $mode = "Normal"; } if (is_null($this->currentLineTransparency)) { $this->currentLineTransparency = []; } if ($mode === (key_exists('mode', $this->currentLineTransparency) ? $this->currentLineTransparency['mode'] : '') && $opacity === (key_exists('opacity', $this->currentLineTransparency) ? $this->currentLineTransparency["opacity"] : '')) { return; } $this->currentLineTransparency["mode"] = $mode; $this->currentLineTransparency["opacity"] = $opacity; $options = [ "BM" => "/$mode", "CA" => (float)$opacity ]; $this->setGraphicsState($options); } /** * Set current blend mode & opacity for filled objects. * * Valid blend modes are: * * Normal, Multiply, Screen, Overlay, Darken, Lighten, * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, * Exclusion * * @param string $mode the blend mode to use * @param float $opacity 0.0 fully transparent, 1.0 fully opaque */ function setFillTransparency($mode, $opacity) { static $blend_modes = [ "Normal", "Multiply", "Screen", "Overlay", "Darken", "Lighten", "ColorDogde", "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion" ]; if (!in_array($mode, $blend_modes)) { $mode = "Normal"; } if (is_null($this->currentFillTransparency)) { $this->currentFillTransparency = []; } if ($mode === (key_exists('mode', $this->currentFillTransparency) ? $this->currentFillTransparency['mode'] : '') && $opacity === (key_exists('opacity', $this->currentFillTransparency) ? $this->currentFillTransparency["opacity"] : '')) { return; } $this->currentFillTransparency["mode"] = $mode; $this->currentFillTransparency["opacity"] = $opacity; $options = [ "BM" => "/$mode", "ca" => (float)$opacity, ]; $this->setGraphicsState($options); } /** * draw a line from one set of coordinates to another * * @param $x1 * @param $y1 * @param $x2 * @param $y2 * @param bool $stroke */ function line($x1, $y1, $x2, $y2, $stroke = true) { $this->addContent(sprintf("\n%.3F %.3F m %.3F %.3F l", $x1, $y1, $x2, $y2)); if ($stroke) { $this->addContent(' S'); } } /** * draw a bezier curve based on 4 control points * * @param $x0 * @param $y0 * @param $x1 * @param $y1 * @param $x2 * @param $y2 * @param $x3 * @param $y3 */ function curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) { // in the current line style, draw a bezier curve from (x0,y0) to (x3,y3) using the other two points // as the control points for the curve. $this->addContent( sprintf("\n%.3F %.3F m %.3F %.3F %.3F %.3F %.3F %.3F c S", $x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) ); } /** * draw a part of an ellipse * * @param $x0 * @param $y0 * @param $astart * @param $afinish * @param $r1 * @param int $r2 * @param int $angle * @param int $nSeg */ function partEllipse($x0, $y0, $astart, $afinish, $r1, $r2 = 0, $angle = 0, $nSeg = 8) { $this->ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, false); } /** * draw a filled ellipse * * @param $x0 * @param $y0 * @param $r1 * @param int $r2 * @param int $angle * @param int $nSeg * @param int $astart * @param int $afinish */ function filledEllipse($x0, $y0, $r1, $r2 = 0, $angle = 0, $nSeg = 8, $astart = 0, $afinish = 360) { $this->ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, true, true); } /** * @param $x * @param $y */ function lineTo($x, $y) { $this->addContent(sprintf("\n%.3F %.3F l", $x, $y)); } /** * @param $x * @param $y */ function moveTo($x, $y) { $this->addContent(sprintf("\n%.3F %.3F m", $x, $y)); } /** * draw a bezier curve based on 4 control points * * @param $x1 * @param $y1 * @param $x2 * @param $y2 * @param $x3 * @param $y3 */ function curveTo($x1, $y1, $x2, $y2, $x3, $y3) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F %.3F %.3F c", $x1, $y1, $x2, $y2, $x3, $y3)); } /** * draw a bezier curve based on 4 control points */ function quadTo($cpx, $cpy, $x, $y) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F v", $cpx, $cpy, $x, $y)); } function closePath() { $this->addContent(' h'); } function endPath() { $this->addContent(' n'); } /** * draw an ellipse * note that the part and filled ellipse are just special cases of this function * * draws an ellipse in the current line style * centered at $x0,$y0, radii $r1,$r2 * if $r2 is not set, then a circle is drawn * from $astart to $afinish, measured in degrees, running anti-clockwise from the right hand side of the ellipse. * nSeg is not allowed to be less than 2, as this will simply draw a line (and will even draw a * pretty crappy shape at 2, as we are approximating with bezier curves. * * @param $x0 * @param $y0 * @param $r1 * @param int $r2 * @param int $angle * @param int $nSeg * @param int $astart * @param int $afinish * @param bool $close * @param bool $fill * @param bool $stroke * @param bool $incomplete */ function ellipse( $x0, $y0, $r1, $r2 = 0, $angle = 0, $nSeg = 8, $astart = 0, $afinish = 360, $close = true, $fill = false, $stroke = true, $incomplete = false ) { if ($r1 == 0) { return; } if ($r2 == 0) { $r2 = $r1; } if ($nSeg < 2) { $nSeg = 2; } $astart = deg2rad((float)$astart); $afinish = deg2rad((float)$afinish); $totalAngle = $afinish - $astart; $dt = $totalAngle / $nSeg; $dtm = $dt / 3; if ($angle != 0) { $a = -1 * deg2rad((float)$angle); $this->addContent( sprintf("\n q %.3F %.3F %.3F %.3F %.3F %.3F cm", cos($a), -sin($a), sin($a), cos($a), $x0, $y0) ); $x0 = 0; $y0 = 0; } $t1 = $astart; $a0 = $x0 + $r1 * cos($t1); $b0 = $y0 + $r2 * sin($t1); $c0 = -$r1 * sin($t1); $d0 = $r2 * cos($t1); if (!$incomplete) { $this->addContent(sprintf("\n%.3F %.3F m ", $a0, $b0)); } for ($i = 1; $i <= $nSeg; $i++) { // draw this bit of the total curve $t1 = $i * $dt + $astart; $a1 = $x0 + $r1 * cos($t1); $b1 = $y0 + $r2 * sin($t1); $c1 = -$r1 * sin($t1); $d1 = $r2 * cos($t1); $this->addContent( sprintf( "\n%.3F %.3F %.3F %.3F %.3F %.3F c", ($a0 + $c0 * $dtm), ($b0 + $d0 * $dtm), ($a1 - $c1 * $dtm), ($b1 - $d1 * $dtm), $a1, $b1 ) ); $a0 = $a1; $b0 = $b1; $c0 = $c1; $d0 = $d1; } if (!$incomplete) { if ($fill) { $this->addContent(' f'); } if ($stroke) { if ($close) { $this->addContent(' s'); // small 's' signifies closing the path as well } else { $this->addContent(' S'); } } } if ($angle != 0) { $this->addContent(' Q'); } } /** * this sets the line drawing style. * width, is the thickness of the line in user units * cap is the type of cap to put on the line, values can be 'butt','round','square' * where the diffference between 'square' and 'butt' is that 'square' projects a flat end past the * end of the line. * join can be 'miter', 'round', 'bevel' * dash is an array which sets the dash pattern, is a series of length values, which are the lengths of the * on and off dashes. * (2) represents 2 on, 2 off, 2 on , 2 off ... * (2,1) is 2 on, 1 off, 2 on, 1 off.. etc * phase is a modifier on the dash pattern which is used to shift the point at which the pattern starts. * * @param int $width * @param string $cap * @param string $join * @param string $dash * @param int $phase */ function setLineStyle($width = 1, $cap = '', $join = '', $dash = '', $phase = 0) { // this is quite inefficient in that it sets all the parameters whenever 1 is changed, but will fix another day $string = ''; if ($width > 0) { $string .= "$width w"; } $ca = ['butt' => 0, 'round' => 1, 'square' => 2]; if (isset($ca[$cap])) { $string .= " $ca[$cap] J"; } $ja = ['miter' => 0, 'round' => 1, 'bevel' => 2]; if (isset($ja[$join])) { $string .= " $ja[$join] j"; } if (is_array($dash)) { $string .= ' [ ' . implode(' ', $dash) . " ] $phase d"; } $this->currentLineStyle = $string; $this->addContent("\n$string"); } /** * draw a polygon, the syntax for this is similar to the GD polygon command * * @param $p * @param $np * @param bool $f */ function polygon($p, $np, $f = false) { $this->addContent(sprintf("\n%.3F %.3F m ", $p[0], $p[1])); for ($i = 2; $i < $np * 2; $i = $i + 2) { $this->addContent(sprintf("%.3F %.3F l ", $p[$i], $p[$i + 1])); } if ($f) { $this->addContent(' f'); } else { $this->addContent(' S'); } } /** * a filled rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not * the coordinates of the upper-right corner * * @param $x1 * @param $y1 * @param $width * @param $height */ function filledRectangle($x1, $y1, $width, $height) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re f", $x1, $y1, $width, $height)); } /** * draw a rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not * the coordinates of the upper-right corner * * @param $x1 * @param $y1 * @param $width * @param $height */ function rectangle($x1, $y1, $width, $height) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re S", $x1, $y1, $width, $height)); } /** * draw a rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not * the coordinates of the upper-right corner * * @param $x1 * @param $y1 * @param $width * @param $height */ function rect($x1, $y1, $width, $height) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re", $x1, $y1, $width, $height)); } function stroke() { $this->addContent("\nS"); } function fill() { $this->addContent("\nf" . ($this->fillRule === "evenodd" ? "*" : "")); } function fillStroke() { $this->addContent("\nb" . ($this->fillRule === "evenodd" ? "*" : "")); } /** * @param string $subtype * @param integer $x * @param integer $y * @param integer $w * @param integer $h * @return int */ function addXObject($subtype, $x, $y, $w, $h) { $id = ++$this->numObj; $this->o_xobject($id, 'new', ['Subtype' => $subtype, 'bbox' => [$x, $y, $w, $h]]); return $id; } /** * @param integer $numXObject * @param string $type * @param array $options */ function setXObjectResource($numXObject, $type, $options) { if (in_array($type, ['procset', 'font', 'xObject'])) { $this->o_xobject($numXObject, $type, $options); } } /** * add signature * * $fieldSigId = $cpdf->addFormField(Cpdf::ACROFORM_FIELD_SIG, 'Signature1', 0, 0, 0, 0, 0); * * $signatureId = $cpdf->addSignature([ * 'signcert' => file_get_contents('dompdf.crt'), * 'privkey' => file_get_contents('dompdf.key'), * 'password' => 'password', * 'name' => 'DomPDF DEMO', * 'location' => 'Home', * 'reason' => 'First Form', * 'contactinfo' => 'info' * ]); * $cpdf->setFormFieldValue($fieldSigId, "$signatureId 0 R"); * * @param string $signcert * @param string $privkey * @param string $password * @param string|null $name * @param string|null $location * @param string|null $reason * @param string|null $contactinfo * @return int */ function addSignature($signcert, $privkey, $password = '', $name = null, $location = null, $reason = null, $contactinfo = null) { $sigId = ++$this->numObj; $this->o_sig($sigId, 'new', [ 'SignCert' => $signcert, 'PrivKey' => $privkey, 'Password' => $password, 'Name' => $name, 'Location' => $location, 'Reason' => $reason, 'ContactInfo' => $contactinfo ]); return $sigId; } /** * add field to form * * @param string $type ACROFORM_FIELD_* * @param string $name * @param $x0 * @param $y0 * @param $x1 * @param $y1 * @param integer $ff Field Flag ACROFORM_FIELD_*_* * @param float $size * @param array $color * @return int */ public function addFormField($type, $name, $x0, $y0, $x1, $y1, $ff = 0, $size = 10.0, $color = [0, 0, 0]) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $color = implode(' ', $color) . ' rg'; $currentFontNum = $this->currentFontNum; $font = array_filter($this->objects[$this->currentNode]['info']['fonts'], function($item) use ($currentFontNum) { return $item['fontNum'] == $currentFontNum; }); $this->o_acroform($this->acroFormId, 'font', ['objNum' => $font[0]['objNum'], 'fontNum' => $font[0]['fontNum']]); $fieldId = ++$this->numObj; $this->o_field($fieldId, 'new', [ 'rect' => [$x0, $y0, $x1, $y1], 'F' => 4, 'FT' => "/$type", 'T' => $name, 'Ff' => $ff, 'pageid' => $this->currentPage, 'da' => "$color /F$this->currentFontNum " . sprintf('%.1F Tf ', $size) ]); return $fieldId; } /** * set Field value * * @param integer $numFieldObj * @param string $value */ public function setFormFieldValue($numFieldObj, $value) { $this->o_field($numFieldObj, 'set', ['value' => $value]); } /** * set Field value (reference) * * @param integer $numFieldObj * @param integer $numObj Object number */ public function setFormFieldRefValue($numFieldObj, $numObj) { $this->o_field($numFieldObj, 'set', ['refvalue' => $numObj]); } /** * set Field Appearanc (reference) * * @param integer $numFieldObj * @param integer $normalNumObj * @param integer|null $rolloverNumObj * @param integer|null $downNumObj */ public function setFormFieldAppearance($numFieldObj, $normalNumObj, $rolloverNumObj = null, $downNumObj = null) { $appearance['N'] = $normalNumObj; if ($rolloverNumObj !== null) { $appearance['R'] = $rolloverNumObj; } if ($downNumObj !== null) { $appearance['D'] = $downNumObj; } $this->o_field($numFieldObj, 'set', ['appearance' => $appearance]); } /** * set Choice Field option values * * @param integer $numFieldObj * @param array $value */ public function setFormFieldOpt($numFieldObj, $value) { $this->o_field($numFieldObj, 'set', ['options' => $value]); } /** * add form to document * * @param integer $sigFlags * @param boolean $needAppearances */ public function addForm($sigFlags = 0, $needAppearances = false) { $this->acroFormId = ++$this->numObj; $this->o_acroform($this->acroFormId, 'new', [ 'NeedAppearances' => $needAppearances ? 'true' : 'false', 'SigFlags' => $sigFlags ]); } /** * save the current graphic state */ function save() { // we must reset the color cache or it will keep bad colors after clipping $this->currentColor = null; $this->currentStrokeColor = null; $this->addContent("\nq"); } /** * restore the last graphic state */ function restore() { // we must reset the color cache or it will keep bad colors after clipping $this->currentColor = null; $this->currentStrokeColor = null; $this->addContent("\nQ"); } /** * draw a clipping rectangle, all the elements added after this will be clipped * * @param $x1 * @param $y1 * @param $width * @param $height */ function clippingRectangle($x1, $y1, $width, $height) { $this->save(); $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re W n", $x1, $y1, $width, $height)); } /** * draw a clipping rounded rectangle, all the elements added after this will be clipped * * @param $x1 * @param $y1 * @param $w * @param $h * @param $rTL * @param $rTR * @param $rBR * @param $rBL */ function clippingRectangleRounded($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) { $this->save(); // start: top edge, left end $this->addContent(sprintf("\n%.3F %.3F m ", $x1, $y1 - $rTL + $h)); // line: bottom edge, left end $this->addContent(sprintf("\n%.3F %.3F l ", $x1, $y1 + $rBL)); // curve: bottom-left corner $this->ellipse($x1 + $rBL, $y1 + $rBL, $rBL, 0, 0, 8, 180, 270, false, false, false, true); // line: right edge, bottom end $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $w - $rBR, $y1)); // curve: bottom-right corner $this->ellipse($x1 + $w - $rBR, $y1 + $rBR, $rBR, 0, 0, 8, 270, 360, false, false, false, true); // line: right edge, top end $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $w, $y1 + $h - $rTR)); // curve: bottom-right corner $this->ellipse($x1 + $w - $rTR, $y1 + $h - $rTR, $rTR, 0, 0, 8, 0, 90, false, false, false, true); // line: bottom edge, right end $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $rTL, $y1 + $h)); // curve: top-right corner $this->ellipse($x1 + $rTL, $y1 + $h - $rTL, $rTL, 0, 0, 8, 90, 180, false, false, false, true); // line: top edge, left end $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $rBL, $y1)); // Close & clip $this->addContent(" W n"); } /** * ends the last clipping shape */ function clippingEnd() { $this->restore(); } /** * scale * * @param float $s_x scaling factor for width as percent * @param float $s_y scaling factor for height as percent * @param float $x Origin abscissa * @param float $y Origin ordinate */ function scale($s_x, $s_y, $x, $y) { $y = $this->currentPageSize["height"] - $y; $tm = [ $s_x, 0, 0, $s_y, $x * (1 - $s_x), $y * (1 - $s_y) ]; $this->transform($tm); } /** * translate * * @param float $t_x movement to the right * @param float $t_y movement to the bottom */ function translate($t_x, $t_y) { $tm = [ 1, 0, 0, 1, $t_x, -$t_y ]; $this->transform($tm); } /** * rotate * * @param float $angle angle in degrees for counter-clockwise rotation * @param float $x Origin abscissa * @param float $y Origin ordinate */ function rotate($angle, $x, $y) { $y = $this->currentPageSize["height"] - $y; $a = deg2rad($angle); $cos_a = cos($a); $sin_a = sin($a); $tm = [ $cos_a, -$sin_a, $sin_a, $cos_a, $x - $sin_a * $y - $cos_a * $x, $y - $cos_a * $y + $sin_a * $x, ]; $this->transform($tm); } /** * skew * * @param float $angle_x * @param float $angle_y * @param float $x Origin abscissa * @param float $y Origin ordinate */ function skew($angle_x, $angle_y, $x, $y) { $y = $this->currentPageSize["height"] - $y; $tan_x = tan(deg2rad($angle_x)); $tan_y = tan(deg2rad($angle_y)); $tm = [ 1, -$tan_y, -$tan_x, 1, $tan_x * $y, $tan_y * $x, ]; $this->transform($tm); } /** * apply graphic transformations * * @param array $tm transformation matrix */ function transform($tm) { $this->addContent(vsprintf("\n %.3F %.3F %.3F %.3F %.3F %.3F cm", $tm)); } /** * add a new page to the document * this also makes the new page the current active object * * @param int $insert * @param int $id * @param string $pos * @return int */ function newPage($insert = 0, $id = 0, $pos = 'after') { // if there is a state saved, then go up the stack closing them // then on the new page, re-open them with the right setings if ($this->nStateStack) { for ($i = $this->nStateStack; $i >= 1; $i--) { $this->restoreState($i); } } $this->numObj++; if ($insert) { // the id from the ezPdf class is the id of the contents of the page, not the page object itself // query that object to find the parent $rid = $this->objects[$id]['onPage']; $opt = ['rid' => $rid, 'pos' => $pos]; $this->o_page($this->numObj, 'new', $opt); } else { $this->o_page($this->numObj, 'new'); } // if there is a stack saved, then put that onto the page if ($this->nStateStack) { for ($i = 1; $i <= $this->nStateStack; $i++) { $this->saveState($i); } } // and if there has been a stroke or fill color set, then transfer them if (isset($this->currentColor)) { $this->setColor($this->currentColor, true); } if (isset($this->currentStrokeColor)) { $this->setStrokeColor($this->currentStrokeColor, true); } // if there is a line style set, then put this in too if (mb_strlen($this->currentLineStyle, '8bit')) { $this->addContent("\n$this->currentLineStyle"); } // the call to the o_page object set currentContents to the present page, so this can be returned as the page id return $this->currentContents; } /** * Streams the PDF to the client. * * @param string $filename The filename to present to the client. * @param array $options Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1). */ function stream($filename = "document.pdf", $options = []) { if (headers_sent()) { die("Unable to stream pdf: headers already sent"); } if (!isset($options["compress"])) $options["compress"] = true; if (!isset($options["Attachment"])) $options["Attachment"] = true; $debug = !$options['compress']; $tmp = ltrim($this->output($debug)); header("Cache-Control: private"); header("Content-Type: application/pdf"); header("Content-Length: " . mb_strlen($tmp, "8bit")); $filename = str_replace(["\n", "'"], "", basename($filename, ".pdf")) . ".pdf"; $attachment = $options["Attachment"] ? "attachment" : "inline"; $encoding = mb_detect_encoding($filename); $fallbackfilename = mb_convert_encoding($filename, "ISO-8859-1", $encoding); $fallbackfilename = str_replace("\"", "", $fallbackfilename); $encodedfilename = rawurlencode($filename); $contentDisposition = "Content-Disposition: $attachment; filename=\"$fallbackfilename\""; if ($fallbackfilename !== $filename) { $contentDisposition .= "; filename*=UTF-8''$encodedfilename"; } header($contentDisposition); echo $tmp; flush(); } /** * return the height in units of the current font in the given size * * @param $size * @return float|int */ function getFontHeight($size) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $font = $this->fonts[$this->currentFont]; // for the current font, and the given size, what is the height of the font in user units if (isset($font['Ascender']) && isset($font['Descender'])) { $h = $font['Ascender'] - $font['Descender']; } else { $h = $font['FontBBox'][3] - $font['FontBBox'][1]; } // have to adjust by a font offset for Windows fonts. unfortunately it looks like // the bounding box calculations are wrong and I don't know why. if (isset($font['FontHeightOffset'])) { // For CourierNew from Windows this needs to be -646 to match the // Adobe native Courier font. // // For FreeMono from GNU this needs to be -337 to match the // Courier font. // // Both have been added manually to the .afm and .ufm files. $h += (int)$font['FontHeightOffset']; } return $size * $h / 1000; } /** * @param $size * @return float|int */ function getFontXHeight($size) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $font = $this->fonts[$this->currentFont]; // for the current font, and the given size, what is the height of the font in user units if (isset($font['XHeight'])) { $xh = $font['Ascender'] - $font['Descender']; } else { $xh = $this->getFontHeight($size) / 2; } return $size * $xh / 1000; } /** * return the font descender, this will normally return a negative number * if you add this number to the baseline, you get the level of the bottom of the font * it is in the pdf user units * * @param $size * @return float|int */ function getFontDescender($size) { // note that this will most likely return a negative value if (!$this->numFonts) { $this->selectFont($this->defaultFont); } //$h = $this->fonts[$this->currentFont]['FontBBox'][1]; $h = $this->fonts[$this->currentFont]['Descender']; return $size * $h / 1000; } /** * filter the text, this is applied to all text just before being inserted into the pdf document * it escapes the various things that need to be escaped, and so on * * @access private * * @param $text * @param bool $bom * @param bool $convert_encoding * @return string */ function filterText($text, $bom = true, $convert_encoding = true) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } if ($convert_encoding) { $cf = $this->currentFont; if (isset($this->fonts[$cf]) && $this->fonts[$cf]['isUnicode']) { $text = $this->utf8toUtf16BE($text, $bom); } else { //$text = html_entity_decode($text, ENT_QUOTES); $text = mb_convert_encoding($text, self::$targetEncoding, 'UTF-8'); } } else if ($bom) { $text = $this->utf8toUtf16BE($text, $bom); } // the chr(13) substitution fixes a bug seen in TCPDF (bug #1421290) return strtr($text, [')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r']); } /** * return array containing codepoints (UTF-8 character values) for the * string passed in. * * based on the excellent TCPDF code by Nicola Asuni and the * RFC for UTF-8 at http://www.faqs.org/rfcs/rfc3629.html * * @access private * @author Orion Richardson * @since January 5, 2008 * * @param string $text UTF-8 string to process * * @return array UTF-8 codepoints array for the string */ function utf8toCodePointsArray(&$text) { $length = mb_strlen($text, '8bit'); // http://www.php.net/manual/en/function.mb-strlen.php#77040 $unicode = []; // array containing unicode values $bytes = []; // array containing single character byte sequences $numbytes = 1; // number of octets needed to represent the UTF-8 character for ($i = 0; $i < $length; $i++) { $c = ord($text[$i]); // get one string character at time if (count($bytes) === 0) { // get starting octect if ($c <= 0x7F) { $unicode[] = $c; // use the character "as is" because is ASCII $numbytes = 1; } elseif (($c >> 0x05) === 0x06) { // 2 bytes character (0x06 = 110 BIN) $bytes[] = ($c - 0xC0) << 0x06; $numbytes = 2; } elseif (($c >> 0x04) === 0x0E) { // 3 bytes character (0x0E = 1110 BIN) $bytes[] = ($c - 0xE0) << 0x0C; $numbytes = 3; } elseif (($c >> 0x03) === 0x1E) { // 4 bytes character (0x1E = 11110 BIN) $bytes[] = ($c - 0xF0) << 0x12; $numbytes = 4; } else { // use replacement character for other invalid sequences $unicode[] = 0xFFFD; $bytes = []; $numbytes = 1; } } elseif (($c >> 0x06) === 0x02) { // bytes 2, 3 and 4 must start with 0x02 = 10 BIN $bytes[] = $c - 0x80; if (count($bytes) === $numbytes) { // compose UTF-8 bytes to a single unicode value $c = $bytes[0]; for ($j = 1; $j < $numbytes; $j++) { $c += ($bytes[$j] << (($numbytes - $j - 1) * 0x06)); } if ((($c >= 0xD800) and ($c <= 0xDFFF)) or ($c >= 0x10FFFF)) { // The definition of UTF-8 prohibits encoding character numbers between // U+D800 and U+DFFF, which are reserved for use with the UTF-16 // encoding form (as surrogate pairs) and do not directly represent // characters. $unicode[] = 0xFFFD; // use replacement character } else { $unicode[] = $c; // add char to array } // reset data for next char $bytes = []; $numbytes = 1; } } else { // use replacement character for other invalid sequences $unicode[] = 0xFFFD; $bytes = []; $numbytes = 1; } } return $unicode; } /** * convert UTF-8 to UTF-16 with an additional byte order marker * at the front if required. * * based on the excellent TCPDF code by Nicola Asuni and the * RFC for UTF-8 at http://www.faqs.org/rfcs/rfc3629.html * * @access private * @author Orion Richardson * @since January 5, 2008 * * @param string $text UTF-8 string to process * @param boolean $bom whether to add the byte order marker * * @return string UTF-16 result string */ function utf8toUtf16BE(&$text, $bom = true) { $out = $bom ? "\xFE\xFF" : ''; $unicode = $this->utf8toCodePointsArray($text); foreach ($unicode as $c) { if ($c === 0xFFFD) { $out .= "\xFF\xFD"; // replacement character } elseif ($c < 0x10000) { $out .= chr($c >> 0x08) . chr($c & 0xFF); } else { $c -= 0x10000; $w1 = 0xD800 | ($c >> 0x10); $w2 = 0xDC00 | ($c & 0x3FF); $out .= chr($w1 >> 0x08) . chr($w1 & 0xFF) . chr($w2 >> 0x08) . chr($w2 & 0xFF); } } return $out; } /** * given a start position and information about how text is to be laid out, calculate where * on the page the text will end * * @param $x * @param $y * @param $angle * @param $size * @param $wa * @param $text * @return array */ private function getTextPosition($x, $y, $angle, $size, $wa, $text) { // given this information return an array containing x and y for the end position as elements 0 and 1 $w = $this->getTextWidth($size, $text); // need to adjust for the number of spaces in this text $words = explode(' ', $text); $nspaces = count($words) - 1; $w += $wa * $nspaces; $a = deg2rad((float)$angle); return [cos($a) * $w + $x, -sin($a) * $w + $y]; } /** * Callback method used by smallCaps * * @param array $matches * * @return string */ function toUpper($matches) { return mb_strtoupper($matches[0]); } function concatMatches($matches) { $str = ""; foreach ($matches as $match) { $str .= $match[0]; } return $str; } /** * register text for font subsetting * * @param $font * @param $text */ function registerText($font, $text) { if (!$this->isUnicode || in_array(mb_strtolower(basename($font)), self::$coreFonts)) { return; } if (!isset($this->stringSubsets[$font])) { $this->stringSubsets[$font] = []; } $this->stringSubsets[$font] = array_unique( array_merge($this->stringSubsets[$font], $this->utf8toCodePointsArray($text)) ); } /** * add text to the document, at a specified location, size and angle on the page * * @param $x * @param $y * @param $size * @param $text * @param int $angle * @param int $wordSpaceAdjust * @param int $charSpaceAdjust * @param bool $smallCaps */ function addText($x, $y, $size, $text, $angle = 0, $wordSpaceAdjust = 0, $charSpaceAdjust = 0, $smallCaps = false) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $text = str_replace(["\r", "\n"], "", $text); // if ($smallCaps) { // preg_match_all("/(\P{Ll}+)/u", $text, $matches, PREG_SET_ORDER); // $lower = $this->concatMatches($matches); // d($lower); // preg_match_all("/(\p{Ll}+)/u", $text, $matches, PREG_SET_ORDER); // $other = $this->concatMatches($matches); // d($other); // $text = preg_replace_callback("/\p{Ll}/u", array($this, "toUpper"), $text); // } // if there are any open callbacks, then they should be called, to show the start of the line if ($this->nCallback > 0) { for ($i = $this->nCallback; $i > 0; $i--) { // call each function $info = [ 'x' => $x, 'y' => $y, 'angle' => $angle, 'status' => 'sol', 'p' => $this->callback[$i]['p'], 'nCallback' => $this->callback[$i]['nCallback'], 'height' => $this->callback[$i]['height'], 'descender' => $this->callback[$i]['descender'] ]; $func = $this->callback[$i]['f']; $this->$func($info); } } if ($angle == 0) { $this->addContent(sprintf("\nBT %.3F %.3F Td", $x, $y)); } else { $a = deg2rad((float)$angle); $this->addContent( sprintf("\nBT %.3F %.3F %.3F %.3F %.3F %.3F Tm", cos($a), -sin($a), sin($a), cos($a), $x, $y) ); } if ($wordSpaceAdjust != 0) { $this->addContent(sprintf(" %.3F Tw", $wordSpaceAdjust)); } if ($charSpaceAdjust != 0) { $this->addContent(sprintf(" %.3F Tc", $charSpaceAdjust)); } $len = mb_strlen($text); $start = 0; if ($start < $len) { $part = $text; // OAR - Don't need this anymore, given that $start always equals zero. substr($text, $start); $place_text = $this->filterText($part, false); // modify unicode text so that extra word spacing is manually implemented (bug #) if ($this->fonts[$this->currentFont]['isUnicode'] && $wordSpaceAdjust != 0) { $space_scale = 1000 / $size; $place_text = str_replace("\x00\x20", "\x00\x20)\x00\x20" . (-round($space_scale * $wordSpaceAdjust)) . "\x00\x20(", $place_text); } $this->addContent(" /F$this->currentFontNum " . sprintf('%.1F Tf ', $size)); $this->addContent(" [($place_text)] TJ"); } if ($wordSpaceAdjust != 0) { $this->addContent(sprintf(" %.3F Tw", 0)); } if ($charSpaceAdjust != 0) { $this->addContent(sprintf(" %.3F Tc", 0)); } $this->addContent(' ET'); // if there are any open callbacks, then they should be called, to show the end of the line if ($this->nCallback > 0) { for ($i = $this->nCallback; $i > 0; $i--) { // call each function $tmp = $this->getTextPosition($x, $y, $angle, $size, $wordSpaceAdjust, $text); $info = [ 'x' => $tmp[0], 'y' => $tmp[1], 'angle' => $angle, 'status' => 'eol', 'p' => $this->callback[$i]['p'], 'nCallback' => $this->callback[$i]['nCallback'], 'height' => $this->callback[$i]['height'], 'descender' => $this->callback[$i]['descender'] ]; $func = $this->callback[$i]['f']; $this->$func($info); } } if ($this->fonts[$this->currentFont]['isSubsetting']) { $this->registerText($this->currentFont, $text); } } /** * calculate how wide a given text string will be on a page, at a given size. * this can be called externally, but is also used by the other class functions * * @param float $size * @param string $text * @param float $word_spacing * @param float $char_spacing * @return float */ function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0) { static $ord_cache = []; // this function should not change any of the settings, though it will need to // track any directives which change during calculation, so copy them at the start // and put them back at the end. $store_currentTextState = $this->currentTextState; if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $text = str_replace(["\r", "\n"], "", $text); // converts a number or a float to a string so it can get the width $text = "$text"; // hmm, this is where it all starts to get tricky - use the font information to // calculate the width of each character, add them up and convert to user units $w = 0; $cf = $this->currentFont; $current_font = $this->fonts[$cf]; $space_scale = 1000 / ($size > 0 ? $size : 1); if ($current_font['isUnicode']) { // for Unicode, use the code points array to calculate width rather // than just the string itself $unicode = $this->utf8toCodePointsArray($text); foreach ($unicode as $char) { // check if we have to replace character if (isset($current_font['differences'][$char])) { $char = $current_font['differences'][$char]; } if (isset($current_font['C'][$char])) { $char_width = $current_font['C'][$char]; // add the character width $w += $char_width; // add additional padding for space if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space $w += $word_spacing * $space_scale; } } } // add additional char spacing if ($char_spacing != 0) { $w += $char_spacing * $space_scale * count($unicode); } } else { // If CPDF is in Unicode mode but the current font does not support Unicode we need to convert the character set to Windows-1252 if ($this->isUnicode) { $text = mb_convert_encoding($text, 'Windows-1252', 'UTF-8'); } $len = mb_strlen($text, 'Windows-1252'); for ($i = 0; $i < $len; $i++) { $c = $text[$i]; $char = isset($ord_cache[$c]) ? $ord_cache[$c] : ($ord_cache[$c] = ord($c)); // check if we have to replace character if (isset($current_font['differences'][$char])) { $char = $current_font['differences'][$char]; } if (isset($current_font['C'][$char])) { $char_width = $current_font['C'][$char]; // add the character width $w += $char_width; // add additional padding for space if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space $w += $word_spacing * $space_scale; } } } // add additional char spacing if ($char_spacing != 0) { $w += $char_spacing * $space_scale * $len; } } $this->currentTextState = $store_currentTextState; $this->setCurrentFont(); return $w * $size / 1000; } /** * this will be called at a new page to return the state to what it was on the * end of the previous page, before the stack was closed down * This is to get around not being able to have open 'q' across pages * * @param int $pageEnd */ function saveState($pageEnd = 0) { if ($pageEnd) { // this will be called at a new page to return the state to what it was on the // end of the previous page, before the stack was closed down // This is to get around not being able to have open 'q' across pages $opt = $this->stateStack[$pageEnd]; // ok to use this as stack starts numbering at 1 $this->setColor($opt['col'], true); $this->setStrokeColor($opt['str'], true); $this->addContent("\n" . $opt['lin']); // $this->currentLineStyle = $opt['lin']; } else { $this->nStateStack++; $this->stateStack[$this->nStateStack] = [ 'col' => $this->currentColor, 'str' => $this->currentStrokeColor, 'lin' => $this->currentLineStyle ]; } $this->save(); } /** * restore a previously saved state * * @param int $pageEnd */ function restoreState($pageEnd = 0) { if (!$pageEnd) { $n = $this->nStateStack; $this->currentColor = $this->stateStack[$n]['col']; $this->currentStrokeColor = $this->stateStack[$n]['str']; $this->addContent("\n" . $this->stateStack[$n]['lin']); $this->currentLineStyle = $this->stateStack[$n]['lin']; $this->stateStack[$n] = null; unset($this->stateStack[$n]); $this->nStateStack--; } $this->restore(); } /** * make a loose object, the output will go into this object, until it is closed, then will revert to * the current one. * this object will not appear until it is included within a page. * the function will return the object number * * @return int */ function openObject() { $this->nStack++; $this->stack[$this->nStack] = ['c' => $this->currentContents, 'p' => $this->currentPage]; // add a new object of the content type, to hold the data flow $this->numObj++; $this->o_contents($this->numObj, 'new'); $this->currentContents = $this->numObj; $this->looseObjects[$this->numObj] = 1; return $this->numObj; } /** * open an existing object for editing * * @param $id */ function reopenObject($id) { $this->nStack++; $this->stack[$this->nStack] = ['c' => $this->currentContents, 'p' => $this->currentPage]; $this->currentContents = $id; // also if this object is the primary contents for a page, then set the current page to its parent if (isset($this->objects[$id]['onPage'])) { $this->currentPage = $this->objects[$id]['onPage']; } } /** * close an object */ function closeObject() { // close the object, as long as there was one open in the first place, which will be indicated by // an objectId on the stack. if ($this->nStack > 0) { $this->currentContents = $this->stack[$this->nStack]['c']; $this->currentPage = $this->stack[$this->nStack]['p']; $this->nStack--; // easier to probably not worry about removing the old entries, they will be overwritten // if there are new ones. } } /** * stop an object from appearing on pages from this point on * * @param $id */ function stopObject($id) { // if an object has been appearing on pages up to now, then stop it, this page will // be the last one that could contain it. if (isset($this->addLooseObjects[$id])) { $this->addLooseObjects[$id] = ''; } } /** * after an object has been created, it wil only show if it has been added, using this function. * * @param $id * @param string $options */ function addObject($id, $options = 'add') { // add the specified object to the page if (isset($this->looseObjects[$id]) && $this->currentContents != $id) { // then it is a valid object, and it is not being added to itself switch ($options) { case 'all': // then this object is to be added to this page (done in the next block) and // all future new pages. $this->addLooseObjects[$id] = 'all'; case 'add': if (isset($this->objects[$this->currentContents]['onPage'])) { // then the destination contents is the primary for the page // (though this object is actually added to that page) $this->o_page($this->objects[$this->currentContents]['onPage'], 'content', $id); } break; case 'even': $this->addLooseObjects[$id] = 'even'; $pageObjectId = $this->objects[$this->currentContents]['onPage']; if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 0) { $this->addObject($id); // hacky huh :) } break; case 'odd': $this->addLooseObjects[$id] = 'odd'; $pageObjectId = $this->objects[$this->currentContents]['onPage']; if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 1) { $this->addObject($id); // hacky huh :) } break; case 'next': $this->addLooseObjects[$id] = 'all'; break; case 'nexteven': $this->addLooseObjects[$id] = 'even'; break; case 'nextodd': $this->addLooseObjects[$id] = 'odd'; break; } } } /** * return a storable representation of a specific object * * @param $id * @return string|null */ function serializeObject($id) { if (array_key_exists($id, $this->objects)) { return serialize($this->objects[$id]); } return null; } /** * restore an object from its stored representation. Returns its new object id. * * @param $obj * @return int */ function restoreSerializedObject($obj) { $obj_id = $this->openObject(); $this->objects[$obj_id] = unserialize($obj); $this->closeObject(); return $obj_id; } /** * Embeds a file inside the PDF * * @param string $filepath path to the file to store inside the PDF * @param string $embeddedFilename the filename displayed in the list of embedded files * @param string $description a description in the list of embedded files */ public function addEmbeddedFile(string $filepath, string $embeddedFilename, string $description): void { $this->numObj++; $this->o_embedded_file_dictionary( $this->numObj, 'new', [ 'filepath' => $filepath, 'filename' => $embeddedFilename, 'description' => $description ] ); } /** * add content to the documents info object * * @param $label * @param int $value */ function addInfo($label, $value = 0) { // this will only work if the label is one of the valid ones. // modify this so that arrays can be passed as well. // if $label is an array then assume that it is key => value pairs // else assume that they are both scalar, anything else will probably error if (is_array($label)) { foreach ($label as $l => $v) { $this->o_info($this->infoObject, $l, $v); } } else { $this->o_info($this->infoObject, $label, $value); } } /** * set the viewer preferences of the document, it is up to the browser to obey these. * * @param $label * @param int $value */ function setPreferences($label, $value = 0) { // this will only work if the label is one of the valid ones. if (is_array($label)) { foreach ($label as $l => $v) { $this->o_catalog($this->catalogId, 'viewerPreferences', [$l => $v]); } } else { $this->o_catalog($this->catalogId, 'viewerPreferences', [$label => $value]); } } /** * extract an integer from a position in a byte stream * * @param $data * @param $pos * @param $num * @return int */ private function getBytes(&$data, $pos, $num) { // return the integer represented by $num bytes from $pos within $data $ret = 0; for ($i = 0; $i < $num; $i++) { $ret *= 256; $ret += ord($data[$pos + $i]); } return $ret; } /** * Check if image already added to pdf image directory. * If yes, need not to create again (pass empty data) * * @param string $imgname * @return bool */ function image_iscached($imgname) { return isset($this->imagelist[$imgname]); } /** * add a PNG image into the document, from a GD object * this should work with remote files * * @param \GdImage|resource $img A GD resource * @param string $file The PNG file * @param float $x X position * @param float $y Y position * @param float $w Width * @param float $h Height * @param bool $is_mask true if the image is a mask * @param bool $mask true if the image is masked * @throws Exception */ function addImagePng(&$img, $file, $x, $y, $w = 0.0, $h = 0.0, $is_mask = false, $mask = null) { if (!function_exists("imagepng")) { throw new \Exception("The PHP GD extension is required, but is not installed."); } //if already cached, need not to read again if (isset($this->imagelist[$file])) { $data = null; } else { // Example for transparency handling on new image. Retain for current image // $tIndex = imagecolortransparent($img); // if ($tIndex > 0) { // $tColor = imagecolorsforindex($img, $tIndex); // $new_tIndex = imagecolorallocate($new_img, $tColor['red'], $tColor['green'], $tColor['blue']); // imagefill($new_img, 0, 0, $new_tIndex); // imagecolortransparent($new_img, $new_tIndex); // } // blending mode (literal/blending) on drawing into current image. not relevant when not saved or not drawn //imagealphablending($img, true); //default, but explicitely set to ensure pdf compatibility imagesavealpha($img, false/*!$is_mask && !$mask*/); $error = 0; //DEBUG_IMG_TEMP //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addImagePng ' . $file . ']'; } ob_start(); @imagepng($img); $data = ob_get_clean(); if ($data == '') { $error = 1; $errormsg = 'trouble writing file from GD'; //DEBUG_IMG_TEMP //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print 'trouble writing file from GD'; } } if ($error) { $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); return; } } //End isset($this->imagelist[$file]) (png Duplicate removal) $this->addPngFromBuf($data, $file, $x, $y, $w, $h, $is_mask, $mask); } /** * @param $file * @param $x * @param $y * @param $w * @param $h * @param $byte */ protected function addImagePngAlpha($file, $x, $y, $w, $h, $byte) { // generate images $img = imagecreatefrompng($file); if ($img === false) { return; } // FIXME The pixel transformation doesn't work well with 8bit PNGs $eight_bit = ($byte & 4) !== 4; $wpx = imagesx($img); $hpx = imagesy($img); imagesavealpha($img, false); // create temp alpha file $tempfile_alpha = @tempnam($this->tmp, "cpdf_img_"); @unlink($tempfile_alpha); $tempfile_alpha = "$tempfile_alpha.png"; // create temp plain file $tempfile_plain = @tempnam($this->tmp, "cpdf_img_"); @unlink($tempfile_plain); $tempfile_plain = "$tempfile_plain.png"; $imgalpha = imagecreate($wpx, $hpx); imagesavealpha($imgalpha, false); // generate gray scale palette (0 -> 255) for ($c = 0; $c < 256; ++$c) { imagecolorallocate($imgalpha, $c, $c, $c); } // Use PECL gmagick + Graphics Magic to process transparent PNG images if (extension_loaded("gmagick")) { $gmagick = new \Gmagick($file); $gmagick->setimageformat('png'); // Get opacity channel (negative of alpha channel) $alpha_channel_neg = clone $gmagick; $alpha_channel_neg->separateimagechannel(\Gmagick::CHANNEL_OPACITY); // Negate opacity channel $alpha_channel = new \Gmagick(); $alpha_channel->newimage($wpx, $hpx, "#FFFFFF", "png"); $alpha_channel->compositeimage($alpha_channel_neg, \Gmagick::COMPOSITE_DIFFERENCE, 0, 0); $alpha_channel->separateimagechannel(\Gmagick::CHANNEL_RED); $alpha_channel->writeimage($tempfile_alpha); // Cast to 8bit+palette $imgalpha_ = imagecreatefrompng($tempfile_alpha); imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); imagedestroy($imgalpha_); imagepng($imgalpha, $tempfile_alpha); // Make opaque image $color_channels = new \Gmagick(); $color_channels->newimage($wpx, $hpx, "#FFFFFF", "png"); $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYRED, 0, 0); $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYGREEN, 0, 0); $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYBLUE, 0, 0); $color_channels->writeimage($tempfile_plain); $imgplain = imagecreatefrompng($tempfile_plain); } // Use PECL imagick + ImageMagic to process transparent PNG images elseif (extension_loaded("imagick")) { // Native cloning was added to pecl-imagick in svn commit 263814 // the first version containing it was 3.0.1RC1 static $imagickClonable = null; if ($imagickClonable === null) { $imagickClonable = true; if (defined('Imagick::IMAGICK_EXTVER')) { $imagickVersion = \Imagick::IMAGICK_EXTVER; } else { $imagickVersion = '0'; } if (version_compare($imagickVersion, '0.0.1', '>=')) { $imagickClonable = version_compare($imagickVersion, '3.0.1rc1', '>='); } } $imagick = new \Imagick($file); $imagick->setFormat('png'); // Get opacity channel (negative of alpha channel) if ($imagick->getImageAlphaChannel() !== 0) { $alpha_channel = $imagickClonable ? clone $imagick : $imagick->clone(); $alpha_channel->separateImageChannel(\Imagick::CHANNEL_ALPHA); // Since ImageMagick7 negate invert transparency as default if (\Imagick::getVersion()['versionNumber'] < 1800) { $alpha_channel->negateImage(true); } $alpha_channel->writeImage($tempfile_alpha); // Cast to 8bit+palette $imgalpha_ = imagecreatefrompng($tempfile_alpha); imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); imagedestroy($imgalpha_); imagepng($imgalpha, $tempfile_alpha); } else { $tempfile_alpha = null; } // Make opaque image $color_channels = new \Imagick(); $color_channels->newImage($wpx, $hpx, "#FFFFFF", "png"); $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYRED, 0, 0); $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYGREEN, 0, 0); $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYBLUE, 0, 0); $color_channels->writeImage($tempfile_plain); $imgplain = imagecreatefrompng($tempfile_plain); } else { // allocated colors cache $allocated_colors = []; // extract alpha channel for ($xpx = 0; $xpx < $wpx; ++$xpx) { for ($ypx = 0; $ypx < $hpx; ++$ypx) { $color = imagecolorat($img, $xpx, $ypx); $col = imagecolorsforindex($img, $color); $alpha = $col['alpha']; if ($eight_bit) { // with gamma correction $gammacorr = 2.2; $pixel = round(pow((((127 - $alpha) * 255 / 127) / 255), $gammacorr) * 255); } else { // without gamma correction $pixel = (127 - $alpha) * 2; $key = $col['red'] . $col['green'] . $col['blue']; if (!isset($allocated_colors[$key])) { $pixel_img = imagecolorallocate($img, $col['red'], $col['green'], $col['blue']); $allocated_colors[$key] = $pixel_img; } else { $pixel_img = $allocated_colors[$key]; } imagesetpixel($img, $xpx, $ypx, $pixel_img); } imagesetpixel($imgalpha, $xpx, $ypx, $pixel); } } // extract image without alpha channel $imgplain = imagecreatetruecolor($wpx, $hpx); imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx); imagedestroy($img); imagepng($imgalpha, $tempfile_alpha); imagepng($imgplain, $tempfile_plain); } $this->imageAlphaList[$file] = [$tempfile_alpha, $tempfile_plain]; // embed mask image if ($tempfile_alpha) { $this->addImagePng($imgalpha, $tempfile_alpha, $x, $y, $w, $h, true); imagedestroy($imgalpha); $this->imageCache[] = $tempfile_alpha; } // embed image, masked with previously embedded mask $this->addImagePng($imgplain, $tempfile_plain, $x, $y, $w, $h, false, ($tempfile_alpha !== null)); imagedestroy($imgplain); $this->imageCache[] = $tempfile_plain; } /** * add a PNG image into the document, from a file * this should work with remote files * * @param $file * @param $x * @param $y * @param int $w * @param int $h * @throws Exception */ function addPngFromFile($file, $x, $y, $w = 0, $h = 0) { if (!function_exists("imagecreatefrompng")) { throw new \Exception("The PHP GD extension is required, but is not installed."); } if (isset($this->imageAlphaList[$file])) { [$alphaFile, $plainFile] = $this->imageAlphaList[$file]; if ($alphaFile) { $img = null; $this->addImagePng($img, $alphaFile, $x, $y, $w, $h, true); } $img = null; $this->addImagePng($img, $plainFile, $x, $y, $w, $h, false, ($plainFile !== null)); return; } //if already cached, need not to read again if (isset($this->imagelist[$file])) { $img = null; } else { $info = file_get_contents($file, false, null, 24, 5); $meta = unpack("CbitDepth/CcolorType/CcompressionMethod/CfilterMethod/CinterlaceMethod", $info); $bit_depth = $meta["bitDepth"]; $color_type = $meta["colorType"]; // http://www.w3.org/TR/PNG/#11IHDR // 3 => indexed // 4 => greyscale with alpha // 6 => fullcolor with alpha $is_alpha = in_array($color_type, [4, 6]) || ($color_type == 3 && $bit_depth != 4); if ($is_alpha) { // exclude grayscale alpha $this->addImagePngAlpha($file, $x, $y, $w, $h, $color_type); return; } //png files typically contain an alpha channel. //pdf file format or class.pdf does not support alpha blending. //on alpha blended images, more transparent areas have a color near black. //This appears in the result on not storing the alpha channel. //Correct would be the box background image or its parent when transparent. //But this would make the image dependent on the background. //Therefore create an image with white background and copy in //A more natural background than black is white. //Therefore create an empty image with white background and merge the //image in with alpha blending. $imgtmp = @imagecreatefrompng($file); if (!$imgtmp) { return; } $sx = imagesx($imgtmp); $sy = imagesy($imgtmp); $img = imagecreatetruecolor($sx, $sy); imagealphablending($img, true); // @todo is it still needed ?? $ti = imagecolortransparent($imgtmp); if ($ti >= 0) { $tc = imagecolorsforindex($imgtmp, $ti); $ti = imagecolorallocate($img, $tc['red'], $tc['green'], $tc['blue']); imagefill($img, 0, 0, $ti); imagecolortransparent($img, $ti); } else { imagefill($img, 1, 1, imagecolorallocate($img, 255, 255, 255)); } imagecopy($img, $imgtmp, 0, 0, 0, 0, $sx, $sy); imagedestroy($imgtmp); } $this->addImagePng($img, $file, $x, $y, $w, $h); if ($img) { imagedestroy($img); } } /** * add a PNG image into the document, from a memory buffer of the file * * @param $data * @param $file * @param $x * @param $y * @param float $w * @param float $h * @param bool $is_mask * @param null $mask */ function addPngFromBuf(&$data, $file, $x, $y, $w = 0.0, $h = 0.0, $is_mask = false, $mask = null) { if (isset($this->imagelist[$file])) { $data = null; $info['width'] = $this->imagelist[$file]['w']; $info['height'] = $this->imagelist[$file]['h']; $label = $this->imagelist[$file]['label']; } else { if ($data == null) { $this->addMessage('addPngFromBuf error - data not present!'); return; } $error = 0; if (!$error) { $header = chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10); if (mb_substr($data, 0, 8, '8bit') != $header) { $error = 1; if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile this file does not have a valid header ' . $file . ']'; } $errormsg = 'this file does not have a valid header'; } } if (!$error) { // set pointer $p = 8; $len = mb_strlen($data, '8bit'); // cycle through the file, identifying chunks $haveHeader = 0; $info = []; $idata = ''; $pdata = ''; while ($p < $len) { $chunkLen = $this->getBytes($data, $p, 4); $chunkType = mb_substr($data, $p + 4, 4, '8bit'); switch ($chunkType) { case 'IHDR': // this is where all the file information comes from $info['width'] = $this->getBytes($data, $p + 8, 4); $info['height'] = $this->getBytes($data, $p + 12, 4); $info['bitDepth'] = ord($data[$p + 16]); $info['colorType'] = ord($data[$p + 17]); $info['compressionMethod'] = ord($data[$p + 18]); $info['filterMethod'] = ord($data[$p + 19]); $info['interlaceMethod'] = ord($data[$p + 20]); //print_r($info); $haveHeader = 1; if ($info['compressionMethod'] != 0) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile unsupported compression method ' . $file . ']'; } $errormsg = 'unsupported compression method'; } if ($info['filterMethod'] != 0) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile unsupported filter method ' . $file . ']'; } $errormsg = 'unsupported filter method'; } break; case 'PLTE': $pdata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); break; case 'IDAT': $idata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); break; case 'tRNS': //this chunk can only occur once and it must occur after the PLTE chunk and before IDAT chunk //print "tRNS found, color type = ".$info['colorType']."\n"; $transparency = []; switch ($info['colorType']) { // indexed color, rbg case 3: /* corresponding to entries in the plte chunk Alpha for palette index 0: 1 byte Alpha for palette index 1: 1 byte ...etc... */ // there will be one entry for each palette entry. up until the last non-opaque entry. // set up an array, stretching over all palette entries which will be o (opaque) or 1 (transparent) $transparency['type'] = 'indexed'; $trans = 0; for ($i = $chunkLen; $i >= 0; $i--) { if (ord($data[$p + 8 + $i]) == 0) { $trans = $i; } } $transparency['data'] = $trans; break; // grayscale case 0: /* corresponding to entries in the plte chunk Gray: 2 bytes, range 0 .. (2^bitdepth)-1 */ // $transparency['grayscale'] = $this->PRVT_getBytes($data,$p+8,2); // g = grayscale $transparency['type'] = 'indexed'; $transparency['data'] = ord($data[$p + 8 + 1]); break; // truecolor case 2: /* corresponding to entries in the plte chunk Red: 2 bytes, range 0 .. (2^bitdepth)-1 Green: 2 bytes, range 0 .. (2^bitdepth)-1 Blue: 2 bytes, range 0 .. (2^bitdepth)-1 */ $transparency['r'] = $this->getBytes($data, $p + 8, 2); // r from truecolor $transparency['g'] = $this->getBytes($data, $p + 10, 2); // g from truecolor $transparency['b'] = $this->getBytes($data, $p + 12, 2); // b from truecolor $transparency['type'] = 'color-key'; break; //unsupported transparency type default: if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile unsupported transparency type ' . $file . ']'; } break; } // KS End new code break; default: break; } $p += $chunkLen + 12; } if (!$haveHeader) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile information header is missing ' . $file . ']'; } $errormsg = 'information header is missing'; } if (isset($info['interlaceMethod']) && $info['interlaceMethod']) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile no support for interlaced images in pdf ' . $file . ']'; } $errormsg = 'There appears to be no support for interlaced images in pdf.'; } } if (!$error && $info['bitDepth'] > 8) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile bit depth of 8 or less is supported ' . $file . ']'; } $errormsg = 'only bit depth of 8 or less is supported'; } if (!$error) { switch ($info['colorType']) { case 3: $color = 'DeviceRGB'; $ncolor = 1; break; case 2: $color = 'DeviceRGB'; $ncolor = 3; break; case 0: $color = 'DeviceGray'; $ncolor = 1; break; default: $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile alpha channel not supported: ' . $info['colorType'] . ' ' . $file . ']'; } $errormsg = 'transparency alpha channel not supported, transparency only supported for palette images.'; } } if ($error) { $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); return; } //print_r($info); // so this image is ok... add it in. $this->numImages++; $im = $this->numImages; $label = "I$im"; $this->numObj++; // $this->o_image($this->numObj,'new',array('label' => $label,'data' => $idata,'iw' => $w,'ih' => $h,'type' => 'png','ic' => $info['width'])); $options = [ 'label' => $label, 'data' => $idata, 'bitsPerComponent' => $info['bitDepth'], 'pdata' => $pdata, 'iw' => $info['width'], 'ih' => $info['height'], 'type' => 'png', 'color' => $color, 'ncolor' => $ncolor, 'masked' => $mask, 'isMask' => $is_mask ]; if (isset($transparency)) { $options['transparency'] = $transparency; } $this->o_image($this->numObj, 'new', $options); $this->imagelist[$file] = ['label' => $label, 'w' => $info['width'], 'h' => $info['height']]; } if ($is_mask) { return; } if ($w <= 0 && $h <= 0) { $w = $info['width']; $h = $info['height']; } if ($w <= 0) { $w = $h / $info['height'] * $info['width']; } if ($h <= 0) { $h = $w * $info['height'] / $info['width']; } $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ", $w, $h, $x, $y, $label)); } /** * add a JPEG image into the document, from a file * * @param $img * @param $x * @param $y * @param int $w * @param int $h */ function addJpegFromFile($img, $x, $y, $w = 0, $h = 0) { // attempt to add a jpeg image straight from a file, using no GD commands // note that this function is unable to operate on a remote file. if (!file_exists($img)) { return; } if ($this->image_iscached($img)) { $data = null; $imageWidth = $this->imagelist[$img]['w']; $imageHeight = $this->imagelist[$img]['h']; $channels = $this->imagelist[$img]['c']; } else { $tmp = getimagesize($img); $imageWidth = $tmp[0]; $imageHeight = $tmp[1]; if (isset($tmp['channels'])) { $channels = $tmp['channels']; } else { $channels = 3; } $data = file_get_contents($img); } if ($w <= 0 && $h <= 0) { $w = $imageWidth; } if ($w == 0) { $w = $h / $imageHeight * $imageWidth; } if ($h == 0) { $h = $w * $imageHeight / $imageWidth; } $this->addJpegImage_common($data, $img, $imageWidth, $imageHeight, $x, $y, $w, $h, $channels); } /** * common code used by the two JPEG adding functions * @param $data * @param $imgname * @param $imageWidth * @param $imageHeight * @param $x * @param $y * @param int $w * @param int $h * @param int $channels */ private function addJpegImage_common( &$data, $imgname, $imageWidth, $imageHeight, $x, $y, $w = 0, $h = 0, $channels = 3 ) { if ($this->image_iscached($imgname)) { $label = $this->imagelist[$imgname]['label']; //debugpng //if (DEBUGPNG) print '[addJpegImage_common Duplicate '.$imgname.']'; } else { if ($data == null) { $this->addMessage('addJpegImage_common error - (' . $imgname . ') data not present!'); return; } // note that this function is not to be called externally // it is just the common code between the GD and the file options $this->numImages++; $im = $this->numImages; $label = "I$im"; $this->numObj++; $this->o_image( $this->numObj, 'new', [ 'label' => $label, 'data' => &$data, 'iw' => $imageWidth, 'ih' => $imageHeight, 'channels' => $channels ] ); $this->imagelist[$imgname] = [ 'label' => $label, 'w' => $imageWidth, 'h' => $imageHeight, 'c' => $channels ]; } $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ ", $w, $h, $x, $y, $label)); } /** * specify where the document should open when it first starts * * @param $style * @param int $a * @param int $b * @param int $c */ function openHere($style, $a = 0, $b = 0, $c = 0) { // this function will open the document at a specified page, in a specified style // the values for style, and the required parameters are: // 'XYZ' left, top, zoom // 'Fit' // 'FitH' top // 'FitV' left // 'FitR' left,bottom,right // 'FitB' // 'FitBH' top // 'FitBV' left $this->numObj++; $this->o_destination( $this->numObj, 'new', ['page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c] ); $id = $this->catalogId; $this->o_catalog($id, 'openHere', $this->numObj); } /** * Add JavaScript code to the PDF document * * @param string $code */ function addJavascript($code) { $this->javascript .= $code; } /** * create a labelled destination within the document * * @param $label * @param $style * @param int $a * @param int $b * @param int $c */ function addDestination($label, $style, $a = 0, $b = 0, $c = 0) { // associates the given label with the destination, it is done this way so that a destination can be specified after // it has been linked to // styles are the same as the 'openHere' function $this->numObj++; $this->o_destination( $this->numObj, 'new', ['page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c] ); $id = $this->numObj; // store the label->idf relationship, note that this means that labels can be used only once $this->destinations["$label"] = $id; } /** * define font families, this is used to initialize the font families for the default fonts * and for the user to add new ones for their fonts. The default bahavious can be overridden should * that be desired. * * @param $family * @param string $options */ function setFontFamily($family, $options = '') { if (!is_array($options)) { if ($family === 'init') { // set the known family groups // these font families will be used to enable bold and italic markers to be included // within text streams. html forms will be used... $this->fontFamilies['Helvetica.afm'] = [ 'b' => 'Helvetica-Bold.afm', 'i' => 'Helvetica-Oblique.afm', 'bi' => 'Helvetica-BoldOblique.afm', 'ib' => 'Helvetica-BoldOblique.afm' ]; $this->fontFamilies['Courier.afm'] = [ 'b' => 'Courier-Bold.afm', 'i' => 'Courier-Oblique.afm', 'bi' => 'Courier-BoldOblique.afm', 'ib' => 'Courier-BoldOblique.afm' ]; $this->fontFamilies['Times-Roman.afm'] = [ 'b' => 'Times-Bold.afm', 'i' => 'Times-Italic.afm', 'bi' => 'Times-BoldItalic.afm', 'ib' => 'Times-BoldItalic.afm' ]; } } else { // the user is trying to set a font family // note that this can also be used to set the base ones to something else if (mb_strlen($family)) { $this->fontFamilies[$family] = $options; } } } /** * used to add messages for use in debugging * * @param $message */ function addMessage($message) { $this->messages .= $message . "\n"; } /** * a few functions which should allow the document to be treated transactionally. * * @param $action */ function transaction($action) { switch ($action) { case 'start': // store all the data away into the checkpoint variable $data = get_object_vars($this); $this->checkpoint = $data; unset($data); break; case 'commit': if (is_array($this->checkpoint) && isset($this->checkpoint['checkpoint'])) { $tmp = $this->checkpoint['checkpoint']; $this->checkpoint = $tmp; unset($tmp); } else { $this->checkpoint = ''; } break; case 'rewind': // do not destroy the current checkpoint, but move us back to the state then, so that we can try again if (is_array($this->checkpoint)) { // can only abort if were inside a checkpoint $tmp = $this->checkpoint; foreach ($tmp as $k => $v) { if ($k !== 'checkpoint') { $this->$k = $v; } } unset($tmp); } break; case 'abort': if (is_array($this->checkpoint)) { // can only abort if were inside a checkpoint $tmp = $this->checkpoint; foreach ($tmp as $k => $v) { $this->$k = $v; } unset($tmp); } break; } } } PK!==--Nconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Surface/SurfacePDFLib.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Surface; use Svg\Style; use Svg\Document; class SurfacePDFLib implements SurfaceInterface { const DEBUG = false; private $canvas; private $width; private $height; /** @var Style */ private $style; public function __construct(Document $doc, $canvas = null) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $dimensions = $doc->getDimensions(); $w = $dimensions["width"]; $h = $dimensions["height"]; if (!$canvas) { $canvas = new \PDFlib(); /* all strings are expected as utf8 */ $canvas->set_option("stringformat=utf8"); $canvas->set_option("errorpolicy=return"); /* open new PDF file; insert a file name to create the PDF on disk */ if ($canvas->begin_document("", "") == 0) { die("Error: " . $canvas->get_errmsg()); } $canvas->set_info("Creator", "PDFlib starter sample"); $canvas->set_info("Title", "starter_graphics"); $canvas->begin_page_ext($w, $h, ""); } // Flip PDF coordinate system so that the origin is in // the top left rather than the bottom left $canvas->setmatrix( 1, 0, 0, -1, 0, $h ); $this->width = $w; $this->height = $h; $this->canvas = $canvas; } function out() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->end_page_ext(""); $this->canvas->end_document(""); return $this->canvas->get_buffer(); } public function save() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->save(); } public function restore() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->restore(); } public function scale($x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->scale($x, $y); } public function rotate($angle) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->rotate($angle); } public function translate($x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->translate($x, $y); } public function transform($a, $b, $c, $d, $e, $f) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->concat($a, $b, $c, $d, $e, $f); } public function beginPath() { if (self::DEBUG) echo __FUNCTION__ . "\n"; // TODO: Implement beginPath() method. } public function closePath() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->closepath(); } public function fillStroke() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->fill_stroke(); } public function clip() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->clip(); } public function fillText($text, $x, $y, $maxWidth = null) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->set_text_pos($x, $y); $this->canvas->show($text); } public function strokeText($text, $x, $y, $maxWidth = null) { if (self::DEBUG) echo __FUNCTION__ . "\n"; // TODO: Implement drawImage() method. } public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null) { if (self::DEBUG) echo __FUNCTION__ . "\n"; if (strpos($image, "data:") === 0) { $data = substr($image, strpos($image, ";") + 1); if (strpos($data, "base64") === 0) { $data = base64_decode(substr($data, 7)); } } else { $data = file_get_contents($image); } $image = tempnam(sys_get_temp_dir(), "svg"); file_put_contents($image, $data); $img = $this->canvas->load_image("auto", $image, ""); $sy = $sy - $sh; $this->canvas->fit_image($img, $sx, $sy, 'boxsize={' . "$sw $sh" . '} fitmethod=entire'); unlink($image); } public function lineTo($x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->lineto($x, $y); } public function moveTo($x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->moveto($x, $y); } public function quadraticCurveTo($cpx, $cpy, $x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; // FIXME not accurate $this->canvas->curveTo($cpx, $cpy, $cpx, $cpy, $x, $y); } public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->curveto($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); } public function arcTo($x1, $y1, $x2, $y2, $radius) { if (self::DEBUG) echo __FUNCTION__ . "\n"; } public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->arc($x, $y, $radius, $startAngle, $endAngle); } public function circle($x, $y, $radius) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->circle($x, $y, $radius); } public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->ellipse($x, $y, $radiusX, $radiusY); } public function fillRect($x, $y, $w, $h) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->rect($x, $y, $w, $h); $this->fill(); } public function rect($x, $y, $w, $h, $rx = 0, $ry = 0) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $canvas = $this->canvas; if ($rx <= 0.000001/* && $ry <= 0.000001*/) { $canvas->rect($x, $y, $w, $h); return; } /* Define a path for a rectangle with corners rounded by a given radius. * Start from the lower left corner and proceed counterclockwise. */ $canvas->moveto($x + $rx, $y); /* Start of the arc segment in the lower right corner */ $canvas->lineto($x + $w - $rx, $y); /* Arc segment in the lower right corner */ $canvas->arc($x + $w - $rx, $y + $rx, $rx, 270, 360); /* Start of the arc segment in the upper right corner */ $canvas->lineto($x + $w, $y + $h - $rx ); /* Arc segment in the upper right corner */ $canvas->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90); /* Start of the arc segment in the upper left corner */ $canvas->lineto($x + $rx, $y + $h); /* Arc segment in the upper left corner */ $canvas->arc($x + $rx, $y + $h - $rx, $rx, 90, 180); /* Start of the arc segment in the lower left corner */ $canvas->lineto($x , $y + $rx); /* Arc segment in the lower left corner */ $canvas->arc($x + $rx, $y + $rx, $rx, 180, 270); } public function fill() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->fill(); } public function strokeRect($x, $y, $w, $h) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->rect($x, $y, $w, $h); $this->stroke(); } public function stroke() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->stroke(); } public function endPath() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->endPath(); } public function measureText($text) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $style = $this->getStyle(); $font = $this->getFont($style->fontFamily, $style->fontStyle); return $this->canvas->stringwidth($text, $font, $this->getStyle()->fontSize); } public function getStyle() { if (self::DEBUG) echo __FUNCTION__ . "\n"; return $this->style; } public function setStyle(Style $style) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->style = $style; $canvas = $this->canvas; if ($stroke = $style->stroke && is_array($style->stroke)) { $canvas->setcolor( "stroke", "rgb", $stroke[0] / 255, $stroke[1] / 255, $stroke[2] / 255, null ); } if ($fill = $style->fill && is_array($style->fill)) { $canvas->setcolor( "fill", "rgb", $fill[0] / 255, $fill[1] / 255, $fill[2] / 255, null ); } if ($fillRule = strtolower($style->fillRule)) { $map = array( "nonzero" => "winding", "evenodd" => "evenodd", ); if (isset($map[$fillRule])) { $fillRule = $map[$fillRule]; $canvas->set_parameter("fillrule", $fillRule); } } $opts = array(); if ($style->strokeWidth > 0.000001) { $opts[] = "linewidth=$style->strokeWidth"; } if (in_array($style->strokeLinecap, array("butt", "round", "projecting"))) { $opts[] = "linecap=$style->strokeLinecap"; } if (in_array($style->strokeLinejoin, array("miter", "round", "bevel"))) { $opts[] = "linejoin=$style->strokeLinejoin"; } $canvas->set_graphics_option(implode(" ", $opts)); $opts = array(); $opacity = $style->opacity; if ($opacity !== null && $opacity < 1.0) { $opts[] = "opacityfill=$opacity"; $opts[] = "opacitystroke=$opacity"; } else { $fillOpacity = $style->fillOpacity; if ($fillOpacity !== null && $fillOpacity < 1.0) { $opts[] = "opacityfill=$fillOpacity"; } $strokeOpacity = $style->strokeOpacity; if ($strokeOpacity !== null && $strokeOpacity < 1.0) { $opts[] = "opacitystroke=$strokeOpacity"; } } if (count($opts)) { $gs = $canvas->create_gstate(implode(" ", $opts)); $canvas->set_gstate($gs); } $font = $this->getFont($style->fontFamily, $style->fontStyle); if ($font) { $canvas->setfont($font, $style->fontSize); } } private function getFont($family, $style) { $map = array( "serif" => "Times", "sans-serif" => "Helvetica", "fantasy" => "Symbol", "cursive" => "Times", "monospace" => "Courier", "arial" => "Helvetica", "verdana" => "Helvetica", ); $family = strtolower($family); if (isset($map[$family])) { $family = $map[$family]; } return $this->canvas->load_font($family, "unicode", "fontstyle=$style"); } public function setFont($family, $style, $weight) { // TODO: Implement setFont() method. } } PK!mrHY5Y5Lconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Surface/SurfaceCpdf.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Surface; use Svg\Document; use Svg\Style; class SurfaceCpdf implements SurfaceInterface { const DEBUG = false; /** @var \Svg\Surface\CPdf */ private $canvas; private $width; private $height; /** @var Style */ private $style; public function __construct(Document $doc, $canvas = null) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $dimensions = $doc->getDimensions(); $w = $dimensions["width"]; $h = $dimensions["height"]; if (!$canvas) { $canvas = new \Svg\Surface\CPdf(array(0, 0, $w, $h)); $refl = new \ReflectionClass($canvas); $canvas->fontcache = realpath(dirname($refl->getFileName()) . "/../../fonts/")."/"; } // Flip PDF coordinate system so that the origin is in // the top left rather than the bottom left $canvas->transform(array( 1, 0, 0, -1, 0, $h )); $this->width = $w; $this->height = $h; $this->canvas = $canvas; } function out() { if (self::DEBUG) echo __FUNCTION__ . "\n"; return $this->canvas->output(); } public function save() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->save(); } public function restore() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->restore(); } public function scale($x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->transform($x, 0, 0, $y, 0, 0); } public function rotate($angle) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $a = deg2rad($angle); $cos_a = cos($a); $sin_a = sin($a); $this->transform( $cos_a, $sin_a, -$sin_a, $cos_a, 0, 0 ); } public function translate($x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->transform( 1, 0, 0, 1, $x, $y ); } public function transform($a, $b, $c, $d, $e, $f) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->transform(array($a, $b, $c, $d, $e, $f)); } public function beginPath() { if (self::DEBUG) echo __FUNCTION__ . "\n"; // TODO: Implement beginPath() method. } public function closePath() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->closePath(); } public function fillStroke() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->fillStroke(); } public function clip() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->clip(); } public function fillText($text, $x, $y, $maxWidth = null) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->addText($x, $y, $this->style->fontSize, $text); } public function strokeText($text, $x, $y, $maxWidth = null) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->addText($x, $y, $this->style->fontSize, $text); } public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null) { if (self::DEBUG) echo __FUNCTION__ . "\n"; if (strpos($image, "data:") === 0) { $parts = explode(',', $image, 2); $data = $parts[1]; $base64 = false; $token = strtok($parts[0], ';'); while ($token !== false) { if ($token == 'base64') { $base64 = true; } $token = strtok(';'); } if ($base64) { $data = base64_decode($data); } } else { $data = file_get_contents($image); } $image = tempnam(sys_get_temp_dir(), "svg"); file_put_contents($image, $data); $img = $this->image($image, $sx, $sy, $sw, $sh, "normal"); unlink($image); } public static function getimagesize($filename) { static $cache = array(); if (isset($cache[$filename])) { return $cache[$filename]; } list($width, $height, $type) = getimagesize($filename); if ($width == null || $height == null) { $data = file_get_contents($filename, null, null, 0, 26); if (substr($data, 0, 2) === "BM") { $meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data); $width = (int)$meta['width']; $height = (int)$meta['height']; $type = IMAGETYPE_BMP; } } return $cache[$filename] = array($width, $height, $type); } function image($img, $x, $y, $w, $h, $resolution = "normal") { list($width, $height, $type) = $this->getimagesize($img); switch ($type) { case IMAGETYPE_JPEG: $this->canvas->addJpegFromFile($img, $x, $y - $h, $w, $h); break; case IMAGETYPE_GIF: case IMAGETYPE_BMP: // @todo use cache for BMP and GIF $img = $this->_convert_gif_bmp_to_png($img, $type); case IMAGETYPE_PNG: $this->canvas->addPngFromFile($img, $x, $y - $h, $w, $h); break; default: } } public function lineTo($x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->lineTo($x, $y); } public function moveTo($x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->moveTo($x, $y); } public function quadraticCurveTo($cpx, $cpy, $x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; // FIXME not accurate $this->canvas->quadTo($cpx, $cpy, $x, $y); } public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->curveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); } public function arcTo($x1, $y1, $x2, $y2, $radius) { if (self::DEBUG) echo __FUNCTION__ . "\n"; } public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, $startAngle, $endAngle, false, false, false, true); } public function circle($x, $y, $radius) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, 0, 360, true, false, false, false); } public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->ellipse($x, $y, $radiusX, $radiusY, 0, 8, 0, 360, false, false, false, false); } public function fillRect($x, $y, $w, $h) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->rect($x, $y, $w, $h); $this->fill(); } public function rect($x, $y, $w, $h, $rx = 0, $ry = 0) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $canvas = $this->canvas; if ($rx <= 0.000001/* && $ry <= 0.000001*/) { $canvas->rect($x, $y, $w, $h); return; } $rx = min($rx, $w / 2); $rx = min($rx, $h / 2); /* Define a path for a rectangle with corners rounded by a given radius. * Start from the lower left corner and proceed counterclockwise. */ $this->moveTo($x + $rx, $y); /* Start of the arc segment in the lower right corner */ $this->lineTo($x + $w - $rx, $y); /* Arc segment in the lower right corner */ $this->arc($x + $w - $rx, $y + $rx, $rx, 270, 360); /* Start of the arc segment in the upper right corner */ $this->lineTo($x + $w, $y + $h - $rx ); /* Arc segment in the upper right corner */ $this->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90); /* Start of the arc segment in the upper left corner */ $this->lineTo($x + $rx, $y + $h); /* Arc segment in the upper left corner */ $this->arc($x + $rx, $y + $h - $rx, $rx, 90, 180); /* Start of the arc segment in the lower left corner */ $this->lineTo($x , $y + $rx); /* Arc segment in the lower left corner */ $this->arc($x + $rx, $y + $rx, $rx, 180, 270); } public function fill() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->fill(); } public function strokeRect($x, $y, $w, $h) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->rect($x, $y, $w, $h); $this->stroke(); } public function stroke() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->stroke(); } public function endPath() { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->canvas->endPath(); } public function measureText($text) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $style = $this->getStyle(); $this->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); return $this->canvas->getTextWidth($this->getStyle()->fontSize, $text); } public function getStyle() { if (self::DEBUG) echo __FUNCTION__ . "\n"; return $this->style; } public function setStyle(Style $style) { if (self::DEBUG) echo __FUNCTION__ . "\n"; $this->style = $style; $canvas = $this->canvas; if (is_array($style->stroke) && $stroke = $style->stroke) { $canvas->setStrokeColor(array((float)$stroke[0]/255, (float)$stroke[1]/255, (float)$stroke[2]/255), true); } if (is_array($style->fill) && $fill = $style->fill) { $canvas->setColor(array((float)$fill[0]/255, (float)$fill[1]/255, (float)$fill[2]/255), true); } if ($fillRule = strtolower($style->fillRule)) { $canvas->setFillRule($fillRule); } $opacity = $style->opacity; if ($opacity !== null && $opacity < 1.0) { $canvas->setLineTransparency("Normal", $opacity); $canvas->currentLineTransparency = null; $canvas->setFillTransparency("Normal", $opacity); $canvas->currentFillTransparency = null; } else { $fillOpacity = $style->fillOpacity; if ($fillOpacity !== null && $fillOpacity < 1.0) { $canvas->setFillTransparency("Normal", $fillOpacity); $canvas->currentFillTransparency = null; } $strokeOpacity = $style->strokeOpacity; if ($strokeOpacity !== null && $strokeOpacity < 1.0) { $canvas->setLineTransparency("Normal", $strokeOpacity); $canvas->currentLineTransparency = null; } } $dashArray = null; if ($style->strokeDasharray) { $dashArray = preg_split('/\s*,\s*/', $style->strokeDasharray); } $phase=0; if ($style->strokeDashoffset) { $phase = $style->strokeDashoffset; } $canvas->setLineStyle( $style->strokeWidth, $style->strokeLinecap, $style->strokeLinejoin, $dashArray, $phase ); $this->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); } public function setFont($family, $style, $weight) { $map = array( "serif" => "Times", "sans-serif" => "Helvetica", "fantasy" => "Symbol", "cursive" => "Times", "monospace" => "Courier", "arial" => "Helvetica", "verdana" => "Helvetica", ); $styleMap = array( 'Helvetica' => array( 'b' => 'Helvetica-Bold', 'i' => 'Helvetica-Oblique', 'bi' => 'Helvetica-BoldOblique', ), 'Courier' => array( 'b' => 'Courier-Bold', 'i' => 'Courier-Oblique', 'bi' => 'Courier-BoldOblique', ), 'Times' => array( '' => 'Times-Roman', 'b' => 'Times-Bold', 'i' => 'Times-Italic', 'bi' => 'Times-BoldItalic', ), ); $family = strtolower($family); $style = strtolower($style); $weight = strtolower($weight); if (isset($map[$family])) { $family = $map[$family]; } if (isset($styleMap[$family])) { $key = ""; if ($weight === "bold" || $weight === "bolder" || (is_numeric($weight) && $weight >= 600)) { $key .= "b"; } if ($style === "italic" || $style === "oblique") { $key .= "i"; } if (isset($styleMap[$family][$key])) { $family = $styleMap[$family][$key]; } } $this->canvas->selectFont("$family.afm"); } } PK!~RRQconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Surface/SurfaceInterface.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Surface; use Svg\Style; /** * Interface Surface, like CanvasRenderingContext2D * * @package Svg */ interface SurfaceInterface { public function save(); public function restore(); // transformations (default transform is the identity matrix) public function scale($x, $y); public function rotate($angle); public function translate($x, $y); public function transform($a, $b, $c, $d, $e, $f); // path ends public function beginPath(); public function closePath(); public function fill(); public function stroke(); public function endPath(); public function fillStroke(); public function clip(); // text (see also the CanvasDrawingStyles interface) public function fillText($text, $x, $y, $maxWidth = null); public function strokeText($text, $x, $y, $maxWidth = null); public function measureText($text); // drawing images public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null); // paths public function lineTo($x, $y); public function moveTo($x, $y); public function quadraticCurveTo($cpx, $cpy, $x, $y); public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); public function arcTo($x1, $y1, $x2, $y2, $radius); public function circle($x, $y, $radius); public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false); public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise); // Rectangle public function rect($x, $y, $w, $h, $rx = 0, $ry = 0); public function fillRect($x, $y, $w, $h); public function strokeRect($x, $y, $w, $h); public function setStyle(Style $style); /** * @return Style */ public function getStyle(); public function setFont($family, $style, $weight); } PK!M(88Fconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Gradient/Stop.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Gradient; class Stop { public $offset; public $color; public $opacity = 1.0; } PK! a6Bconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Shape.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; use Svg\Style; class Shape extends AbstractTag { protected function before($attributes) { $surface = $this->document->getSurface(); $surface->save(); $style = $this->makeStyle($attributes); $this->setStyle($style); $surface->setStyle($style); $this->applyTransform($attributes); } protected function after() { $surface = $this->document->getSurface(); if ($this->hasShape) { $style = $surface->getStyle(); $fill = $style->fill && is_array($style->fill); $stroke = $style->stroke && is_array($style->stroke); if ($fill) { if ($stroke) { $surface->fillStroke(); } else { // if (is_string($style->fill)) { // /** @var LinearGradient|RadialGradient $gradient */ // $gradient = $this->getDocument()->getDef($style->fill); // // var_dump($gradient->getStops()); // } $surface->fill(); } } elseif ($stroke) { $surface->stroke(); } else { $surface->endPath(); } } $surface->restore(); } } PK!W WWAconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Rect.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Rect extends Shape { protected $x = 0; protected $y = 0; protected $width = 0; protected $height = 0; protected $rx = 0; protected $ry = 0; public function start($attributes) { if (isset($attributes['x'])) { $this->x = $attributes['x']; } if (isset($attributes['y'])) { $this->y = $attributes['y']; } if (isset($attributes['width'])) { if ('%' === substr($attributes['width'], -1)) { $factor = substr($attributes['width'], 0, -1) / 100; $this->width = $this->document->getWidth() * $factor; } else { $this->width = $attributes['width']; } } if (isset($attributes['height'])) { if ('%' === substr($attributes['height'], -1)) { $factor = substr($attributes['height'], 0, -1) / 100; $this->height = $this->document->getHeight() * $factor; } else { $this->height = $attributes['height']; } } if (isset($attributes['rx'])) { $this->rx = $attributes['rx']; } if (isset($attributes['ry'])) { $this->ry = $attributes['ry']; } $this->document->getSurface()->rect($this->x, $this->y, $this->width, $this->height, $this->rx, $this->ry); } } PK!)bDAconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Line.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Line extends Shape { protected $x1 = 0; protected $y1 = 0; protected $x2 = 0; protected $y2 = 0; public function start($attributes) { if (isset($attributes['x1'])) { $this->x1 = $attributes['x1']; } if (isset($attributes['y1'])) { $this->y1 = $attributes['y1']; } if (isset($attributes['x2'])) { $this->x2 = $attributes['x2']; } if (isset($attributes['y2'])) { $this->y2 = $attributes['y2']; } $surface = $this->document->getSurface(); $surface->moveTo($this->x1, $this->y1); $surface->lineTo($this->x2, $this->y2); } } PK!g>  Kconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/LinearGradient.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; use Svg\Gradient; use Svg\Style; class LinearGradient extends AbstractTag { protected $x1; protected $y1; protected $x2; protected $y2; /** @var Gradient\Stop[] */ protected $stops = array(); public function start($attributes) { parent::start($attributes); if (isset($attributes['x1'])) { $this->x1 = $attributes['x1']; } if (isset($attributes['y1'])) { $this->y1 = $attributes['y1']; } if (isset($attributes['x2'])) { $this->x2 = $attributes['x2']; } if (isset($attributes['y2'])) { $this->y2 = $attributes['y2']; } } public function getStops() { if (empty($this->stops)) { foreach ($this->children as $_child) { if ($_child->tagName != "stop") { continue; } $_stop = new Gradient\Stop(); $_attributes = $_child->attributes; // Style if (isset($_attributes["style"])) { $_style = Style::parseCssStyle($_attributes["style"]); if (isset($_style["stop-color"])) { $_stop->color = Style::parseColor($_style["stop-color"]); } if (isset($_style["stop-opacity"])) { $_stop->opacity = max(0, min(1.0, $_style["stop-opacity"])); } } // Attributes if (isset($_attributes["offset"])) { $_stop->offset = $_attributes["offset"]; } if (isset($_attributes["stop-color"])) { $_stop->color = Style::parseColor($_attributes["stop-color"]); } if (isset($_attributes["stop-opacity"])) { $_stop->opacity = max(0, min(1.0, $_attributes["stop-opacity"])); } $this->stops[] = $_stop; } } return $this->stops; } } PK!<::Aconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Stop.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Stop extends AbstractTag { public function start($attributes) { } } PK!iEconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Polyline.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Polyline extends Shape { public function start($attributes) { $tmp = array(); preg_match_all('/([\-]*[0-9\.]+)/', $attributes['points'], $tmp); $points = $tmp[0]; $count = count($points); $surface = $this->document->getSurface(); list($x, $y) = $points; $surface->moveTo($x, $y); for ($i = 2; $i < $count; $i += 2) { $x = $points[$i]; $y = $points[$i + 1]; $surface->lineTo($x, $y); } } } PK!*TBconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Group.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; use Svg\Style; class Group extends AbstractTag { protected function before($attributes) { $surface = $this->document->getSurface(); $surface->save(); $style = $this->makeStyle($attributes); $this->setStyle($style); $surface->setStyle($style); $this->applyTransform($attributes); } protected function after() { $this->document->getSurface()->restore(); } } PK!zCconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Anchor.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Anchor extends Group { } PK!! Cconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/UseTag.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class UseTag extends AbstractTag { protected $x = 0; protected $y = 0; protected $width; protected $height; /** @var AbstractTag */ protected $reference; protected function before($attributes) { if (isset($attributes['x'])) { $this->x = $attributes['x']; } if (isset($attributes['y'])) { $this->y = $attributes['y']; } if (isset($attributes['width'])) { $this->width = $attributes['width']; } if (isset($attributes['height'])) { $this->height = $attributes['height']; } parent::before($attributes); $document = $this->getDocument(); $link = $attributes["xlink:href"]; $this->reference = $document->getDef($link); if ($this->reference) { $this->reference->before($attributes); } $surface = $document->getSurface(); $surface->save(); $surface->translate($this->x, $this->y); } protected function after() { parent::after(); if ($this->reference) { $this->reference->after(); } $this->getDocument()->getSurface()->restore(); } public function handle($attributes) { parent::handle($attributes); if (!$this->reference) { return; } $attributes = array_merge($this->reference->attributes, $attributes); $this->reference->handle($attributes); foreach ($this->reference->children as $_child) { $_attributes = array_merge($_child->attributes, $attributes); $_child->handle($_attributes); } } public function handleEnd() { parent::handleEnd(); if (!$this->reference) { return; } $this->reference->handleEnd(); foreach ($this->reference->children as $_child) { $_child->handleEnd(); } } } PK!KCconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Circle.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Circle extends Shape { protected $cx = 0; protected $cy = 0; protected $r; public function start($attributes) { if (isset($attributes['cx'])) { $this->cx = $attributes['cx']; } if (isset($attributes['cy'])) { $this->cy = $attributes['cy']; } if (isset($attributes['r'])) { $this->r = $attributes['r']; } $this->document->getSurface()->circle($this->cx, $this->cy, $this->r); } } PK!ˮ`DDKconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/RadialGradient.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class RadialGradient extends AbstractTag { public function start($attributes) { } } PK!0?ؔNNAconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Path.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; use Svg\Surface\SurfaceInterface; class Path extends Shape { // kindly borrowed from fabric.util.parsePath. /* @see https://github.com/fabricjs/fabric.js/blob/master/src/util/path.js#L664 */ const NUMBER_PATTERN = '([-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?)\s*'; const COMMA_PATTERN = '(?:\s+,?\s*|,\s*)?'; const FLAG_PATTERN = '([01])'; const ARC_REGEXP = '/' . self::NUMBER_PATTERN . self::COMMA_PATTERN . self::NUMBER_PATTERN . self::COMMA_PATTERN . self::NUMBER_PATTERN . self::COMMA_PATTERN . self::FLAG_PATTERN . self::COMMA_PATTERN . self::FLAG_PATTERN . self::COMMA_PATTERN . self::NUMBER_PATTERN . self::COMMA_PATTERN . self::NUMBER_PATTERN . '/'; static $commandLengths = array( 'm' => 2, 'l' => 2, 'h' => 1, 'v' => 1, 'c' => 6, 's' => 4, 'q' => 4, 't' => 2, 'a' => 7, ); static $repeatedCommands = array( 'm' => 'l', 'M' => 'L', ); public static function parse(string $commandSequence): array { $commands = array(); preg_match_all('/([MZLHVCSQTAmzlhvcsqta])([eE ,\-.\d]+)*/', $commandSequence, $commands, PREG_SET_ORDER); $path = array(); foreach ($commands as $c) { if (count($c) == 3) { $commandLower = strtolower($c[1]); // arcs have special flags that apparently don't require spaces. if ($commandLower === 'a' && preg_match_all(static::ARC_REGEXP, $c[2], $matches)) { $numberOfMatches = count($matches[0]); for ($k = 0; $k < $numberOfMatches; ++$k) { $path[] = [ $c[1], $matches[1][$k], $matches[2][$k], $matches[3][$k], $matches[4][$k], $matches[5][$k], $matches[6][$k], $matches[7][$k], ]; } continue; } $arguments = array(); preg_match_all('/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/i', $c[2], $arguments, PREG_PATTERN_ORDER); $item = $arguments[0]; if ( isset(self::$commandLengths[$commandLower]) && ($commandLength = self::$commandLengths[$commandLower]) && count($item) > $commandLength ) { $repeatedCommand = isset(self::$repeatedCommands[$c[1]]) ? self::$repeatedCommands[$c[1]] : $c[1]; $command = $c[1]; for ($k = 0, $klen = count($item); $k < $klen; $k += $commandLength) { $_item = array_slice($item, $k, $k + $commandLength); array_unshift($_item, $command); $path[] = $_item; $command = $repeatedCommand; } } else { array_unshift($item, $c[1]); $path[] = $item; } } else { $item = array($c[1]); $path[] = $item; } } return $path; } public function start($attributes) { if (!isset($attributes['d'])) { $this->hasShape = false; return; } $path = static::parse($attributes['d']); $surface = $this->document->getSurface(); // From https://github.com/kangax/fabric.js/blob/master/src/shapes/path.class.js $current = null; // current instruction $previous = null; $subpathStartX = 0; $subpathStartY = 0; $x = 0; // current x $y = 0; // current y $controlX = 0; // current control point x $controlY = 0; // current control point y $tempX = null; $tempY = null; $tempControlX = null; $tempControlY = null; $l = 0; //-((this.width / 2) + $this.pathOffset.x), $t = 0; //-((this.height / 2) + $this.pathOffset.y), $methodName = null; foreach ($path as $current) { switch ($current[0]) { // first letter case 'l': // lineto, relative $x += $current[1]; $y += $current[2]; $surface->lineTo($x + $l, $y + $t); break; case 'L': // lineto, absolute $x = $current[1]; $y = $current[2]; $surface->lineTo($x + $l, $y + $t); break; case 'h': // horizontal lineto, relative $x += $current[1]; $surface->lineTo($x + $l, $y + $t); break; case 'H': // horizontal lineto, absolute $x = $current[1]; $surface->lineTo($x + $l, $y + $t); break; case 'v': // vertical lineto, relative $y += $current[1]; $surface->lineTo($x + $l, $y + $t); break; case 'V': // verical lineto, absolute $y = $current[1]; $surface->lineTo($x + $l, $y + $t); break; case 'm': // moveTo, relative $x += $current[1]; $y += $current[2]; $subpathStartX = $x; $subpathStartY = $y; $surface->moveTo($x + $l, $y + $t); break; case 'M': // moveTo, absolute $x = $current[1]; $y = $current[2]; $subpathStartX = $x; $subpathStartY = $y; $surface->moveTo($x + $l, $y + $t); break; case 'c': // bezierCurveTo, relative $tempX = $x + $current[5]; $tempY = $y + $current[6]; $controlX = $x + $current[3]; $controlY = $y + $current[4]; $surface->bezierCurveTo( $x + $current[1] + $l, // x1 $y + $current[2] + $t, // y1 $controlX + $l, // x2 $controlY + $t, // y2 $tempX + $l, $tempY + $t ); $x = $tempX; $y = $tempY; break; case 'C': // bezierCurveTo, absolute $x = $current[5]; $y = $current[6]; $controlX = $current[3]; $controlY = $current[4]; $surface->bezierCurveTo( $current[1] + $l, $current[2] + $t, $controlX + $l, $controlY + $t, $x + $l, $y + $t ); break; case 's': // shorthand cubic bezierCurveTo, relative // transform to absolute x,y $tempX = $x + $current[3]; $tempY = $y + $current[4]; if (!preg_match('/[CcSs]/', $previous[0])) { // If there is no previous command or if the previous command was not a C, c, S, or s, // the control point is coincident with the current point $controlX = $x; $controlY = $y; } else { // calculate reflection of previous control points $controlX = 2 * $x - $controlX; $controlY = 2 * $y - $controlY; } $surface->bezierCurveTo( $controlX + $l, $controlY + $t, $x + $current[1] + $l, $y + $current[2] + $t, $tempX + $l, $tempY + $t ); // set control point to 2nd one of this command // "... the first control point is assumed to be // the reflection of the second control point on // the previous command relative to the current point." $controlX = $x + $current[1]; $controlY = $y + $current[2]; $x = $tempX; $y = $tempY; break; case 'S': // shorthand cubic bezierCurveTo, absolute $tempX = $current[3]; $tempY = $current[4]; if (!preg_match('/[CcSs]/', $previous[0])) { // If there is no previous command or if the previous command was not a C, c, S, or s, // the control point is coincident with the current point $controlX = $x; $controlY = $y; } else { // calculate reflection of previous control points $controlX = 2 * $x - $controlX; $controlY = 2 * $y - $controlY; } $surface->bezierCurveTo( $controlX + $l, $controlY + $t, $current[1] + $l, $current[2] + $t, $tempX + $l, $tempY + $t ); $x = $tempX; $y = $tempY; // set control point to 2nd one of this command // "... the first control point is assumed to be // the reflection of the second control point on // the previous command relative to the current point." $controlX = $current[1]; $controlY = $current[2]; break; case 'q': // quadraticCurveTo, relative // transform to absolute x,y $tempX = $x + $current[3]; $tempY = $y + $current[4]; $controlX = $x + $current[1]; $controlY = $y + $current[2]; $surface->quadraticCurveTo( $controlX + $l, $controlY + $t, $tempX + $l, $tempY + $t ); $x = $tempX; $y = $tempY; break; case 'Q': // quadraticCurveTo, absolute $tempX = $current[3]; $tempY = $current[4]; $surface->quadraticCurveTo( $current[1] + $l, $current[2] + $t, $tempX + $l, $tempY + $t ); $x = $tempX; $y = $tempY; $controlX = $current[1]; $controlY = $current[2]; break; case 't': // shorthand quadraticCurveTo, relative // transform to absolute x,y $tempX = $x + $current[1]; $tempY = $y + $current[2]; if (preg_match("/[QqTt]/", $previous[0])) { // If there is no previous command or if the previous command was not a Q, q, T or t, // assume the control point is coincident with the current point $controlX = $x; $controlY = $y; } else { if ($previous[0] === 't') { // calculate reflection of previous control points for t $controlX = 2 * $x - $tempControlX; $controlY = 2 * $y - $tempControlY; } else { if ($previous[0] === 'q') { // calculate reflection of previous control points for q $controlX = 2 * $x - $controlX; $controlY = 2 * $y - $controlY; } } } $tempControlX = $controlX; $tempControlY = $controlY; $surface->quadraticCurveTo( $controlX + $l, $controlY + $t, $tempX + $l, $tempY + $t ); $x = $tempX; $y = $tempY; $controlX = $x + $current[1]; $controlY = $y + $current[2]; break; case 'T': $tempX = $current[1]; $tempY = $current[2]; // calculate reflection of previous control points $controlX = 2 * $x - $controlX; $controlY = 2 * $y - $controlY; $surface->quadraticCurveTo( $controlX + $l, $controlY + $t, $tempX + $l, $tempY + $t ); $x = $tempX; $y = $tempY; break; case 'a': // TODO: optimize this $this->drawArc( $surface, $x + $l, $y + $t, array( $current[1], $current[2], $current[3], $current[4], $current[5], $current[6] + $x + $l, $current[7] + $y + $t ) ); $x += $current[6]; $y += $current[7]; break; case 'A': // TODO: optimize this $this->drawArc( $surface, $x + $l, $y + $t, array( $current[1], $current[2], $current[3], $current[4], $current[5], $current[6] + $l, $current[7] + $t ) ); $x = $current[6]; $y = $current[7]; break; case 'z': case 'Z': $x = $subpathStartX; $y = $subpathStartY; $surface->closePath(); break; } $previous = $current; } } function drawArc(SurfaceInterface $surface, $fx, $fy, $coords) { $rx = $coords[0]; $ry = $coords[1]; $rot = $coords[2]; $large = $coords[3]; $sweep = $coords[4]; $tx = $coords[5]; $ty = $coords[6]; $segs = array( array(), array(), array(), array(), ); $segsNorm = $this->arcToSegments($tx - $fx, $ty - $fy, $rx, $ry, $large, $sweep, $rot); for ($i = 0, $len = count($segsNorm); $i < $len; $i++) { $segs[$i][0] = $segsNorm[$i][0] + $fx; $segs[$i][1] = $segsNorm[$i][1] + $fy; $segs[$i][2] = $segsNorm[$i][2] + $fx; $segs[$i][3] = $segsNorm[$i][3] + $fy; $segs[$i][4] = $segsNorm[$i][4] + $fx; $segs[$i][5] = $segsNorm[$i][5] + $fy; call_user_func_array(array($surface, "bezierCurveTo"), $segs[$i]); } } function arcToSegments($toX, $toY, $rx, $ry, $large, $sweep, $rotateX) { $th = $rotateX * M_PI / 180; $sinTh = sin($th); $cosTh = cos($th); $fromX = 0; $fromY = 0; $rx = abs($rx); $ry = abs($ry); $px = -$cosTh * $toX * 0.5 - $sinTh * $toY * 0.5; $py = -$cosTh * $toY * 0.5 + $sinTh * $toX * 0.5; $rx2 = $rx * $rx; $ry2 = $ry * $ry; $py2 = $py * $py; $px2 = $px * $px; $pl = $rx2 * $ry2 - $rx2 * $py2 - $ry2 * $px2; $root = 0; if ($pl < 0) { $s = sqrt(1 - $pl / ($rx2 * $ry2)); $rx *= $s; $ry *= $s; } else { $root = ($large == $sweep ? -1.0 : 1.0) * sqrt($pl / ($rx2 * $py2 + $ry2 * $px2)); } $cx = $root * $rx * $py / $ry; $cy = -$root * $ry * $px / $rx; $cx1 = $cosTh * $cx - $sinTh * $cy + $toX * 0.5; $cy1 = $sinTh * $cx + $cosTh * $cy + $toY * 0.5; $mTheta = $this->calcVectorAngle(1, 0, ($px - $cx) / $rx, ($py - $cy) / $ry); $dtheta = $this->calcVectorAngle(($px - $cx) / $rx, ($py - $cy) / $ry, (-$px - $cx) / $rx, (-$py - $cy) / $ry); if ($sweep == 0 && $dtheta > 0) { $dtheta -= 2 * M_PI; } else { if ($sweep == 1 && $dtheta < 0) { $dtheta += 2 * M_PI; } } // $Convert $into $cubic $bezier $segments <= 90deg $segments = ceil(abs($dtheta / M_PI * 2)); $result = array(); $mDelta = $dtheta / $segments; $mT = 8 / 3 * sin($mDelta / 4) * sin($mDelta / 4) / sin($mDelta / 2); $th3 = $mTheta + $mDelta; for ($i = 0; $i < $segments; $i++) { $result[$i] = $this->segmentToBezier( $mTheta, $th3, $cosTh, $sinTh, $rx, $ry, $cx1, $cy1, $mT, $fromX, $fromY ); $fromX = $result[$i][4]; $fromY = $result[$i][5]; $mTheta = $th3; $th3 += $mDelta; } return $result; } function segmentToBezier($th2, $th3, $cosTh, $sinTh, $rx, $ry, $cx1, $cy1, $mT, $fromX, $fromY) { $costh2 = cos($th2); $sinth2 = sin($th2); $costh3 = cos($th3); $sinth3 = sin($th3); $toX = $cosTh * $rx * $costh3 - $sinTh * $ry * $sinth3 + $cx1; $toY = $sinTh * $rx * $costh3 + $cosTh * $ry * $sinth3 + $cy1; $cp1X = $fromX + $mT * (-$cosTh * $rx * $sinth2 - $sinTh * $ry * $costh2); $cp1Y = $fromY + $mT * (-$sinTh * $rx * $sinth2 + $cosTh * $ry * $costh2); $cp2X = $toX + $mT * ($cosTh * $rx * $sinth3 + $sinTh * $ry * $costh3); $cp2Y = $toY + $mT * ($sinTh * $rx * $sinth3 - $cosTh * $ry * $costh3); return array( $cp1X, $cp1Y, $cp2X, $cp2Y, $toX, $toY ); } function calcVectorAngle($ux, $uy, $vx, $vy) { $ta = atan2($uy, $ux); $tb = atan2($vy, $vx); if ($tb >= $ta) { return $tb - $ta; } else { return 2 * M_PI - ($ta - $tb); } } } PK!9Hconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/AbstractTag.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; use Svg\Document; use Svg\Style; abstract class AbstractTag { /** @var Document */ protected $document; public $tagName; /** @var Style */ protected $style; protected $attributes = array(); protected $hasShape = true; /** @var self[] */ protected $children = array(); public function __construct(Document $document, $tagName) { $this->document = $document; $this->tagName = $tagName; } public function getDocument(){ return $this->document; } /** * @return Group|null */ public function getParentGroup() { $stack = $this->getDocument()->getStack(); for ($i = count($stack)-2; $i >= 0; $i--) { $tag = $stack[$i]; if ($tag instanceof Group || $tag instanceof Document) { return $tag; } } return null; } public function handle($attributes) { $this->attributes = $attributes; if (!$this->getDocument()->inDefs) { $this->before($attributes); $this->start($attributes); } } public function handleEnd() { if (!$this->getDocument()->inDefs) { $this->end(); $this->after(); } } protected function before($attributes) { } protected function start($attributes) { } protected function end() { } protected function after() { } public function getAttributes() { return $this->attributes; } protected function setStyle(Style $style) { $this->style = $style; if ($style->display === "none") { $this->hasShape = false; } } /** * @return Style */ public function getStyle() { return $this->style; } /** * Make a style object from the tag and its attributes * * @param array $attributes * * @return Style */ protected function makeStyle($attributes) { $style = new Style(); $style->inherit($this); $style->fromStyleSheets($this, $attributes); $style->fromAttributes($attributes); return $style; } protected function applyTransform($attributes) { if (isset($attributes["transform"])) { $surface = $this->document->getSurface(); $transform = $attributes["transform"]; $match = array(); preg_match_all( '/(matrix|translate|scale|rotate|skewX|skewY)\((.*?)\)/is', $transform, $match, PREG_SET_ORDER ); $transformations = array(); if (count($match[0])) { foreach ($match as $_match) { $arguments = preg_split('/[ ,]+/', $_match[2]); array_unshift($arguments, $_match[1]); $transformations[] = $arguments; } } foreach ($transformations as $t) { switch ($t[0]) { case "matrix": $surface->transform($t[1], $t[2], $t[3], $t[4], $t[5], $t[6]); break; case "translate": $surface->translate($t[1], isset($t[2]) ? $t[2] : 0); break; case "scale": $surface->scale($t[1], isset($t[2]) ? $t[2] : $t[1]); break; case "rotate": if (isset($t[2])) { $t[3] = isset($t[3]) ? $t[3] : 0; $surface->translate($t[2], $t[3]); $surface->rotate($t[1]); $surface->translate(-$t[2], -$t[3]); } else { $surface->rotate($t[1]); } break; case "skewX": $surface->skewX($t[1]); break; case "skewY": $surface->skewY($t[1]); break; } } } } } PK!x1 ttAconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Text.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Text extends Shape { protected $x = 0; protected $y = 0; protected $text = ""; public function start($attributes) { $document = $this->document; $height = $this->document->getHeight(); $this->y = $height; if (isset($attributes['x'])) { $this->x = $attributes['x']; } if (isset($attributes['y'])) { $this->y = $height - $attributes['y']; } $document->getSurface()->transform(1, 0, 0, -1, 0, $height); } public function end() { $surface = $this->document->getSurface(); $x = $this->x; $y = $this->y; $style = $surface->getStyle(); $surface->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); switch ($style->textAnchor) { case "middle": $width = $surface->measureText($this->text); $x -= $width / 2; break; case "end": $width = $surface->measureText($this->text); $x -= $width; break; } $surface->fillText($this->getText(), $x, $y); } protected function after() { $this->document->getSurface()->restore(); } public function appendText($text) { $this->text .= $text; } public function getText() { return trim($this->text); } } PK!=1cEconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/StyleTag.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; use Sabberworm\CSS; class StyleTag extends AbstractTag { protected $text = ""; public function end() { $parser = new CSS\Parser($this->text); $this->document->appendStyleSheet($parser->parse()); } public function appendText($text) { $this->text .= $text; } } PK!3:Econvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/ClipPath.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; use Svg\Style; class ClipPath extends AbstractTag { protected function before($attributes) { $surface = $this->document->getSurface(); $surface->save(); $style = $this->makeStyle($attributes); $this->setStyle($style); $surface->setStyle($style); $this->applyTransform($attributes); } protected function after() { $this->document->getSurface()->restore(); } } PK!oDconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Ellipse.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Ellipse extends Shape { protected $cx = 0; protected $cy = 0; protected $rx = 0; protected $ry = 0; public function start($attributes) { parent::start($attributes); if (isset($attributes['cx'])) { $this->cx = $attributes['cx']; } if (isset($attributes['cy'])) { $this->cy = $attributes['cy']; } if (isset($attributes['rx'])) { $this->rx = $attributes['rx']; } if (isset($attributes['ry'])) { $this->ry = $attributes['ry']; } $this->document->getSurface()->ellipse($this->cx, $this->cy, $this->rx, $this->ry, 0, 0, 360, false); } } PK!=`Bconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Image.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Image extends AbstractTag { protected $x = 0; protected $y = 0; protected $width = 0; protected $height = 0; protected $href = null; protected function before($attributes) { parent::before($attributes); $surface = $this->document->getSurface(); $surface->save(); $this->applyTransform($attributes); } public function start($attributes) { $document = $this->document; $height = $this->document->getHeight(); $this->y = $height; if (isset($attributes['x'])) { $this->x = $attributes['x']; } if (isset($attributes['y'])) { $this->y = $height - $attributes['y']; } if (isset($attributes['width'])) { $this->width = $attributes['width']; } if (isset($attributes['height'])) { $this->height = $attributes['height']; } if (isset($attributes['xlink:href'])) { $this->href = $attributes['xlink:href']; } $document->getSurface()->transform(1, 0, 0, -1, 0, $height); $document->getSurface()->drawImage($this->href, $this->x, $this->y, $this->width, $this->height); } protected function after() { $this->document->getSurface()->restore(); } } PK!pDconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Polygon.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg\Tag; class Polygon extends Shape { public function start($attributes) { $tmp = array(); preg_match_all('/([\-]*[0-9\.]+)/', $attributes['points'], $tmp); $points = $tmp[0]; $count = count($points); $surface = $this->document->getSurface(); list($x, $y) = $points; $surface->moveTo($x, $y); for ($i = 2; $i < $count; $i += 2) { $x = $points[$i]; $y = $points[$i + 1]; $surface->lineTo($x, $y); } $surface->closePath(); } } PK!>4>GG>convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Style.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg; use Svg\Tag\AbstractTag; class Style { const TYPE_COLOR = 1; const TYPE_LENGTH = 2; const TYPE_NAME = 3; const TYPE_ANGLE = 4; const TYPE_NUMBER = 5; public $color; public $opacity; public $display; public $fill; public $fillOpacity; public $fillRule; public $stroke; public $strokeOpacity; public $strokeLinecap; public $strokeLinejoin; public $strokeMiterlimit; public $strokeWidth; public $strokeDasharray; public $strokeDashoffset; public $fontFamily = 'serif'; public $fontSize = 12; public $fontWeight = 'normal'; public $fontStyle = 'normal'; public $textAnchor = 'start'; protected function getStyleMap() { return array( 'color' => array('color', self::TYPE_COLOR), 'opacity' => array('opacity', self::TYPE_NUMBER), 'display' => array('display', self::TYPE_NAME), 'fill' => array('fill', self::TYPE_COLOR), 'fill-opacity' => array('fillOpacity', self::TYPE_NUMBER), 'fill-rule' => array('fillRule', self::TYPE_NAME), 'stroke' => array('stroke', self::TYPE_COLOR), 'stroke-dasharray' => array('strokeDasharray', self::TYPE_NAME), 'stroke-dashoffset' => array('strokeDashoffset', self::TYPE_NUMBER), 'stroke-linecap' => array('strokeLinecap', self::TYPE_NAME), 'stroke-linejoin' => array('strokeLinejoin', self::TYPE_NAME), 'stroke-miterlimit' => array('strokeMiterlimit', self::TYPE_NUMBER), 'stroke-opacity' => array('strokeOpacity', self::TYPE_NUMBER), 'stroke-width' => array('strokeWidth', self::TYPE_NUMBER), 'font-family' => array('fontFamily', self::TYPE_NAME), 'font-size' => array('fontSize', self::TYPE_NUMBER), 'font-weight' => array('fontWeight', self::TYPE_NAME), 'font-style' => array('fontStyle', self::TYPE_NAME), 'text-anchor' => array('textAnchor', self::TYPE_NAME), ); } /** * @param $attributes * * @return Style */ public function fromAttributes($attributes) { $this->fillStyles($attributes); if (isset($attributes["style"])) { $styles = self::parseCssStyle($attributes["style"]); $this->fillStyles($styles); } } public function inherit(AbstractTag $tag) { $group = $tag->getParentGroup(); if ($group) { $parent_style = $group->getStyle(); foreach ($parent_style as $_key => $_value) { if ($_value !== null) { $this->$_key = $_value; } } } } public function fromStyleSheets(AbstractTag $tag, $attributes) { $class = isset($attributes["class"]) ? preg_split('/\s+/', trim($attributes["class"])) : null; $stylesheets = $tag->getDocument()->getStyleSheets(); $styles = array(); foreach ($stylesheets as $_sc) { /** @var \Sabberworm\CSS\RuleSet\DeclarationBlock $_decl */ foreach ($_sc->getAllDeclarationBlocks() as $_decl) { /** @var \Sabberworm\CSS\Property\Selector $_selector */ foreach ($_decl->getSelectors() as $_selector) { $_selector = $_selector->getSelector(); // Match class name if ($class !== null) { foreach ($class as $_class) { if ($_selector === ".$_class") { /** @var \Sabberworm\CSS\Rule\Rule $_rule */ foreach ($_decl->getRules() as $_rule) { $styles[$_rule->getRule()] = $_rule->getValue() . ""; } break 2; } } } // Match tag name if ($_selector === $tag->tagName) { /** @var \Sabberworm\CSS\Rule\Rule $_rule */ foreach ($_decl->getRules() as $_rule) { $styles[$_rule->getRule()] = $_rule->getValue() . ""; } break; } } } } $this->fillStyles($styles); } protected function fillStyles($styles) { foreach ($this->getStyleMap() as $from => $spec) { if (isset($styles[$from])) { list($to, $type) = $spec; $value = null; switch ($type) { case self::TYPE_COLOR: $value = self::parseColor($styles[$from]); break; case self::TYPE_NUMBER: $value = ($styles[$from] === null) ? null : (float)$styles[$from]; break; default: $value = $styles[$from]; } if ($value !== null) { $this->$to = $value; } } } } static function parseColor($color) { $color = strtolower(trim($color)); $parts = preg_split('/[^,]\s+/', $color, 2); if (count($parts) == 2) { $color = $parts[1]; } else { $color = $parts[0]; } if ($color === "none") { return "none"; } // SVG color name if (isset(self::$colorNames[$color])) { return self::parseHexColor(self::$colorNames[$color]); } // Hex color if ($color[0] === "#") { return self::parseHexColor($color); } // RGB color if (strpos($color, "rgb") !== false) { return self::getTriplet($color); } // RGB color if (strpos($color, "hsl") !== false) { $triplet = self::getTriplet($color, true); if ($triplet == null) { return null; } list($h, $s, $l) = $triplet; $r = $l; $g = $l; $b = $l; $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s); if ($v > 0) { $m = $l + $l - $v; $sv = ($v - $m) / $v; $h *= 6.0; $sextant = floor($h); $fract = $h - $sextant; $vsf = $v * $sv * $fract; $mid1 = $m + $vsf; $mid2 = $v - $vsf; switch ($sextant) { case 0: $r = $v; $g = $mid1; $b = $m; break; case 1: $r = $mid2; $g = $v; $b = $m; break; case 2: $r = $m; $g = $v; $b = $mid1; break; case 3: $r = $m; $g = $mid2; $b = $v; break; case 4: $r = $mid1; $g = $m; $b = $v; break; case 5: $r = $v; $g = $m; $b = $mid2; break; } } return array( $r * 255.0, $g * 255.0, $b * 255.0, ); } // Gradient if (strpos($color, "url(#") !== false) { $i = strpos($color, "("); $j = strpos($color, ")"); // Bad url format if ($i === false || $j === false) { return null; } return trim(substr($color, $i + 1, $j - $i - 1)); } return null; } static function getTriplet($color, $percent = false) { $i = strpos($color, "("); $j = strpos($color, ")"); // Bad color value if ($i === false || $j === false) { return null; } $triplet = preg_split("/\\s*,\\s*/", trim(substr($color, $i + 1, $j - $i - 1))); if (count($triplet) != 3) { return null; } foreach (array_keys($triplet) as $c) { $triplet[$c] = trim($triplet[$c]); if ($percent) { if ($triplet[$c][strlen($triplet[$c]) - 1] === "%") { $triplet[$c] = floatval($triplet[$c]) / 100; } else { $triplet[$c] = $triplet[$c] / 255; } } else { if ($triplet[$c][strlen($triplet[$c]) - 1] === "%") { $triplet[$c] = round(floatval($triplet[$c]) * 2.55); } } } return $triplet; } static function parseHexColor($hex) { $c = array(0, 0, 0); // #FFFFFF if (isset($hex[6])) { $c[0] = hexdec(substr($hex, 1, 2)); $c[1] = hexdec(substr($hex, 3, 2)); $c[2] = hexdec(substr($hex, 5, 2)); } else { $c[0] = hexdec($hex[1] . $hex[1]); $c[1] = hexdec($hex[2] . $hex[2]); $c[2] = hexdec($hex[3] . $hex[3]); } return $c; } /** * Simple CSS parser * * @param $style * * @return array */ static function parseCssStyle($style) { $matches = array(); preg_match_all("/([a-z-]+)\\s*:\\s*([^;$]+)/si", $style, $matches, PREG_SET_ORDER); $styles = array(); foreach ($matches as $match) { $styles[$match[1]] = $match[2]; } return $styles; } /** * Convert a size to a float * * @param string $size SVG size * @param float $dpi DPI * @param float $referenceSize Reference size * * @return float|null */ static function convertSize($size, $referenceSize = 11.0, $dpi = 96.0) { $size = trim(strtolower($size)); if (is_numeric($size)) { return $size; } if ($pos = strpos($size, "px")) { return floatval(substr($size, 0, $pos)); } if ($pos = strpos($size, "pt")) { return floatval(substr($size, 0, $pos)); } if ($pos = strpos($size, "cm")) { return floatval(substr($size, 0, $pos)) * $dpi; } if ($pos = strpos($size, "%")) { return $referenceSize * substr($size, 0, $pos) / 100; } if ($pos = strpos($size, "em")) { return $referenceSize * substr($size, 0, $pos); } // TODO cm, mm, pc, in, etc return null; } static $colorNames = array( 'antiquewhite' => '#FAEBD7', 'aqua' => '#00FFFF', 'aquamarine' => '#7FFFD4', 'beige' => '#F5F5DC', 'black' => '#000000', 'blue' => '#0000FF', 'brown' => '#A52A2A', 'cadetblue' => '#5F9EA0', 'chocolate' => '#D2691E', 'cornflowerblue' => '#6495ED', 'crimson' => '#DC143C', 'darkblue' => '#00008B', 'darkgoldenrod' => '#B8860B', 'darkgreen' => '#006400', 'darkmagenta' => '#8B008B', 'darkorange' => '#FF8C00', 'darkred' => '#8B0000', 'darkseagreen' => '#8FBC8F', 'darkslategray' => '#2F4F4F', 'darkviolet' => '#9400D3', 'deepskyblue' => '#00BFFF', 'dodgerblue' => '#1E90FF', 'firebrick' => '#B22222', 'forestgreen' => '#228B22', 'fuchsia' => '#FF00FF', 'gainsboro' => '#DCDCDC', 'gold' => '#FFD700', 'gray' => '#808080', 'green' => '#008000', 'greenyellow' => '#ADFF2F', 'hotpink' => '#FF69B4', 'indigo' => '#4B0082', 'khaki' => '#F0E68C', 'lavenderblush' => '#FFF0F5', 'lemonchiffon' => '#FFFACD', 'lightcoral' => '#F08080', 'lightgoldenrodyellow' => '#FAFAD2', 'lightgreen' => '#90EE90', 'lightsalmon' => '#FFA07A', 'lightskyblue' => '#87CEFA', 'lightslategray' => '#778899', 'lightyellow' => '#FFFFE0', 'lime' => '#00FF00', 'limegreen' => '#32CD32', 'magenta' => '#FF00FF', 'maroon' => '#800000', 'mediumaquamarine' => '#66CDAA', 'mediumorchid' => '#BA55D3', 'mediumseagreen' => '#3CB371', 'mediumspringgreen' => '#00FA9A', 'mediumvioletred' => '#C71585', 'midnightblue' => '#191970', 'mintcream' => '#F5FFFA', 'moccasin' => '#FFE4B5', 'navy' => '#000080', 'olive' => '#808000', 'orange' => '#FFA500', 'orchid' => '#DA70D6', 'palegreen' => '#98FB98', 'palevioletred' => '#D87093', 'peachpuff' => '#FFDAB9', 'pink' => '#FFC0CB', 'powderblue' => '#B0E0E6', 'purple' => '#800080', 'red' => '#FF0000', 'royalblue' => '#4169E1', 'salmon' => '#FA8072', 'seagreen' => '#2E8B57', 'sienna' => '#A0522D', 'silver' => '#C0C0C0', 'skyblue' => '#87CEEB', 'slategray' => '#708090', 'springgreen' => '#00FF7F', 'steelblue' => '#4682B4', 'tan' => '#D2B48C', 'teal' => '#008080', 'thistle' => '#D8BFD8', 'turquoise' => '#40E0D0', 'violetred' => '#D02090', 'white' => '#FFFFFF', 'yellow' => '#FFFF00', 'aliceblue' => '#f0f8ff', 'azure' => '#f0ffff', 'bisque' => '#ffe4c4', 'blanchedalmond' => '#ffebcd', 'blueviolet' => '#8a2be2', 'burlywood' => '#deb887', 'chartreuse' => '#7fff00', 'coral' => '#ff7f50', 'cornsilk' => '#fff8dc', 'cyan' => '#00ffff', 'darkcyan' => '#008b8b', 'darkgray' => '#a9a9a9', 'darkgrey' => '#a9a9a9', 'darkkhaki' => '#bdb76b', 'darkolivegreen' => '#556b2f', 'darkorchid' => '#9932cc', 'darksalmon' => '#e9967a', 'darkslateblue' => '#483d8b', 'darkslategrey' => '#2f4f4f', 'darkturquoise' => '#00ced1', 'deeppink' => '#ff1493', 'dimgray' => '#696969', 'dimgrey' => '#696969', 'floralwhite' => '#fffaf0', 'ghostwhite' => '#f8f8ff', 'goldenrod' => '#daa520', 'grey' => '#808080', 'honeydew' => '#f0fff0', 'indianred' => '#cd5c5c', 'ivory' => '#fffff0', 'lavender' => '#e6e6fa', 'lawngreen' => '#7cfc00', 'lightblue' => '#add8e6', 'lightcyan' => '#e0ffff', 'lightgray' => '#d3d3d3', 'lightgrey' => '#d3d3d3', 'lightpink' => '#ffb6c1', 'lightseagreen' => '#20b2aa', 'lightslategrey' => '#778899', 'lightsteelblue' => '#b0c4de', 'linen' => '#faf0e6', 'mediumblue' => '#0000cd', 'mediumpurple' => '#9370db', 'mediumslateblue' => '#7b68ee', 'mediumturquoise' => '#48d1cc', 'mistyrose' => '#ffe4e1', 'navajowhite' => '#ffdead', 'oldlace' => '#fdf5e6', 'olivedrab' => '#6b8e23', 'orangered' => '#ff4500', 'palegoldenrod' => '#eee8aa', 'paleturquoise' => '#afeeee', 'papayawhip' => '#ffefd5', 'peru' => '#cd853f', 'plum' => '#dda0dd', 'rosybrown' => '#bc8f8f', 'saddlebrown' => '#8b4513', 'sandybrown' => '#f4a460', 'seashell' => '#fff5ee', 'slateblue' => '#6a5acd', 'slategrey' => '#708090', 'snow' => '#fffafa', 'tomato' => '#ff6347', 'violet' => '#ee82ee', 'wheat' => '#f5deb3', 'whitesmoke' => '#f5f5f5', 'yellowgreen' => '#9acd32', ); } PK!\S%%Aconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Document.phpnu[ * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html */ namespace Svg; use Svg\Surface\SurfaceInterface; use Svg\Tag\AbstractTag; use Svg\Tag\Anchor; use Svg\Tag\Circle; use Svg\Tag\Ellipse; use Svg\Tag\Group; use Svg\Tag\ClipPath; use Svg\Tag\Image; use Svg\Tag\Line; use Svg\Tag\LinearGradient; use Svg\Tag\Path; use Svg\Tag\Polygon; use Svg\Tag\Polyline; use Svg\Tag\Rect; use Svg\Tag\Stop; use Svg\Tag\Text; use Svg\Tag\StyleTag; use Svg\Tag\UseTag; class Document extends AbstractTag { protected $filename; public $inDefs = false; protected $x; protected $y; protected $width; protected $height; protected $subPathInit; protected $pathBBox; protected $viewBox; /** @var SurfaceInterface */ protected $surface; /** @var AbstractTag[] */ protected $stack = array(); /** @var AbstractTag[] */ protected $defs = array(); /** @var \Sabberworm\CSS\CSSList\Document[] */ protected $styleSheets = array(); public function loadFile($filename) { $this->filename = $filename; } protected function initParser() { $parser = xml_parser_create("utf-8"); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); xml_set_element_handler( $parser, array($this, "_tagStart"), array($this, "_tagEnd") ); xml_set_character_data_handler( $parser, array($this, "_charData") ); return $parser; } public function __construct() { } /** * @return SurfaceInterface */ public function getSurface() { return $this->surface; } public function getStack() { return $this->stack; } public function getWidth() { return $this->width; } public function getHeight() { return $this->height; } public function getDimensions() { $rootAttributes = null; $parser = xml_parser_create("utf-8"); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); xml_set_element_handler( $parser, function ($parser, $name, $attributes) use (&$rootAttributes) { if ($name === "svg" && $rootAttributes === null) { $attributes = array_change_key_case($attributes, CASE_LOWER); $rootAttributes = $attributes; } }, function ($parser, $name) {} ); $fp = fopen($this->filename, "r"); while ($line = fread($fp, 8192)) { xml_parse($parser, $line, false); if ($rootAttributes !== null) { break; } } xml_parser_free($parser); return $this->handleSizeAttributes($rootAttributes); } public function handleSizeAttributes($attributes){ if ($this->width === null) { if (isset($attributes["width"])) { $width = Style::convertSize($attributes["width"], 400); $this->width = $width; } if (isset($attributes["height"])) { $height = Style::convertSize($attributes["height"], 300); $this->height = $height; } if (isset($attributes['viewbox'])) { $viewBox = preg_split('/[\s,]+/is', trim($attributes['viewbox'])); if (count($viewBox) == 4) { $this->x = $viewBox[0]; $this->y = $viewBox[1]; if (!$this->width) { $this->width = $viewBox[2]; } if (!$this->height) { $this->height = $viewBox[3]; } } } } return array( 0 => $this->width, 1 => $this->height, "width" => $this->width, "height" => $this->height, ); } public function getDocument(){ return $this; } /** * Append a style sheet * * @param \Sabberworm\CSS\CSSList\Document $stylesheet */ public function appendStyleSheet($stylesheet) { $this->styleSheets[] = $stylesheet; } /** * Get the document style sheets * * @return \Sabberworm\CSS\CSSList\Document[] */ public function getStyleSheets() { return $this->styleSheets; } protected function before($attributes) { $surface = $this->getSurface(); $style = new DefaultStyle(); $style->inherit($this); $style->fromAttributes($attributes); $this->setStyle($style); $surface->setStyle($style); } public function render(SurfaceInterface $surface) { $this->inDefs = false; $this->surface = $surface; $parser = $this->initParser(); if ($this->x || $this->y) { $surface->translate(-$this->x, -$this->y); } $fp = fopen($this->filename, "r"); while ($line = fread($fp, 8192)) { xml_parse($parser, $line, false); } xml_parse($parser, "", true); xml_parser_free($parser); } protected function svgOffset($attributes) { $this->attributes = $attributes; $this->handleSizeAttributes($attributes); } public function getDef($id) { $id = ltrim($id, "#"); return isset($this->defs[$id]) ? $this->defs[$id] : null; } private function _tagStart($parser, $name, $attributes) { $this->x = 0; $this->y = 0; $tag = null; $attributes = array_change_key_case($attributes, CASE_LOWER); switch (strtolower($name)) { case 'defs': $this->inDefs = true; return; case 'svg': if (count($this->attributes)) { $tag = new Group($this, $name); } else { $tag = $this; $this->svgOffset($attributes); } break; case 'path': $tag = new Path($this, $name); break; case 'rect': $tag = new Rect($this, $name); break; case 'circle': $tag = new Circle($this, $name); break; case 'ellipse': $tag = new Ellipse($this, $name); break; case 'image': $tag = new Image($this, $name); break; case 'line': $tag = new Line($this, $name); break; case 'polyline': $tag = new Polyline($this, $name); break; case 'polygon': $tag = new Polygon($this, $name); break; case 'lineargradient': $tag = new LinearGradient($this, $name); break; case 'radialgradient': $tag = new LinearGradient($this, $name); break; case 'stop': $tag = new Stop($this, $name); break; case 'style': $tag = new StyleTag($this, $name); break; case 'a': $tag = new Anchor($this, $name); break; case 'g': case 'symbol': $tag = new Group($this, $name); break; case 'clippath': $tag = new ClipPath($this, $name); break; case 'use': $tag = new UseTag($this, $name); break; case 'text': $tag = new Text($this, $name); break; case 'desc': return; } if ($tag) { if (isset($attributes["id"])) { $this->defs[$attributes["id"]] = $tag; } else { /** @var AbstractTag $top */ $top = end($this->stack); if ($top && $top != $tag) { $top->children[] = $tag; } } $this->stack[] = $tag; $tag->handle($attributes); } } function _charData($parser, $data) { $stack_top = end($this->stack); if ($stack_top instanceof Text || $stack_top instanceof StyleTag) { $stack_top->appendText($data); } } function _tagEnd($parser, $name) { /** @var AbstractTag $tag */ $tag = null; switch (strtolower($name)) { case 'defs': $this->inDefs = false; return; case 'svg': case 'path': case 'rect': case 'circle': case 'ellipse': case 'image': case 'line': case 'polyline': case 'polygon': case 'radialgradient': case 'lineargradient': case 'stop': case 'style': case 'text': case 'g': case 'symbol': case 'clippath': case 'use': case 'a': $tag = array_pop($this->stack); break; } if (!$this->inDefs && $tag) { $tag->handleEnd(); } } } PK!k//>convertformstools/pdf/dompdf/lib/php-css-parser/src/Parser.phpnu[oParserState = new ParserState($sText, $oParserSettings, $iLineNo); } /** * @param string $sCharset * * @return void */ public function setCharset($sCharset) { $this->oParserState->setCharset($sCharset); } /** * @return void */ public function getCharset() { // Note: The `return` statement is missing here. This is a bug that needs to be fixed. $this->oParserState->getCharset(); } /** * @return Document * * @throws SourceException */ public function parse() { return Document::parse($this->oParserState); } } PK!FE66Iconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/CSSFunction.phpnu[ $aArguments * @param string $sSeparator * @param int $iLineNo */ public function __construct($sName, $aArguments, $sSeparator = ',', $iLineNo = 0) { if ($aArguments instanceof RuleValueList) { $sSeparator = $aArguments->getListSeparator(); $aArguments = $aArguments->getListComponents(); } $this->sName = $sName; $this->iLineNo = $iLineNo; parent::__construct($aArguments, $sSeparator, $iLineNo); } /** * @return string */ public function getName() { return $this->sName; } /** * @param string $sName * * @return void */ public function setName($sName) { $this->sName = $sName; } /** * @return array */ public function getArguments() { return $this->aComponents; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $aArguments = parent::render($oOutputFormat); return "{$this->sName}({$aArguments})"; } } PK!r  Aconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/URL.phpnu[oURL = $oURL; } /** * @return URL * * @throws SourceException * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public static function parse(ParserState $oParserState) { $bUseUrl = $oParserState->comes('url', true); if ($bUseUrl) { $oParserState->consume('url'); $oParserState->consumeWhiteSpace(); $oParserState->consume('('); } $oParserState->consumeWhiteSpace(); $oResult = new URL(CSSString::parse($oParserState), $oParserState->currentLine()); if ($bUseUrl) { $oParserState->consumeWhiteSpace(); $oParserState->consume(')'); } return $oResult; } /** * @return void */ public function setURL(CSSString $oURL) { $this->oURL = $oURL; } /** * @return CSSString */ public function getURL() { return $this->oURL; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { return "url({$this->oURL->render($oOutputFormat)})"; } } PK!YP P Jconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/CalcFunction.phpnu[consumeUntil('(', false, true)); $oCalcList = new CalcRuleValueList($oParserState->currentLine()); $oList = new RuleValueList(',', $oParserState->currentLine()); $iNestingLevel = 0; $iLastComponentType = null; while (!$oParserState->comes(')') || $iNestingLevel > 0) { $oParserState->consumeWhiteSpace(); if ($oParserState->comes('(')) { $iNestingLevel++; $oCalcList->addListComponent($oParserState->consume(1)); $oParserState->consumeWhiteSpace(); continue; } elseif ($oParserState->comes(')')) { $iNestingLevel--; $oCalcList->addListComponent($oParserState->consume(1)); $oParserState->consumeWhiteSpace(); continue; } if ($iLastComponentType != CalcFunction::T_OPERAND) { $oVal = Value::parsePrimitiveValue($oParserState); $oCalcList->addListComponent($oVal); $iLastComponentType = CalcFunction::T_OPERAND; } else { if (in_array($oParserState->peek(), $aOperators)) { if (($oParserState->comes('-') || $oParserState->comes('+'))) { if ( $oParserState->peek(1, -1) != ' ' || !($oParserState->comes('- ') || $oParserState->comes('+ ')) ) { throw new UnexpectedTokenException( " {$oParserState->peek()} ", $oParserState->peek(1, -1) . $oParserState->peek(2), 'literal', $oParserState->currentLine() ); } } $oCalcList->addListComponent($oParserState->consume(1)); $iLastComponentType = CalcFunction::T_OPERATOR; } else { throw new UnexpectedTokenException( sprintf( 'Next token was expected to be an operand of type %s. Instead "%s" was found.', implode(', ', $aOperators), $oVal ), '', 'custom', $oParserState->currentLine() ); } } $oParserState->consumeWhiteSpace(); } $oList->addListComponent($oCalcList); $oParserState->consume(')'); return new CalcFunction($sFunction, $oList, ',', $oParserState->currentLine()); } } PK!>emOconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/CalcRuleValueList.phpnu[implode(' ', $this->aComponents); } } PK!s3Lconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/PrimitiveValue.phpnu[ */ protected $aComponents; /** * @var string */ protected $sSeparator; /** * phpcs:ignore Generic.Files.LineLength * @param array|RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string $aComponents * @param string $sSeparator * @param int $iLineNo */ public function __construct($aComponents = [], $sSeparator = ',', $iLineNo = 0) { parent::__construct($iLineNo); if (!is_array($aComponents)) { $aComponents = [$aComponents]; } $this->aComponents = $aComponents; $this->sSeparator = $sSeparator; } /** * @param RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string $mComponent * * @return void */ public function addListComponent($mComponent) { $this->aComponents[] = $mComponent; } /** * @return array */ public function getListComponents() { return $this->aComponents; } /** * @param array $aComponents * * @return void */ public function setListComponents(array $aComponents) { $this->aComponents = $aComponents; } /** * @return string */ public function getListSeparator() { return $this->sSeparator; } /** * @param string $sSeparator * * @return void */ public function setListSeparator($sSeparator) { $this->sSeparator = $sSeparator; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { return $oOutputFormat->implode( $oOutputFormat->spaceBeforeListArgumentSeparator($this->sSeparator) . $this->sSeparator . $oOutputFormat->spaceAfterListArgumentSeparator($this->sSeparator), $this->aComponents ); } } PK!Oܧ Gconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/CSSString.phpnu[sString = $sString; parent::__construct($iLineNo); } /** * @return CSSString * * @throws SourceException * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public static function parse(ParserState $oParserState) { $sBegin = $oParserState->peek(); $sQuote = null; if ($sBegin === "'") { $sQuote = "'"; } elseif ($sBegin === '"') { $sQuote = '"'; } if ($sQuote !== null) { $oParserState->consume($sQuote); } $sResult = ""; $sContent = null; if ($sQuote === null) { // Unquoted strings end in whitespace or with braces, brackets, parentheses while (!preg_match('/[\\s{}()<>\\[\\]]/isu', $oParserState->peek())) { $sResult .= $oParserState->parseCharacter(false); } } else { while (!$oParserState->comes($sQuote)) { $sContent = $oParserState->parseCharacter(false); if ($sContent === null) { throw new SourceException( "Non-well-formed quoted string {$oParserState->peek(3)}", $oParserState->currentLine() ); } $sResult .= $sContent; } $oParserState->consume($sQuote); } return new CSSString($sResult, $oParserState->currentLine()); } /** * @param string $sString * * @return void */ public function setString($sString) { $this->sString = $sString; } /** * @return string */ public function getString() { return $this->sString; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $sString = addslashes($this->sString); $sString = str_replace("\n", '\A', $sString); return $oOutputFormat->getStringQuotingType() . $sString . $oOutputFormat->getStringQuotingType(); } } PK!hrBconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/Size.phpnu[ */ const ABSOLUTE_SIZE_UNITS = ['px', 'cm', 'mm', 'mozmm', 'in', 'pt', 'pc', 'vh', 'vw', 'vmin', 'vmax', 'rem']; /** * @var array */ const RELATIVE_SIZE_UNITS = ['%', 'em', 'ex', 'ch', 'fr']; /** * @var array */ const NON_SIZE_UNITS = ['deg', 'grad', 'rad', 's', 'ms', 'turns', 'Hz', 'kHz']; /** * @var array>|null */ private static $SIZE_UNITS = null; /** * @var float */ private $fSize; /** * @var string|null */ private $sUnit; /** * @var bool */ private $bIsColorComponent; /** * @param float|int|string $fSize * @param string|null $sUnit * @param bool $bIsColorComponent * @param int $iLineNo */ public function __construct($fSize, $sUnit = null, $bIsColorComponent = false, $iLineNo = 0) { parent::__construct($iLineNo); $this->fSize = (float)$fSize; $this->sUnit = $sUnit; $this->bIsColorComponent = $bIsColorComponent; } /** * @param bool $bIsColorComponent * * @return Size * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public static function parse(ParserState $oParserState, $bIsColorComponent = false) { $sSize = ''; if ($oParserState->comes('-')) { $sSize .= $oParserState->consume('-'); } while (is_numeric($oParserState->peek()) || $oParserState->comes('.')) { if ($oParserState->comes('.')) { $sSize .= $oParserState->consume('.'); } else { $sSize .= $oParserState->consume(1); } } $sUnit = null; $aSizeUnits = self::getSizeUnits(); foreach ($aSizeUnits as $iLength => &$aValues) { $sKey = strtolower($oParserState->peek($iLength)); if (array_key_exists($sKey, $aValues)) { if (($sUnit = $aValues[$sKey]) !== null) { $oParserState->consume($iLength); break; } } } return new Size((float)$sSize, $sUnit, $bIsColorComponent, $oParserState->currentLine()); } /** * @return array> */ private static function getSizeUnits() { if (!is_array(self::$SIZE_UNITS)) { self::$SIZE_UNITS = []; foreach (array_merge(self::ABSOLUTE_SIZE_UNITS, self::RELATIVE_SIZE_UNITS, self::NON_SIZE_UNITS) as $val) { $iSize = strlen($val); if (!isset(self::$SIZE_UNITS[$iSize])) { self::$SIZE_UNITS[$iSize] = []; } self::$SIZE_UNITS[$iSize][strtolower($val)] = $val; } krsort(self::$SIZE_UNITS, SORT_NUMERIC); } return self::$SIZE_UNITS; } /** * @param string $sUnit * * @return void */ public function setUnit($sUnit) { $this->sUnit = $sUnit; } /** * @return string|null */ public function getUnit() { return $this->sUnit; } /** * @param float|int|string $fSize */ public function setSize($fSize) { $this->fSize = (float)$fSize; } /** * @return float */ public function getSize() { return $this->fSize; } /** * @return bool */ public function isColorComponent() { return $this->bIsColorComponent; } /** * Returns whether the number stored in this Size really represents a size (as in a length of something on screen). * * @return false if the unit an angle, a duration, a frequency or the number is a component in a Color object. */ public function isSize() { if (in_array($this->sUnit, self::NON_SIZE_UNITS, true)) { return false; } return !$this->isColorComponent(); } /** * @return bool */ public function isRelative() { if (in_array($this->sUnit, self::RELATIVE_SIZE_UNITS, true)) { return true; } if ($this->sUnit === null && $this->fSize != 0) { return true; } return false; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $l = localeconv(); $sPoint = preg_quote($l['decimal_point'], '/'); $sSize = preg_match("/[\d\.]+e[+-]?\d+/i", (string)$this->fSize) ? preg_replace("/$sPoint?0+$/", "", sprintf("%f", $this->fSize)) : $this->fSize; return preg_replace(["/$sPoint/", "/^(-?)0\./"], ['.', '$1.'], $sSize) . ($this->sUnit === null ? '' : $this->sUnit); } } PK!p##Kconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/RuleValueList.phpnu[iLineNo = $iLineNo; } /** * @param array $aListDelimiters * * @return RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string * * @throws UnexpectedTokenException * @throws UnexpectedEOFException */ public static function parseValue(ParserState $oParserState, array $aListDelimiters = []) { /** @var array $aStack */ $aStack = []; $oParserState->consumeWhiteSpace(); //Build a list of delimiters and parsed values while ( !($oParserState->comes('}') || $oParserState->comes(';') || $oParserState->comes('!') || $oParserState->comes(')') || $oParserState->comes('\\')) ) { if (count($aStack) > 0) { $bFoundDelimiter = false; foreach ($aListDelimiters as $sDelimiter) { if ($oParserState->comes($sDelimiter)) { array_push($aStack, $oParserState->consume($sDelimiter)); $oParserState->consumeWhiteSpace(); $bFoundDelimiter = true; break; } } if (!$bFoundDelimiter) { //Whitespace was the list delimiter array_push($aStack, ' '); } } array_push($aStack, self::parsePrimitiveValue($oParserState)); $oParserState->consumeWhiteSpace(); } // Convert the list to list objects foreach ($aListDelimiters as $sDelimiter) { if (count($aStack) === 1) { return $aStack[0]; } $iStartPosition = null; while (($iStartPosition = array_search($sDelimiter, $aStack, true)) !== false) { $iLength = 2; //Number of elements to be joined for ($i = $iStartPosition + 2; $i < count($aStack); $i += 2, ++$iLength) { if ($sDelimiter !== $aStack[$i]) { break; } } $oList = new RuleValueList($sDelimiter, $oParserState->currentLine()); for ($i = $iStartPosition - 1; $i - $iStartPosition + 1 < $iLength * 2; $i += 2) { $oList->addListComponent($aStack[$i]); } array_splice($aStack, $iStartPosition - 1, $iLength * 2 - 1, [$oList]); } } if (!isset($aStack[0])) { throw new UnexpectedTokenException( " {$oParserState->peek()} ", $oParserState->peek(1, -1) . $oParserState->peek(2), 'literal', $oParserState->currentLine() ); } return $aStack[0]; } /** * @param bool $bIgnoreCase * * @return CSSFunction|string * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public static function parseIdentifierOrFunction(ParserState $oParserState, $bIgnoreCase = false) { $sResult = $oParserState->parseIdentifier($bIgnoreCase); if ($oParserState->comes('(')) { $oParserState->consume('('); $aArguments = Value::parseValue($oParserState, ['=', ' ', ',']); $sResult = new CSSFunction($sResult, $aArguments, ',', $oParserState->currentLine()); $oParserState->consume(')'); } return $sResult; } /** * @return CSSFunction|CSSString|LineName|Size|URL|string * * @throws UnexpectedEOFException * @throws UnexpectedTokenException * @throws SourceException */ public static function parsePrimitiveValue(ParserState $oParserState) { $oValue = null; $oParserState->consumeWhiteSpace(); if ( is_numeric($oParserState->peek()) || ($oParserState->comes('-.') && is_numeric($oParserState->peek(1, 2))) || (($oParserState->comes('-') || $oParserState->comes('.')) && is_numeric($oParserState->peek(1, 1))) ) { $oValue = Size::parse($oParserState); } elseif ($oParserState->comes('#') || $oParserState->comes('rgb', true) || $oParserState->comes('hsl', true)) { $oValue = Color::parse($oParserState); } elseif ($oParserState->comes('url', true)) { $oValue = URL::parse($oParserState); } elseif ( $oParserState->comes('calc', true) || $oParserState->comes('-webkit-calc', true) || $oParserState->comes('-moz-calc', true) ) { $oValue = CalcFunction::parse($oParserState); } elseif ($oParserState->comes("'") || $oParserState->comes('"')) { $oValue = CSSString::parse($oParserState); } elseif ($oParserState->comes("progid:") && $oParserState->getSettings()->bLenientParsing) { $oValue = self::parseMicrosoftFilter($oParserState); } elseif ($oParserState->comes("[")) { $oValue = LineName::parse($oParserState); } elseif ($oParserState->comes("U+")) { $oValue = self::parseUnicodeRangeValue($oParserState); } else { $oValue = self::parseIdentifierOrFunction($oParserState); } $oParserState->consumeWhiteSpace(); return $oValue; } /** * @return CSSFunction * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ private static function parseMicrosoftFilter(ParserState $oParserState) { $sFunction = $oParserState->consumeUntil('(', false, true); $aArguments = Value::parseValue($oParserState, [',', '=']); return new CSSFunction($sFunction, $aArguments, ',', $oParserState->currentLine()); } /** * @return string * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ private static function parseUnicodeRangeValue(ParserState $oParserState) { $iCodepointMaxLength = 6; // Code points outside BMP can use up to six digits $sRange = ""; $oParserState->consume("U+"); do { if ($oParserState->comes('-')) { $iCodepointMaxLength = 13; // Max length is 2 six digit code points + the dash(-) between them } $sRange .= $oParserState->consume(1); } while (strlen($sRange) < $iCodepointMaxLength && preg_match("/[A-Fa-f0-9\?-]/", $oParserState->peek())); return "U+{$sRange}"; } /** * @return int */ public function getLineNo() { return $this->iLineNo; } } PK!ԙ  Fconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/LineName.phpnu[ $aComponents * @param int $iLineNo */ public function __construct(array $aComponents = [], $iLineNo = 0) { parent::__construct($aComponents, ' ', $iLineNo); } /** * @return LineName * * @throws UnexpectedTokenException * @throws UnexpectedEOFException */ public static function parse(ParserState $oParserState) { $oParserState->consume('['); $oParserState->consumeWhiteSpace(); $aNames = []; do { if ($oParserState->getSettings()->bLenientParsing) { try { $aNames[] = $oParserState->parseIdentifier(); } catch (UnexpectedTokenException $e) { if (!$oParserState->comes(']')) { throw $e; } } } else { $aNames[] = $oParserState->parseIdentifier(); } $oParserState->consumeWhiteSpace(); } while (!$oParserState->comes(']')); $oParserState->consume(']'); return new LineName($aNames, $oParserState->currentLine()); } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { return '[' . parent::render(OutputFormat::createCompact()) . ']'; } } PK!<Cconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/Color.phpnu[ $aColor * @param int $iLineNo */ public function __construct(array $aColor, $iLineNo = 0) { parent::__construct(implode('', array_keys($aColor)), $aColor, ',', $iLineNo); } /** * @return Color|CSSFunction * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public static function parse(ParserState $oParserState) { $aColor = []; if ($oParserState->comes('#')) { $oParserState->consume('#'); $sValue = $oParserState->parseIdentifier(false); if ($oParserState->strlen($sValue) === 3) { $sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2]; } elseif ($oParserState->strlen($sValue) === 4) { $sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2] . $sValue[3] . $sValue[3]; } if ($oParserState->strlen($sValue) === 8) { $aColor = [ 'r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $oParserState->currentLine()), 'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $oParserState->currentLine()), 'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $oParserState->currentLine()), 'a' => new Size( round(self::mapRange(intval($sValue[6] . $sValue[7], 16), 0, 255, 0, 1), 2), null, true, $oParserState->currentLine() ), ]; } else { $aColor = [ 'r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $oParserState->currentLine()), 'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $oParserState->currentLine()), 'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $oParserState->currentLine()), ]; } } else { $sColorMode = $oParserState->parseIdentifier(true); $oParserState->consumeWhiteSpace(); $oParserState->consume('('); $bContainsVar = false; $iLength = $oParserState->strlen($sColorMode); for ($i = 0; $i < $iLength; ++$i) { $oParserState->consumeWhiteSpace(); if ($oParserState->comes('var')) { $aColor[$sColorMode[$i]] = CSSFunction::parseIdentifierOrFunction($oParserState); $bContainsVar = true; } else { $aColor[$sColorMode[$i]] = Size::parse($oParserState, true); } if ($bContainsVar && $oParserState->comes(')')) { // With a var argument the function can have fewer arguments break; } $oParserState->consumeWhiteSpace(); if ($i < ($iLength - 1)) { $oParserState->consume(','); } } $oParserState->consume(')'); if ($bContainsVar) { return new CSSFunction($sColorMode, array_values($aColor), ',', $oParserState->currentLine()); } } return new Color($aColor, $oParserState->currentLine()); } /** * @param float $fVal * @param float $fFromMin * @param float $fFromMax * @param float $fToMin * @param float $fToMax * * @return float */ private static function mapRange($fVal, $fFromMin, $fFromMax, $fToMin, $fToMax) { $fFromRange = $fFromMax - $fFromMin; $fToRange = $fToMax - $fToMin; $fMultiplier = $fToRange / $fFromRange; $fNewVal = $fVal - $fFromMin; $fNewVal *= $fMultiplier; return $fNewVal + $fToMin; } /** * @return array */ public function getColor() { return $this->aComponents; } /** * @param array $aColor * * @return void */ public function setColor(array $aColor) { $this->setName(implode('', array_keys($aColor))); $this->aComponents = $aColor; } /** * @return string */ public function getColorDescription() { return $this->getName(); } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { // Shorthand RGB color values if ($oOutputFormat->getRGBHashNotation() && implode('', array_keys($this->aComponents)) === 'rgb') { $sResult = sprintf( '%02x%02x%02x', $this->aComponents['r']->getSize(), $this->aComponents['g']->getSize(), $this->aComponents['b']->getSize() ); return '#' . (($sResult[0] == $sResult[1]) && ($sResult[2] == $sResult[3]) && ($sResult[4] == $sResult[5]) ? "$sResult[0]$sResult[2]$sResult[4]" : $sResult); } return parent::render($oOutputFormat); } } PK!1nHconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/KeyFrame.phpnu[vendorKeyFrame = null; $this->animationName = null; } /** * @param string $vendorKeyFrame */ public function setVendorKeyFrame($vendorKeyFrame) { $this->vendorKeyFrame = $vendorKeyFrame; } /** * @return string|null */ public function getVendorKeyFrame() { return $this->vendorKeyFrame; } /** * @param string $animationName */ public function setAnimationName($animationName) { $this->animationName = $animationName; } /** * @return string|null */ public function getAnimationName() { return $this->animationName; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $sResult = "@{$this->vendorKeyFrame} {$this->animationName}{$oOutputFormat->spaceBeforeOpeningBrace()}{"; $sResult .= parent::render($oOutputFormat); $sResult .= '}'; return $sResult; } /** * @return bool */ public function isRootList() { return false; } /** * @return string|null */ public function atRuleName() { return $this->vendorKeyFrame; } /** * @return string|null */ public function atRuleArgs() { return $this->animationName; } } PK!THconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/Document.phpnu[currentLine()); CSSList::parseList($oParserState, $oDocument); return $oDocument; } /** * Gets all `DeclarationBlock` objects recursively. * * @return array */ public function getAllDeclarationBlocks() { /** @var array $aResult */ $aResult = []; $this->allDeclarationBlocks($aResult); return $aResult; } /** * Gets all `DeclarationBlock` objects recursively. * * @return array * * @deprecated will be removed in version 9.0; use `getAllDeclarationBlocks()` instead */ public function getAllSelectors() { return $this->getAllDeclarationBlocks(); } /** * Returns all `RuleSet` objects found recursively in the tree. * * @return array */ public function getAllRuleSets() { /** @var array $aResult */ $aResult = []; $this->allRuleSets($aResult); return $aResult; } /** * Returns all `Value` objects found recursively in the tree. * * @param CSSList|RuleSet|string $mElement * the `CSSList` or `RuleSet` to start the search from (defaults to the whole document). * If a string is given, it is used as rule name filter. * @param bool $bSearchInFunctionArguments whether to also return Value objects used as Function arguments. * * @return array * * @see RuleSet->getRules() */ public function getAllValues($mElement = null, $bSearchInFunctionArguments = false) { $sSearchString = null; if ($mElement === null) { $mElement = $this; } elseif (is_string($mElement)) { $sSearchString = $mElement; $mElement = $this; } /** @var array $aResult */ $aResult = []; $this->allValues($mElement, $aResult, $sSearchString, $bSearchInFunctionArguments); return $aResult; } /** * Returns all `Selector` objects found recursively in the tree. * * Note that this does not yield the full `DeclarationBlock` that the selector belongs to * (and, currently, there is no way to get to that). * * @param string|null $sSpecificitySearch * An optional filter by specificity. * May contain a comparison operator and a number or just a number (defaults to "=="). * * @return array * @example `getSelectorsBySpecificity('>= 100')` * */ public function getSelectorsBySpecificity($sSpecificitySearch = null) { /** @var array $aResult */ $aResult = []; $this->allSelectors($aResult, $sSpecificitySearch); return $aResult; } /** * Expands all shorthand properties to their long value. * * @return void */ public function expandShorthands() { foreach ($this->getAllDeclarationBlocks() as $oDeclaration) { $oDeclaration->expandShorthands(); } } /** * Create shorthands properties whenever possible. * * @return void */ public function createShorthands() { foreach ($this->getAllDeclarationBlocks() as $oDeclaration) { $oDeclaration->createShorthands(); } } /** * Overrides `render()` to make format argument optional. * * @param OutputFormat|null $oOutputFormat * * @return string */ public function render(OutputFormat $oOutputFormat = null) { if ($oOutputFormat === null) { $oOutputFormat = new OutputFormat(); } return parent::render($oOutputFormat); } /** * @return bool */ public function isRootList() { return true; } } PK!c=n==Gconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/CSSList.phpnu[ */ protected $aComments; /** * @var array */ protected $aContents; /** * @var int */ protected $iLineNo; /** * @param int $iLineNo */ public function __construct($iLineNo = 0) { $this->aComments = []; $this->aContents = []; $this->iLineNo = $iLineNo; } /** * @return void * * @throws UnexpectedTokenException * @throws SourceException */ public static function parseList(ParserState $oParserState, CSSList $oList) { $bIsRoot = $oList instanceof Document; if (is_string($oParserState)) { $oParserState = new ParserState($oParserState, Settings::create()); } $bLenientParsing = $oParserState->getSettings()->bLenientParsing; while (!$oParserState->isEnd()) { $comments = $oParserState->consumeWhiteSpace(); $oListItem = null; if ($bLenientParsing) { try { $oListItem = self::parseListItem($oParserState, $oList); } catch (UnexpectedTokenException $e) { $oListItem = false; } } else { $oListItem = self::parseListItem($oParserState, $oList); } if ($oListItem === null) { // List parsing finished return; } if ($oListItem) { $oListItem->setComments($comments); $oList->append($oListItem); } $oParserState->consumeWhiteSpace(); } if (!$bIsRoot && !$bLenientParsing) { throw new SourceException("Unexpected end of document", $oParserState->currentLine()); } } /** * @return AtRuleBlockList|KeyFrame|Charset|CSSNamespace|Import|AtRuleSet|DeclarationBlock|null|false * * @throws SourceException * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ private static function parseListItem(ParserState $oParserState, CSSList $oList) { $bIsRoot = $oList instanceof Document; if ($oParserState->comes('@')) { $oAtRule = self::parseAtRule($oParserState); if ($oAtRule instanceof Charset) { if (!$bIsRoot) { throw new UnexpectedTokenException( '@charset may only occur in root document', '', 'custom', $oParserState->currentLine() ); } if (count($oList->getContents()) > 0) { throw new UnexpectedTokenException( '@charset must be the first parseable token in a document', '', 'custom', $oParserState->currentLine() ); } $oParserState->setCharset($oAtRule->getCharset()->getString()); } return $oAtRule; } elseif ($oParserState->comes('}')) { if (!$oParserState->getSettings()->bLenientParsing) { throw new UnexpectedTokenException('CSS selector', '}', 'identifier', $oParserState->currentLine()); } else { if ($bIsRoot) { if ($oParserState->getSettings()->bLenientParsing) { return DeclarationBlock::parse($oParserState); } else { throw new SourceException("Unopened {", $oParserState->currentLine()); } } else { return null; } } } else { return DeclarationBlock::parse($oParserState, $oList); } } /** * @param ParserState $oParserState * * @return AtRuleBlockList|KeyFrame|Charset|CSSNamespace|Import|AtRuleSet|null * * @throws SourceException * @throws UnexpectedTokenException * @throws UnexpectedEOFException */ private static function parseAtRule(ParserState $oParserState) { $oParserState->consume('@'); $sIdentifier = $oParserState->parseIdentifier(); $iIdentifierLineNum = $oParserState->currentLine(); $oParserState->consumeWhiteSpace(); if ($sIdentifier === 'import') { $oLocation = URL::parse($oParserState); $oParserState->consumeWhiteSpace(); $sMediaQuery = null; if (!$oParserState->comes(';')) { $sMediaQuery = trim($oParserState->consumeUntil([';', ParserState::EOF])); } $oParserState->consumeUntil([';', ParserState::EOF], true, true); return new Import($oLocation, $sMediaQuery ?: null, $iIdentifierLineNum); } elseif ($sIdentifier === 'charset') { $sCharset = CSSString::parse($oParserState); $oParserState->consumeWhiteSpace(); $oParserState->consumeUntil([';', ParserState::EOF], true, true); return new Charset($sCharset, $iIdentifierLineNum); } elseif (self::identifierIs($sIdentifier, 'keyframes')) { $oResult = new KeyFrame($iIdentifierLineNum); $oResult->setVendorKeyFrame($sIdentifier); $oResult->setAnimationName(trim($oParserState->consumeUntil('{', false, true))); CSSList::parseList($oParserState, $oResult); if ($oParserState->comes('}')) { $oParserState->consume('}'); } return $oResult; } elseif ($sIdentifier === 'namespace') { $sPrefix = null; $mUrl = Value::parsePrimitiveValue($oParserState); if (!$oParserState->comes(';')) { $sPrefix = $mUrl; $mUrl = Value::parsePrimitiveValue($oParserState); } $oParserState->consumeUntil([';', ParserState::EOF], true, true); if ($sPrefix !== null && !is_string($sPrefix)) { throw new UnexpectedTokenException('Wrong namespace prefix', $sPrefix, 'custom', $iIdentifierLineNum); } if (!($mUrl instanceof CSSString || $mUrl instanceof URL)) { throw new UnexpectedTokenException( 'Wrong namespace url of invalid type', $mUrl, 'custom', $iIdentifierLineNum ); } return new CSSNamespace($mUrl, $sPrefix, $iIdentifierLineNum); } else { // Unknown other at rule (font-face or such) $sArgs = trim($oParserState->consumeUntil('{', false, true)); if (substr_count($sArgs, "(") != substr_count($sArgs, ")")) { if ($oParserState->getSettings()->bLenientParsing) { return null; } else { throw new SourceException("Unmatched brace count in media query", $oParserState->currentLine()); } } $bUseRuleSet = true; foreach (explode('/', AtRule::BLOCK_RULES) as $sBlockRuleName) { if (self::identifierIs($sIdentifier, $sBlockRuleName)) { $bUseRuleSet = false; break; } } if ($bUseRuleSet) { $oAtRule = new AtRuleSet($sIdentifier, $sArgs, $iIdentifierLineNum); RuleSet::parseRuleSet($oParserState, $oAtRule); } else { $oAtRule = new AtRuleBlockList($sIdentifier, $sArgs, $iIdentifierLineNum); CSSList::parseList($oParserState, $oAtRule); if ($oParserState->comes('}')) { $oParserState->consume('}'); } } return $oAtRule; } } /** * Tests an identifier for a given value. Since identifiers are all keywords, they can be vendor-prefixed. * We need to check for these versions too. * * @param string $sIdentifier * @param string $sMatch * * @return bool */ private static function identifierIs($sIdentifier, $sMatch) { return (strcasecmp($sIdentifier, $sMatch) === 0) ?: preg_match("/^(-\\w+-)?$sMatch$/i", $sIdentifier) === 1; } /** * @return int */ public function getLineNo() { return $this->iLineNo; } /** * Prepends an item to the list of contents. * * @param RuleSet|CSSList|Import|Charset $oItem * * @return void */ public function prepend($oItem) { array_unshift($this->aContents, $oItem); } /** * Appends an item to tje list of contents. * * @param RuleSet|CSSList|Import|Charset $oItem * * @return void */ public function append($oItem) { $this->aContents[] = $oItem; } /** * Splices the list of contents. * * @param int $iOffset * @param int $iLength * @param array $mReplacement * * @return void */ public function splice($iOffset, $iLength = null, $mReplacement = null) { array_splice($this->aContents, $iOffset, $iLength, $mReplacement); } /** * Removes an item from the CSS list. * * @param RuleSet|Import|Charset|CSSList $oItemToRemove * May be a RuleSet (most likely a DeclarationBlock), a Import, * a Charset or another CSSList (most likely a MediaQuery) * * @return bool whether the item was removed */ public function remove($oItemToRemove) { $iKey = array_search($oItemToRemove, $this->aContents, true); if ($iKey !== false) { unset($this->aContents[$iKey]); return true; } return false; } /** * Replaces an item from the CSS list. * * @param RuleSet|Import|Charset|CSSList $oOldItem * May be a `RuleSet` (most likely a `DeclarationBlock`), an `Import`, a `Charset` * or another `CSSList` (most likely a `MediaQuery`) * * @return bool */ public function replace($oOldItem, $mNewItem) { $iKey = array_search($oOldItem, $this->aContents, true); if ($iKey !== false) { if (is_array($mNewItem)) { array_splice($this->aContents, $iKey, 1, $mNewItem); } else { array_splice($this->aContents, $iKey, 1, [$mNewItem]); } return true; } return false; } /** * @param array $aContents */ public function setContents(array $aContents) { $this->aContents = []; foreach ($aContents as $content) { $this->append($content); } } /** * Removes a declaration block from the CSS list if it matches all given selectors. * * @param DeclarationBlock|array|string $mSelector the selectors to match * @param bool $bRemoveAll whether to stop at the first declaration block found or remove all blocks * * @return void */ public function removeDeclarationBlockBySelector($mSelector, $bRemoveAll = false) { if ($mSelector instanceof DeclarationBlock) { $mSelector = $mSelector->getSelectors(); } if (!is_array($mSelector)) { $mSelector = explode(',', $mSelector); } foreach ($mSelector as $iKey => &$mSel) { if (!($mSel instanceof Selector)) { if (!Selector::isValid($mSel)) { throw new UnexpectedTokenException( "Selector did not match '" . Selector::SELECTOR_VALIDATION_RX . "'.", $mSel, "custom" ); } $mSel = new Selector($mSel); } } foreach ($this->aContents as $iKey => $mItem) { if (!($mItem instanceof DeclarationBlock)) { continue; } if ($mItem->getSelectors() == $mSelector) { unset($this->aContents[$iKey]); if (!$bRemoveAll) { return; } } } } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $sResult = ''; $bIsFirst = true; $oNextLevel = $oOutputFormat; if (!$this->isRootList()) { $oNextLevel = $oOutputFormat->nextLevel(); } foreach ($this->aContents as $oContent) { $sRendered = $oOutputFormat->safely(function () use ($oNextLevel, $oContent) { return $oContent->render($oNextLevel); }); if ($sRendered === null) { continue; } if ($bIsFirst) { $bIsFirst = false; $sResult .= $oNextLevel->spaceBeforeBlocks(); } else { $sResult .= $oNextLevel->spaceBetweenBlocks(); } $sResult .= $sRendered; } if (!$bIsFirst) { // Had some output $sResult .= $oOutputFormat->spaceAfterBlocks(); } return $sResult; } /** * Return true if the list can not be further outdented. Only important when rendering. * * @return bool */ abstract public function isRootList(); /** * @return array */ public function getContents() { return $this->aContents; } /** * @param array $aComments * * @return void */ public function addComments(array $aComments) { $this->aComments = array_merge($this->aComments, $aComments); } /** * @return array */ public function getComments() { return $this->aComments; } /** * @param array $aComments * * @return void */ public function setComments(array $aComments) { $this->aComments = $aComments; } } PK!eHettLconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/CSSBlockList.phpnu[ $aResult * * @return void */ protected function allDeclarationBlocks(array &$aResult) { foreach ($this->aContents as $mContent) { if ($mContent instanceof DeclarationBlock) { $aResult[] = $mContent; } elseif ($mContent instanceof CSSBlockList) { $mContent->allDeclarationBlocks($aResult); } } } /** * @param array $aResult * * @return void */ protected function allRuleSets(array &$aResult) { foreach ($this->aContents as $mContent) { if ($mContent instanceof RuleSet) { $aResult[] = $mContent; } elseif ($mContent instanceof CSSBlockList) { $mContent->allRuleSets($aResult); } } } /** * @param CSSList|Rule|RuleSet|Value $oElement * @param array $aResult * @param string|null $sSearchString * @param bool $bSearchInFunctionArguments * * @return void */ protected function allValues($oElement, array &$aResult, $sSearchString = null, $bSearchInFunctionArguments = false) { if ($oElement instanceof CSSBlockList) { foreach ($oElement->getContents() as $oContent) { $this->allValues($oContent, $aResult, $sSearchString, $bSearchInFunctionArguments); } } elseif ($oElement instanceof RuleSet) { foreach ($oElement->getRules($sSearchString) as $oRule) { $this->allValues($oRule, $aResult, $sSearchString, $bSearchInFunctionArguments); } } elseif ($oElement instanceof Rule) { $this->allValues($oElement->getValue(), $aResult, $sSearchString, $bSearchInFunctionArguments); } elseif ($oElement instanceof ValueList) { if ($bSearchInFunctionArguments || !($oElement instanceof CSSFunction)) { foreach ($oElement->getListComponents() as $mComponent) { $this->allValues($mComponent, $aResult, $sSearchString, $bSearchInFunctionArguments); } } } else { // Non-List `Value` or `CSSString` (CSS identifier) $aResult[] = $oElement; } } /** * @param array $aResult * @param string|null $sSpecificitySearch * * @return void */ protected function allSelectors(array &$aResult, $sSpecificitySearch = null) { /** @var array $aDeclarationBlocks */ $aDeclarationBlocks = []; $this->allDeclarationBlocks($aDeclarationBlocks); foreach ($aDeclarationBlocks as $oBlock) { foreach ($oBlock->getSelectors() as $oSelector) { if ($sSpecificitySearch === null) { $aResult[] = $oSelector; } else { $sComparator = '==='; $aSpecificitySearch = explode(' ', $sSpecificitySearch); $iTargetSpecificity = $aSpecificitySearch[0]; if (count($aSpecificitySearch) > 1) { $sComparator = $aSpecificitySearch[0]; $iTargetSpecificity = $aSpecificitySearch[1]; } $iTargetSpecificity = (int)$iTargetSpecificity; $iSelectorSpecificity = $oSelector->getSpecificity(); $bMatches = false; switch ($sComparator) { case '<=': $bMatches = $iSelectorSpecificity <= $iTargetSpecificity; break; case '<': $bMatches = $iSelectorSpecificity < $iTargetSpecificity; break; case '>=': $bMatches = $iSelectorSpecificity >= $iTargetSpecificity; break; case '>': $bMatches = $iSelectorSpecificity > $iTargetSpecificity; break; default: $bMatches = $iSelectorSpecificity === $iTargetSpecificity; break; } if ($bMatches) { $aResult[] = $oSelector; } } } } } } PK!zzOconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/AtRuleBlockList.phpnu[sType = $sType; $this->sArgs = $sArgs; } /** * @return string */ public function atRuleName() { return $this->sType; } /** * @return string */ public function atRuleArgs() { return $this->sArgs; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $sArgs = $this->sArgs; if ($sArgs) { $sArgs = ' ' . $sArgs; } $sResult = $oOutputFormat->sBeforeAtRuleBlock; $sResult .= "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{"; $sResult .= parent::render($oOutputFormat); $sResult .= '}'; $sResult .= $oOutputFormat->sAfterAtRuleBlock; return $sResult; } /** * @return bool */ public function isRootList() { return false; } } PK!yW'Xconvertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/UnexpectedTokenException.phpnu[sExpected = $sExpected; $this->sFound = $sFound; $this->sMatchType = $sMatchType; $sMessage = "Token “{$sExpected}” ({$sMatchType}) not found. Got “{$sFound}”."; if ($this->sMatchType === 'search') { $sMessage = "Search for “{$sExpected}” returned no results. Context: “{$sFound}”."; } elseif ($this->sMatchType === 'count') { $sMessage = "Next token was expected to have {$sExpected} chars. Context: “{$sFound}”."; } elseif ($this->sMatchType === 'identifier') { $sMessage = "Identifier expected. Got “{$sFound}”"; } elseif ($this->sMatchType === 'custom') { $sMessage = trim("$sExpected $sFound"); } parent::__construct($sMessage, $iLineNo); } } PK!jyBffOconvertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/OutputException.phpnu[ */ private $aText; /** * @var int */ private $iCurrentPosition; /** * @var string */ private $sCharset; /** * @var int */ private $iLength; /** * @var int */ private $iLineNo; /** * @param string $sText * @param int $iLineNo */ public function __construct($sText, Settings $oParserSettings, $iLineNo = 1) { $this->oParserSettings = $oParserSettings; $this->sText = $sText; $this->iCurrentPosition = 0; $this->iLineNo = $iLineNo; $this->setCharset($this->oParserSettings->sDefaultCharset); } /** * @param string $sCharset * * @return void */ public function setCharset($sCharset) { $this->sCharset = $sCharset; $this->aText = $this->strsplit($this->sText); if (is_array($this->aText)) { $this->iLength = count($this->aText); } } /** * @return string */ public function getCharset() { return $this->sCharset; } /** * @return int */ public function currentLine() { return $this->iLineNo; } /** * @return int */ public function currentColumn() { return $this->iCurrentPosition; } /** * @return Settings */ public function getSettings() { return $this->oParserSettings; } /** * @param bool $bIgnoreCase * * @return string * * @throws UnexpectedTokenException */ public function parseIdentifier($bIgnoreCase = true) { $sResult = $this->parseCharacter(true); if ($sResult === null) { throw new UnexpectedTokenException($sResult, $this->peek(5), 'identifier', $this->iLineNo); } $sCharacter = null; while (($sCharacter = $this->parseCharacter(true)) !== null) { if (preg_match('/[a-zA-Z0-9\x{00A0}-\x{FFFF}_-]/Sux', $sCharacter)) { $sResult .= $sCharacter; } else { $sResult .= '\\' . $sCharacter; } } if ($bIgnoreCase) { $sResult = $this->strtolower($sResult); } return $sResult; } /** * @param bool $bIsForIdentifier * * @return string|null * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public function parseCharacter($bIsForIdentifier) { if ($this->peek() === '\\') { if ( $bIsForIdentifier && $this->oParserSettings->bLenientParsing && ($this->comes('\0') || $this->comes('\9')) ) { // Non-strings can contain \0 or \9 which is an IE hack supported in lenient parsing. return null; } $this->consume('\\'); if ($this->comes('\n') || $this->comes('\r')) { return ''; } if (preg_match('/[0-9a-fA-F]/Su', $this->peek()) === 0) { return $this->consume(1); } $sUnicode = $this->consumeExpression('/^[0-9a-fA-F]{1,6}/u', 6); if ($this->strlen($sUnicode) < 6) { // Consume whitespace after incomplete unicode escape if (preg_match('/\\s/isSu', $this->peek())) { if ($this->comes('\r\n')) { $this->consume(2); } else { $this->consume(1); } } } $iUnicode = intval($sUnicode, 16); $sUtf32 = ""; for ($i = 0; $i < 4; ++$i) { $sUtf32 .= chr($iUnicode & 0xff); $iUnicode = $iUnicode >> 8; } return iconv('utf-32le', $this->sCharset, $sUtf32); } if ($bIsForIdentifier) { $peek = ord($this->peek()); // Ranges: a-z A-Z 0-9 - _ if ( ($peek >= 97 && $peek <= 122) || ($peek >= 65 && $peek <= 90) || ($peek >= 48 && $peek <= 57) || ($peek === 45) || ($peek === 95) || ($peek > 0xa1) ) { return $this->consume(1); } } else { return $this->consume(1); } return null; } /** * @return array|void * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public function consumeWhiteSpace() { $comments = []; do { while (preg_match('/\\s/isSu', $this->peek()) === 1) { $this->consume(1); } if ($this->oParserSettings->bLenientParsing) { try { $oComment = $this->consumeComment(); } catch (UnexpectedEOFException $e) { $this->iCurrentPosition = $this->iLength; return; } } else { $oComment = $this->consumeComment(); } if ($oComment !== false) { $comments[] = $oComment; } } while ($oComment !== false); return $comments; } /** * @param string $sString * @param bool $bCaseInsensitive * * @return bool */ public function comes($sString, $bCaseInsensitive = false) { $sPeek = $this->peek(strlen($sString)); return ($sPeek == '') ? false : $this->streql($sPeek, $sString, $bCaseInsensitive); } /** * @param int $iLength * @param int $iOffset * * @return string */ public function peek($iLength = 1, $iOffset = 0) { $iOffset += $this->iCurrentPosition; if ($iOffset >= $this->iLength) { return ''; } return $this->substr($iOffset, $iLength); } /** * @param int $mValue * * @return string * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public function consume($mValue = 1) { if (is_string($mValue)) { $iLineCount = substr_count($mValue, "\n"); $iLength = $this->strlen($mValue); if (!$this->streql($this->substr($this->iCurrentPosition, $iLength), $mValue)) { throw new UnexpectedTokenException($mValue, $this->peek(max($iLength, 5)), $this->iLineNo); } $this->iLineNo += $iLineCount; $this->iCurrentPosition += $this->strlen($mValue); return $mValue; } else { if ($this->iCurrentPosition + $mValue > $this->iLength) { throw new UnexpectedEOFException($mValue, $this->peek(5), 'count', $this->iLineNo); } $sResult = $this->substr($this->iCurrentPosition, $mValue); $iLineCount = substr_count($sResult, "\n"); $this->iLineNo += $iLineCount; $this->iCurrentPosition += $mValue; return $sResult; } } /** * @param string $mExpression * @param int|null $iMaxLength * * @return string * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public function consumeExpression($mExpression, $iMaxLength = null) { $aMatches = null; $sInput = $iMaxLength !== null ? $this->peek($iMaxLength) : $this->inputLeft(); if (preg_match($mExpression, $sInput, $aMatches, PREG_OFFSET_CAPTURE) === 1) { return $this->consume($aMatches[0][0]); } throw new UnexpectedTokenException($mExpression, $this->peek(5), 'expression', $this->iLineNo); } /** * @return Comment|false */ public function consumeComment() { $mComment = false; if ($this->comes('/*')) { $iLineNo = $this->iLineNo; $this->consume(1); $mComment = ''; while (($char = $this->consume(1)) !== '') { $mComment .= $char; if ($this->comes('*/')) { $this->consume(2); break; } } } if ($mComment !== false) { // We skip the * which was included in the comment. return new Comment(substr($mComment, 1), $iLineNo); } return $mComment; } /** * @return bool */ public function isEnd() { return $this->iCurrentPosition >= $this->iLength; } /** * @param array|string $aEnd * @param string $bIncludeEnd * @param string $consumeEnd * @param array $comments * * @return string * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false, array &$comments = []) { $aEnd = is_array($aEnd) ? $aEnd : [$aEnd]; $out = ''; $start = $this->iCurrentPosition; while (!$this->isEnd()) { $char = $this->consume(1); if (in_array($char, $aEnd)) { if ($bIncludeEnd) { $out .= $char; } elseif (!$consumeEnd) { $this->iCurrentPosition -= $this->strlen($char); } return $out; } $out .= $char; if ($comment = $this->consumeComment()) { $comments[] = $comment; } } if (in_array(self::EOF, $aEnd)) { return $out; } $this->iCurrentPosition = $start; throw new UnexpectedEOFException( 'One of ("' . implode('","', $aEnd) . '")', $this->peek(5), 'search', $this->iLineNo ); } /** * @return string */ private function inputLeft() { return $this->substr($this->iCurrentPosition, -1); } /** * @param string $sString1 * @param string $sString2 * @param bool $bCaseInsensitive * * @return bool */ public function streql($sString1, $sString2, $bCaseInsensitive = true) { if ($bCaseInsensitive) { return $this->strtolower($sString1) === $this->strtolower($sString2); } else { return $sString1 === $sString2; } } /** * @param int $iAmount * * @return void */ public function backtrack($iAmount) { $this->iCurrentPosition -= $iAmount; } /** * @param string $sString * * @return int */ public function strlen($sString) { if ($this->oParserSettings->bMultibyteSupport) { return mb_strlen($sString, $this->sCharset); } else { return strlen($sString); } } /** * @param int $iStart * @param int $iLength * * @return string */ private function substr($iStart, $iLength) { if ($iLength < 0) { $iLength = $this->iLength - $iStart + $iLength; } if ($iStart + $iLength > $this->iLength) { $iLength = $this->iLength - $iStart; } $sResult = ''; while ($iLength > 0) { $sResult .= $this->aText[$iStart]; $iStart++; $iLength--; } return $sResult; } /** * @param string $sString * * @return string */ private function strtolower($sString) { if ($this->oParserSettings->bMultibyteSupport) { return mb_strtolower($sString, $this->sCharset); } else { return strtolower($sString); } } /** * @param string $sString * * @return array */ private function strsplit($sString) { if ($this->oParserSettings->bMultibyteSupport) { if ($this->streql($this->sCharset, 'utf-8')) { return preg_split('//u', $sString, -1, PREG_SPLIT_NO_EMPTY); } else { $iLength = mb_strlen($sString, $this->sCharset); $aResult = []; for ($i = 0; $i < $iLength; ++$i) { $aResult[] = mb_substr($sString, $i, 1, $this->sCharset); } return $aResult; } } else { if ($sString === '') { return []; } else { return str_split($sString); } } } /** * @param string $sString * @param string $sNeedle * @param int $iOffset * * @return int|false */ private function strpos($sString, $sNeedle, $iOffset) { if ($this->oParserSettings->bMultibyteSupport) { return mb_strpos($sString, $sNeedle, $iOffset, $this->sCharset); } else { return strpos($sString, $sNeedle, $iOffset); } } } PK!cܚ22Oconvertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/SourceException.phpnu[iLineNo = $iLineNo; if (!empty($iLineNo)) { $sMessage .= " [line no: $iLineNo]"; } parent::__construct($sMessage); } /** * @return int */ public function getLineNo() { return $this->iLineNo; } } PK!qVconvertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/UnexpectedEOFException.phpnu[oFormat = $oFormat; } /** * @param string $sName * @param string|null $sType * * @return string */ public function space($sName, $sType = null) { $sSpaceString = $this->oFormat->get("Space$sName"); // If $sSpaceString is an array, we have multiple values configured // depending on the type of object the space applies to if (is_array($sSpaceString)) { if ($sType !== null && isset($sSpaceString[$sType])) { $sSpaceString = $sSpaceString[$sType]; } else { $sSpaceString = reset($sSpaceString); } } return $this->prepareSpace($sSpaceString); } /** * @return string */ public function spaceAfterRuleName() { return $this->space('AfterRuleName'); } /** * @return string */ public function spaceBeforeRules() { return $this->space('BeforeRules'); } /** * @return string */ public function spaceAfterRules() { return $this->space('AfterRules'); } /** * @return string */ public function spaceBetweenRules() { return $this->space('BetweenRules'); } /** * @return string */ public function spaceBeforeBlocks() { return $this->space('BeforeBlocks'); } /** * @return string */ public function spaceAfterBlocks() { return $this->space('AfterBlocks'); } /** * @return string */ public function spaceBetweenBlocks() { return $this->space('BetweenBlocks'); } /** * @return string */ public function spaceBeforeSelectorSeparator() { return $this->space('BeforeSelectorSeparator'); } /** * @return string */ public function spaceAfterSelectorSeparator() { return $this->space('AfterSelectorSeparator'); } /** * @param string $sSeparator * * @return string */ public function spaceBeforeListArgumentSeparator($sSeparator) { return $this->space('BeforeListArgumentSeparator', $sSeparator); } /** * @param string $sSeparator * * @return string */ public function spaceAfterListArgumentSeparator($sSeparator) { return $this->space('AfterListArgumentSeparator', $sSeparator); } /** * @return string */ public function spaceBeforeOpeningBrace() { return $this->space('BeforeOpeningBrace'); } /** * Runs the given code, either swallowing or passing exceptions, depending on the `bIgnoreExceptions` setting. * * @param string $cCode the name of the function to call * * @return string|null */ public function safely($cCode) { if ($this->oFormat->get('IgnoreExceptions')) { // If output exceptions are ignored, run the code with exception guards try { return $cCode(); } catch (OutputException $e) { return null; } // Do nothing } else { // Run the code as-is return $cCode(); } } /** * Clone of the `implode` function, but calls `render` with the current output format instead of `__toString()`. * * @param string $sSeparator * @param array $aValues * @param bool $bIncreaseLevel * * @return string */ public function implode($sSeparator, array $aValues, $bIncreaseLevel = false) { $sResult = ''; $oFormat = $this->oFormat; if ($bIncreaseLevel) { $oFormat = $oFormat->nextLevel(); } $bIsFirst = true; foreach ($aValues as $mValue) { if ($bIsFirst) { $bIsFirst = false; } else { $sResult .= $sSeparator; } if ($mValue instanceof Renderable) { $sResult .= $mValue->render($oFormat); } else { $sResult .= $mValue; } } return $sResult; } /** * @param string $sString * * @return string */ public function removeLastSemicolon($sString) { if ($this->oFormat->get('SemicolonAfterLastRule')) { return $sString; } $sString = explode(';', $sString); if (count($sString) < 2) { return $sString[0]; } $sLast = array_pop($sString); $sNextToLast = array_pop($sString); array_push($sString, $sNextToLast . $sLast); return implode(';', $sString); } /** * @param string $sSpaceString * * @return string */ private function prepareSpace($sSpaceString) { return str_replace("\n", "\n" . $this->indent(), $sSpaceString); } /** * @return string */ private function indent() { return str_repeat($this->oFormat->sIndentation, $this->oFormat->level()); } } PK!@convertformstools/pdf/dompdf/lib/php-css-parser/src/Settings.phpnu[bMultibyteSupport = extension_loaded('mbstring'); } /** * @return self new instance */ public static function create() { return new Settings(); } /** * @param bool $bMultibyteSupport * * @return self fluent interface */ public function withMultibyteSupport($bMultibyteSupport = true) { $this->bMultibyteSupport = $bMultibyteSupport; return $this; } /** * @param string $sDefaultCharset * * @return self fluent interface */ public function withDefaultCharset($sDefaultCharset) { $this->sDefaultCharset = $sDefaultCharset; return $this; } /** * @param bool $bLenientParsing * * @return self fluent interface */ public function withLenientParsing($bLenientParsing = true) { $this->bLenientParsing = $bLenientParsing; return $this; } /** * @return self fluent interface */ public function beStrict() { return $this->withLenientParsing(false); } } PK!L((Bconvertformstools/pdf/dompdf/lib/php-css-parser/src/Renderable.phpnu[set('Space*Rules', "\n");`) */ public $sSpaceAfterRuleName = ' '; /** * @var string */ public $sSpaceBeforeRules = ''; /** * @var string */ public $sSpaceAfterRules = ''; /** * @var string */ public $sSpaceBetweenRules = ''; /** * @var string */ public $sSpaceBeforeBlocks = ''; /** * @var string */ public $sSpaceAfterBlocks = ''; /** * @var string */ public $sSpaceBetweenBlocks = "\n"; /** * Content injected in and around at-rule blocks. * * @var string */ public $sBeforeAtRuleBlock = ''; /** * @var string */ public $sAfterAtRuleBlock = ''; /** * This is what’s printed before and after the comma if a declaration block contains multiple selectors. * * @var string */ public $sSpaceBeforeSelectorSeparator = ''; /** * @var string */ public $sSpaceAfterSelectorSeparator = ' '; /** * This is what’s printed after the comma of value lists * * @var string */ public $sSpaceBeforeListArgumentSeparator = ''; /** * @var string */ public $sSpaceAfterListArgumentSeparator = ''; /** * @var string */ public $sSpaceBeforeOpeningBrace = ' '; /** * Content injected in and around declaration blocks. * * @var string */ public $sBeforeDeclarationBlock = ''; /** * @var string */ public $sAfterDeclarationBlockSelectors = ''; /** * @var string */ public $sAfterDeclarationBlock = ''; /** * Indentation character(s) per level. Only applicable if newlines are used in any of the spacing settings. * * @var string */ public $sIndentation = "\t"; /** * Output exceptions. * * @var bool */ public $bIgnoreExceptions = false; /** * @var OutputFormatter|null */ private $oFormatter = null; /** * @var OutputFormat|null */ private $oNextLevelFormat = null; /** * @var int */ private $iIndentationLevel = 0; public function __construct() { } /** * @param string $sName * * @return string|null */ public function get($sName) { $aVarPrefixes = ['a', 's', 'm', 'b', 'f', 'o', 'c', 'i']; foreach ($aVarPrefixes as $sPrefix) { $sFieldName = $sPrefix . ucfirst($sName); if (isset($this->$sFieldName)) { return $this->$sFieldName; } } return null; } /** * @param array|string $aNames * @param mixed $mValue * * @return self|false */ public function set($aNames, $mValue) { $aVarPrefixes = ['a', 's', 'm', 'b', 'f', 'o', 'c', 'i']; if (is_string($aNames) && strpos($aNames, '*') !== false) { $aNames = [ str_replace('*', 'Before', $aNames), str_replace('*', 'Between', $aNames), str_replace('*', 'After', $aNames), ]; } elseif (!is_array($aNames)) { $aNames = [$aNames]; } foreach ($aVarPrefixes as $sPrefix) { $bDidReplace = false; foreach ($aNames as $sName) { $sFieldName = $sPrefix . ucfirst($sName); if (isset($this->$sFieldName)) { $this->$sFieldName = $mValue; $bDidReplace = true; } } if ($bDidReplace) { return $this; } } // Break the chain so the user knows this option is invalid return false; } /** * @param string $sMethodName * @param array $aArguments * * @return mixed * * @throws \Exception */ public function __call($sMethodName, array $aArguments) { if (strpos($sMethodName, 'set') === 0) { return $this->set(substr($sMethodName, 3), $aArguments[0]); } elseif (strpos($sMethodName, 'get') === 0) { return $this->get(substr($sMethodName, 3)); } elseif (method_exists(OutputFormatter::class, $sMethodName)) { return call_user_func_array([$this->getFormatter(), $sMethodName], $aArguments); } else { throw new \Exception('Unknown OutputFormat method called: ' . $sMethodName); } } /** * @param int $iNumber * * @return self */ public function indentWithTabs($iNumber = 1) { return $this->setIndentation(str_repeat("\t", $iNumber)); } /** * @param int $iNumber * * @return self */ public function indentWithSpaces($iNumber = 2) { return $this->setIndentation(str_repeat(" ", $iNumber)); } /** * @return OutputFormat */ public function nextLevel() { if ($this->oNextLevelFormat === null) { $this->oNextLevelFormat = clone $this; $this->oNextLevelFormat->iIndentationLevel++; $this->oNextLevelFormat->oFormatter = null; } return $this->oNextLevelFormat; } /** * @return void */ public function beLenient() { $this->bIgnoreExceptions = true; } /** * @return OutputFormatter */ public function getFormatter() { if ($this->oFormatter === null) { $this->oFormatter = new OutputFormatter($this); } return $this->oFormatter; } /** * @return int */ public function level() { return $this->iIndentationLevel; } /** * Creates an instance of this class without any particular formatting settings. * * @return self */ public static function create() { return new OutputFormat(); } /** * Creates an instance of this class with a preset for compact formatting. * * @return self */ public static function createCompact() { $format = self::create(); $format->set('Space*Rules', "")->set('Space*Blocks', "")->setSpaceAfterRuleName('') ->setSpaceBeforeOpeningBrace('')->setSpaceAfterSelectorSeparator(''); return $format; } /** * Creates an instance of this class with a preset for pretty formatting. * * @return self */ public static function createPretty() { $format = self::create(); $format->set('Space*Rules', "\n")->set('Space*Blocks', "\n") ->setSpaceBetweenBlocks("\n\n")->set('SpaceAfterListArgumentSeparator', ['default' => '', ',' => ' ']); return $format; } } PK!K''Aconvertformstools/pdf/dompdf/lib/php-css-parser/src/Rule/Rule.phpnu[ */ private $aIeHack; /** * @var int */ protected $iLineNo; /** * @var int */ protected $iColNo; /** * @var array */ protected $aComments; /** * @param string $sRule * @param int $iLineNo * @param int $iColNo */ public function __construct($sRule, $iLineNo = 0, $iColNo = 0) { $this->sRule = $sRule; $this->mValue = null; $this->bIsImportant = false; $this->aIeHack = []; $this->iLineNo = $iLineNo; $this->iColNo = $iColNo; $this->aComments = []; } /** * @return Rule * * @throws UnexpectedEOFException * @throws UnexpectedTokenException */ public static function parse(ParserState $oParserState) { $aComments = $oParserState->consumeWhiteSpace(); $oRule = new Rule( $oParserState->parseIdentifier(!$oParserState->comes("--")), $oParserState->currentLine(), $oParserState->currentColumn() ); $oRule->setComments($aComments); $oRule->addComments($oParserState->consumeWhiteSpace()); $oParserState->consume(':'); $oValue = Value::parseValue($oParserState, self::listDelimiterForRule($oRule->getRule())); $oRule->setValue($oValue); if ($oParserState->getSettings()->bLenientParsing) { while ($oParserState->comes('\\')) { $oParserState->consume('\\'); $oRule->addIeHack($oParserState->consume()); $oParserState->consumeWhiteSpace(); } } $oParserState->consumeWhiteSpace(); if ($oParserState->comes('!')) { $oParserState->consume('!'); $oParserState->consumeWhiteSpace(); $oParserState->consume('important'); $oRule->setIsImportant(true); } $oParserState->consumeWhiteSpace(); while ($oParserState->comes(';')) { $oParserState->consume(';'); } $oParserState->consumeWhiteSpace(); return $oRule; } /** * @param string $sRule * * @return array */ private static function listDelimiterForRule($sRule) { if (preg_match('/^font($|-)/', $sRule)) { return [',', '/', ' ']; } return [',', ' ', '/']; } /** * @return int */ public function getLineNo() { return $this->iLineNo; } /** * @return int */ public function getColNo() { return $this->iColNo; } /** * @param int $iLine * @param int $iColumn * * @return void */ public function setPosition($iLine, $iColumn) { $this->iColNo = $iColumn; $this->iLineNo = $iLine; } /** * @param string $sRule * * @return void */ public function setRule($sRule) { $this->sRule = $sRule; } /** * @return string */ public function getRule() { return $this->sRule; } /** * @return RuleValueList|null */ public function getValue() { return $this->mValue; } /** * @param RuleValueList|null $mValue * * @return void */ public function setValue($mValue) { $this->mValue = $mValue; } /** * @param array> $aSpaceSeparatedValues * * @return RuleValueList * * @deprecated will be removed in version 9.0 * Old-Style 2-dimensional array given. Retained for (some) backwards-compatibility. * Use `setValue()` instead and wrap the value inside a RuleValueList if necessary. */ public function setValues(array $aSpaceSeparatedValues) { $oSpaceSeparatedList = null; if (count($aSpaceSeparatedValues) > 1) { $oSpaceSeparatedList = new RuleValueList(' ', $this->iLineNo); } foreach ($aSpaceSeparatedValues as $aCommaSeparatedValues) { $oCommaSeparatedList = null; if (count($aCommaSeparatedValues) > 1) { $oCommaSeparatedList = new RuleValueList(',', $this->iLineNo); } foreach ($aCommaSeparatedValues as $mValue) { if (!$oSpaceSeparatedList && !$oCommaSeparatedList) { $this->mValue = $mValue; return $mValue; } if ($oCommaSeparatedList) { $oCommaSeparatedList->addListComponent($mValue); } else { $oSpaceSeparatedList->addListComponent($mValue); } } if (!$oSpaceSeparatedList) { $this->mValue = $oCommaSeparatedList; return $oCommaSeparatedList; } else { $oSpaceSeparatedList->addListComponent($oCommaSeparatedList); } } $this->mValue = $oSpaceSeparatedList; return $oSpaceSeparatedList; } /** * @return array> * * @deprecated will be removed in version 9.0 * Old-Style 2-dimensional array returned. Retained for (some) backwards-compatibility. * Use `getValue()` instead and check for the existence of a (nested set of) ValueList object(s). */ public function getValues() { if (!$this->mValue instanceof RuleValueList) { return [[$this->mValue]]; } if ($this->mValue->getListSeparator() === ',') { return [$this->mValue->getListComponents()]; } $aResult = []; foreach ($this->mValue->getListComponents() as $mValue) { if (!$mValue instanceof RuleValueList || $mValue->getListSeparator() !== ',') { $aResult[] = [$mValue]; continue; } if ($this->mValue->getListSeparator() === ' ' || count($aResult) === 0) { $aResult[] = []; } foreach ($mValue->getListComponents() as $mValue) { $aResult[count($aResult) - 1][] = $mValue; } } return $aResult; } /** * Adds a value to the existing value. Value will be appended if a `RuleValueList` exists of the given type. * Otherwise, the existing value will be wrapped by one. * * @param RuleValueList|array $mValue * @param string $sType * * @return void */ public function addValue($mValue, $sType = ' ') { if (!is_array($mValue)) { $mValue = [$mValue]; } if (!$this->mValue instanceof RuleValueList || $this->mValue->getListSeparator() !== $sType) { $mCurrentValue = $this->mValue; $this->mValue = new RuleValueList($sType, $this->iLineNo); if ($mCurrentValue) { $this->mValue->addListComponent($mCurrentValue); } } foreach ($mValue as $mValueItem) { $this->mValue->addListComponent($mValueItem); } } /** * @param int $iModifier * * @return void */ public function addIeHack($iModifier) { $this->aIeHack[] = $iModifier; } /** * @param array $aModifiers * * @return void */ public function setIeHack(array $aModifiers) { $this->aIeHack = $aModifiers; } /** * @return array */ public function getIeHack() { return $this->aIeHack; } /** * @param bool $bIsImportant * * @return void */ public function setIsImportant($bIsImportant) { $this->bIsImportant = $bIsImportant; } /** * @return bool */ public function getIsImportant() { return $this->bIsImportant; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $sResult = "{$this->sRule}:{$oOutputFormat->spaceAfterRuleName()}"; if ($this->mValue instanceof Value) { //Can also be a ValueList $sResult .= $this->mValue->render($oOutputFormat); } else { $sResult .= $this->mValue; } if (!empty($this->aIeHack)) { $sResult .= ' \\' . implode('\\', $this->aIeHack); } if ($this->bIsImportant) { $sResult .= ' !important'; } $sResult .= ';'; return $sResult; } /** * @param array $aComments * * @return void */ public function addComments(array $aComments) { $this->aComments = array_merge($this->aComments, $aComments); } /** * @return array */ public function getComments() { return $this->aComments; } /** * @param array $aComments * * @return void */ public function setComments(array $aComments) { $this->aComments = $aComments; } } PK!**Gconvertformstools/pdf/dompdf/lib/php-css-parser/src/RuleSet/RuleSet.phpnu[ */ private $aRules; /** * @var int */ protected $iLineNo; /** * @var array */ protected $aComments; /** * @param int $iLineNo */ public function __construct($iLineNo = 0) { $this->aRules = []; $this->iLineNo = $iLineNo; $this->aComments = []; } /** * @return void * * @throws UnexpectedTokenException * @throws UnexpectedEOFException */ public static function parseRuleSet(ParserState $oParserState, RuleSet $oRuleSet) { while ($oParserState->comes(';')) { $oParserState->consume(';'); } while (!$oParserState->comes('}')) { $oRule = null; if ($oParserState->getSettings()->bLenientParsing) { try { $oRule = Rule::parse($oParserState); } catch (UnexpectedTokenException $e) { try { $sConsume = $oParserState->consumeUntil(["\n", ";", '}'], true); // We need to “unfind” the matches to the end of the ruleSet as this will be matched later if ($oParserState->streql(substr($sConsume, -1), '}')) { $oParserState->backtrack(1); } else { while ($oParserState->comes(';')) { $oParserState->consume(';'); } } } catch (UnexpectedTokenException $e) { // We’ve reached the end of the document. Just close the RuleSet. return; } } } else { $oRule = Rule::parse($oParserState); } if ($oRule) { $oRuleSet->addRule($oRule); } } $oParserState->consume('}'); } /** * @return int */ public function getLineNo() { return $this->iLineNo; } /** * @param Rule|null $oSibling * * @return void */ public function addRule(Rule $oRule, Rule $oSibling = null) { $sRule = $oRule->getRule(); if (!isset($this->aRules[$sRule])) { $this->aRules[$sRule] = []; } $iPosition = count($this->aRules[$sRule]); if ($oSibling !== null) { $iSiblingPos = array_search($oSibling, $this->aRules[$sRule], true); if ($iSiblingPos !== false) { $iPosition = $iSiblingPos; $oRule->setPosition($oSibling->getLineNo(), $oSibling->getColNo() - 1); } } if ($oRule->getLineNo() === 0 && $oRule->getColNo() === 0) { //this node is added manually, give it the next best line $rules = $this->getRules(); $pos = count($rules); if ($pos > 0) { $last = $rules[$pos - 1]; $oRule->setPosition($last->getLineNo() + 1, 0); } } array_splice($this->aRules[$sRule], $iPosition, 0, [$oRule]); } /** * Returns all rules matching the given rule name * * @example $oRuleSet->getRules('font') // returns array(0 => $oRule, …) or array(). * * @example $oRuleSet->getRules('font-') * //returns an array of all rules either beginning with font- or matching font. * * @param Rule|string|null $mRule * Pattern to search for. If null, returns all rules. * If the pattern ends with a dash, all rules starting with the pattern are returned * as well as one matching the pattern with the dash excluded. * Passing a Rule behaves like calling `getRules($mRule->getRule())`. * * @return array */ public function getRules($mRule = null) { if ($mRule instanceof Rule) { $mRule = $mRule->getRule(); } /** @var array $aResult */ $aResult = []; foreach ($this->aRules as $sName => $aRules) { // Either no search rule is given or the search rule matches the found rule exactly // or the search rule ends in “-” and the found rule starts with the search rule. if ( !$mRule || $sName === $mRule || ( strrpos($mRule, '-') === strlen($mRule) - strlen('-') && (strpos($sName, $mRule) === 0 || $sName === substr($mRule, 0, -1)) ) ) { $aResult = array_merge($aResult, $aRules); } } usort($aResult, function (Rule $first, Rule $second) { if ($first->getLineNo() === $second->getLineNo()) { return $first->getColNo() - $second->getColNo(); } return $first->getLineNo() - $second->getLineNo(); }); return $aResult; } /** * Overrides all the rules of this set. * * @param array $aRules The rules to override with. * * @return void */ public function setRules(array $aRules) { $this->aRules = []; foreach ($aRules as $rule) { $this->addRule($rule); } } /** * Returns all rules matching the given pattern and returns them in an associative array with the rule’s name * as keys. This method exists mainly for backwards-compatibility and is really only partially useful. * * Note: This method loses some information: Calling this (with an argument of `background-`) on a declaration block * like `{ background-color: green; background-color; rgba(0, 127, 0, 0.7); }` will only yield an associative array * containing the rgba-valued rule while `getRules()` would yield an indexed array containing both. * * @param Rule|string|null $mRule $mRule * Pattern to search for. If null, returns all rules. If the pattern ends with a dash, * all rules starting with the pattern are returned as well as one matching the pattern with the dash * excluded. Passing a Rule behaves like calling `getRules($mRule->getRule())`. * * @return array */ public function getRulesAssoc($mRule = null) { /** @var array $aResult */ $aResult = []; foreach ($this->getRules($mRule) as $oRule) { $aResult[$oRule->getRule()] = $oRule; } return $aResult; } /** * Removes a rule from this RuleSet. This accepts all the possible values that `getRules()` accepts. * * If given a Rule, it will only remove this particular rule (by identity). * If given a name, it will remove all rules by that name. * * Note: this is different from pre-v.2.0 behaviour of PHP-CSS-Parser, where passing a Rule instance would * remove all rules with the same name. To get the old behaviour, use `removeRule($oRule->getRule())`. * * @param Rule|string|null $mRule * pattern to remove. If $mRule is null, all rules are removed. If the pattern ends in a dash, * all rules starting with the pattern are removed as well as one matching the pattern with the dash * excluded. Passing a Rule behaves matches by identity. * * @return void */ public function removeRule($mRule) { if ($mRule instanceof Rule) { $sRule = $mRule->getRule(); if (!isset($this->aRules[$sRule])) { return; } foreach ($this->aRules[$sRule] as $iKey => $oRule) { if ($oRule === $mRule) { unset($this->aRules[$sRule][$iKey]); } } } else { foreach ($this->aRules as $sName => $aRules) { // Either no search rule is given or the search rule matches the found rule exactly // or the search rule ends in “-” and the found rule starts with the search rule or equals it // (without the trailing dash). if ( !$mRule || $sName === $mRule || (strrpos($mRule, '-') === strlen($mRule) - strlen('-') && (strpos($sName, $mRule) === 0 || $sName === substr($mRule, 0, -1))) ) { unset($this->aRules[$sName]); } } } } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $sResult = ''; $bIsFirst = true; foreach ($this->aRules as $aRules) { foreach ($aRules as $oRule) { $sRendered = $oOutputFormat->safely(function () use ($oRule, $oOutputFormat) { return $oRule->render($oOutputFormat->nextLevel()); }); if ($sRendered === null) { continue; } if ($bIsFirst) { $bIsFirst = false; $sResult .= $oOutputFormat->nextLevel()->spaceBeforeRules(); } else { $sResult .= $oOutputFormat->nextLevel()->spaceBetweenRules(); } $sResult .= $sRendered; } } if (!$bIsFirst) { // Had some output $sResult .= $oOutputFormat->spaceAfterRules(); } return $oOutputFormat->removeLastSemicolon($sResult); } /** * @param array $aComments * * @return void */ public function addComments(array $aComments) { $this->aComments = array_merge($this->aComments, $aComments); } /** * @return array */ public function getComments() { return $this->aComments; } /** * @param array $aComments * * @return void */ public function setComments(array $aComments) { $this->aComments = $aComments; } } PK!|'ssPconvertformstools/pdf/dompdf/lib/php-css-parser/src/RuleSet/DeclarationBlock.phpnu[ */ private $aSelectors; /** * @param int $iLineNo */ public function __construct($iLineNo = 0) { parent::__construct($iLineNo); $this->aSelectors = []; } /** * @param CSSList|null $oList * * @return DeclarationBlock|false * * @throws UnexpectedTokenException * @throws UnexpectedEOFException */ public static function parse(ParserState $oParserState, $oList = null) { $aComments = []; $oResult = new DeclarationBlock($oParserState->currentLine()); try { $aSelectorParts = []; $sStringWrapperChar = false; do { $aSelectorParts[] = $oParserState->consume(1) . $oParserState->consumeUntil(['{', '}', '\'', '"'], false, false, $aComments); if (in_array($oParserState->peek(), ['\'', '"']) && substr(end($aSelectorParts), -1) != "\\") { if ($sStringWrapperChar === false) { $sStringWrapperChar = $oParserState->peek(); } elseif ($sStringWrapperChar == $oParserState->peek()) { $sStringWrapperChar = false; } } } while (!in_array($oParserState->peek(), ['{', '}']) || $sStringWrapperChar !== false); $oResult->setSelectors(implode('', $aSelectorParts), $oList); if ($oParserState->comes('{')) { $oParserState->consume(1); } } catch (UnexpectedTokenException $e) { if ($oParserState->getSettings()->bLenientParsing) { if (!$oParserState->comes('}')) { $oParserState->consumeUntil('}', false, true); } return false; } else { throw $e; } } $oResult->setComments($aComments); RuleSet::parseRuleSet($oParserState, $oResult); return $oResult; } /** * @param array|string $mSelector * @param CSSList|null $oList * * @throws UnexpectedTokenException */ public function setSelectors($mSelector, $oList = null) { if (is_array($mSelector)) { $this->aSelectors = $mSelector; } else { $this->aSelectors = explode(',', $mSelector); } foreach ($this->aSelectors as $iKey => $mSelector) { if (!($mSelector instanceof Selector)) { if ($oList === null || !($oList instanceof KeyFrame)) { if (!Selector::isValid($mSelector)) { throw new UnexpectedTokenException( "Selector did not match '" . Selector::SELECTOR_VALIDATION_RX . "'.", $mSelector, "custom" ); } $this->aSelectors[$iKey] = new Selector($mSelector); } else { if (!KeyframeSelector::isValid($mSelector)) { throw new UnexpectedTokenException( "Selector did not match '" . KeyframeSelector::SELECTOR_VALIDATION_RX . "'.", $mSelector, "custom" ); } $this->aSelectors[$iKey] = new KeyframeSelector($mSelector); } } } } /** * Remove one of the selectors of the block. * * @param Selector|string $mSelector * * @return bool */ public function removeSelector($mSelector) { if ($mSelector instanceof Selector) { $mSelector = $mSelector->getSelector(); } foreach ($this->aSelectors as $iKey => $oSelector) { if ($oSelector->getSelector() === $mSelector) { unset($this->aSelectors[$iKey]); return true; } } return false; } /** * @return array * * @deprecated will be removed in version 9.0; use `getSelectors()` instead */ public function getSelector() { return $this->getSelectors(); } /** * @param Selector|string $mSelector * @param CSSList|null $oList * * @return void * * @deprecated will be removed in version 9.0; use `setSelectors()` instead */ public function setSelector($mSelector, $oList = null) { $this->setSelectors($mSelector, $oList); } /** * @return array */ public function getSelectors() { return $this->aSelectors; } /** * Splits shorthand declarations (e.g. `margin` or `font`) into their constituent parts. * * @return void */ public function expandShorthands() { // border must be expanded before dimensions $this->expandBorderShorthand(); $this->expandDimensionsShorthand(); $this->expandFontShorthand(); $this->expandBackgroundShorthand(); $this->expandListStyleShorthand(); } /** * Creates shorthand declarations (e.g. `margin` or `font`) whenever possible. * * @return void */ public function createShorthands() { $this->createBackgroundShorthand(); $this->createDimensionsShorthand(); // border must be shortened after dimensions $this->createBorderShorthand(); $this->createFontShorthand(); $this->createListStyleShorthand(); } /** * Splits shorthand border declarations (e.g. `border: 1px red;`). * * Additional splitting happens in expandDimensionsShorthand. * * Multiple borders are not yet supported as of 3. * * @return void */ public function expandBorderShorthand() { $aBorderRules = [ 'border', 'border-left', 'border-right', 'border-top', 'border-bottom', ]; $aBorderSizes = [ 'thin', 'medium', 'thick', ]; $aRules = $this->getRulesAssoc(); foreach ($aBorderRules as $sBorderRule) { if (!isset($aRules[$sBorderRule])) { continue; } $oRule = $aRules[$sBorderRule]; $mRuleValue = $oRule->getValue(); $aValues = []; if (!$mRuleValue instanceof RuleValueList) { $aValues[] = $mRuleValue; } else { $aValues = $mRuleValue->getListComponents(); } foreach ($aValues as $mValue) { if ($mValue instanceof Value) { $mNewValue = clone $mValue; } else { $mNewValue = $mValue; } if ($mValue instanceof Size) { $sNewRuleName = $sBorderRule . "-width"; } elseif ($mValue instanceof Color) { $sNewRuleName = $sBorderRule . "-color"; } else { if (in_array($mValue, $aBorderSizes)) { $sNewRuleName = $sBorderRule . "-width"; } else { $sNewRuleName = $sBorderRule . "-style"; } } $oNewRule = new Rule($sNewRuleName, $oRule->getLineNo(), $oRule->getColNo()); $oNewRule->setIsImportant($oRule->getIsImportant()); $oNewRule->addValue([$mNewValue]); $this->addRule($oNewRule); } $this->removeRule($sBorderRule); } } /** * Splits shorthand dimensional declarations (e.g. `margin: 0px auto;`) * into their constituent parts. * * Handles `margin`, `padding`, `border-color`, `border-style` and `border-width`. * * @return void */ public function expandDimensionsShorthand() { $aExpansions = [ 'margin' => 'margin-%s', 'padding' => 'padding-%s', 'border-color' => 'border-%s-color', 'border-style' => 'border-%s-style', 'border-width' => 'border-%s-width', ]; $aRules = $this->getRulesAssoc(); foreach ($aExpansions as $sProperty => $sExpanded) { if (!isset($aRules[$sProperty])) { continue; } $oRule = $aRules[$sProperty]; $mRuleValue = $oRule->getValue(); $aValues = []; if (!$mRuleValue instanceof RuleValueList) { $aValues[] = $mRuleValue; } else { $aValues = $mRuleValue->getListComponents(); } $top = $right = $bottom = $left = null; switch (count($aValues)) { case 1: $top = $right = $bottom = $left = $aValues[0]; break; case 2: $top = $bottom = $aValues[0]; $left = $right = $aValues[1]; break; case 3: $top = $aValues[0]; $left = $right = $aValues[1]; $bottom = $aValues[2]; break; case 4: $top = $aValues[0]; $right = $aValues[1]; $bottom = $aValues[2]; $left = $aValues[3]; break; } foreach (['top', 'right', 'bottom', 'left'] as $sPosition) { $oNewRule = new Rule(sprintf($sExpanded, $sPosition), $oRule->getLineNo(), $oRule->getColNo()); $oNewRule->setIsImportant($oRule->getIsImportant()); $oNewRule->addValue(${$sPosition}); $this->addRule($oNewRule); } $this->removeRule($sProperty); } } /** * Converts shorthand font declarations * (e.g. `font: 300 italic 11px/14px verdana, helvetica, sans-serif;`) * into their constituent parts. * * @return void */ public function expandFontShorthand() { $aRules = $this->getRulesAssoc(); if (!isset($aRules['font'])) { return; } $oRule = $aRules['font']; // reset properties to 'normal' per http://www.w3.org/TR/21/fonts.html#font-shorthand $aFontProperties = [ 'font-style' => 'normal', 'font-variant' => 'normal', 'font-weight' => 'normal', 'font-size' => 'normal', 'line-height' => 'normal', ]; $mRuleValue = $oRule->getValue(); $aValues = []; if (!$mRuleValue instanceof RuleValueList) { $aValues[] = $mRuleValue; } else { $aValues = $mRuleValue->getListComponents(); } foreach ($aValues as $mValue) { if (!$mValue instanceof Value) { $mValue = mb_strtolower($mValue); } if (in_array($mValue, ['normal', 'inherit'])) { foreach (['font-style', 'font-weight', 'font-variant'] as $sProperty) { if (!isset($aFontProperties[$sProperty])) { $aFontProperties[$sProperty] = $mValue; } } } elseif (in_array($mValue, ['italic', 'oblique'])) { $aFontProperties['font-style'] = $mValue; } elseif ($mValue == 'small-caps') { $aFontProperties['font-variant'] = $mValue; } elseif ( in_array($mValue, ['bold', 'bolder', 'lighter']) || ($mValue instanceof Size && in_array($mValue->getSize(), range(100, 900, 100))) ) { $aFontProperties['font-weight'] = $mValue; } elseif ($mValue instanceof RuleValueList && $mValue->getListSeparator() == '/') { list($oSize, $oHeight) = $mValue->getListComponents(); $aFontProperties['font-size'] = $oSize; $aFontProperties['line-height'] = $oHeight; } elseif ($mValue instanceof Size && $mValue->getUnit() !== null) { $aFontProperties['font-size'] = $mValue; } else { $aFontProperties['font-family'] = $mValue; } } foreach ($aFontProperties as $sProperty => $mValue) { $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo()); $oNewRule->addValue($mValue); $oNewRule->setIsImportant($oRule->getIsImportant()); $this->addRule($oNewRule); } $this->removeRule('font'); } /** * Converts shorthand background declarations * (e.g. `background: url("chess.png") gray 50% repeat fixed;`) * into their constituent parts. * * @see http://www.w3.org/TR/21/colors.html#propdef-background * * @return void */ public function expandBackgroundShorthand() { $aRules = $this->getRulesAssoc(); if (!isset($aRules['background'])) { return; } $oRule = $aRules['background']; $aBgProperties = [ 'background-color' => ['transparent'], 'background-image' => ['none'], 'background-repeat' => ['repeat'], 'background-attachment' => ['scroll'], 'background-position' => [ new Size(0, '%', null, false, $this->iLineNo), new Size(0, '%', null, false, $this->iLineNo), ], ]; $mRuleValue = $oRule->getValue(); $aValues = []; if (!$mRuleValue instanceof RuleValueList) { $aValues[] = $mRuleValue; } else { $aValues = $mRuleValue->getListComponents(); } if (count($aValues) == 1 && $aValues[0] == 'inherit') { foreach ($aBgProperties as $sProperty => $mValue) { $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo()); $oNewRule->addValue('inherit'); $oNewRule->setIsImportant($oRule->getIsImportant()); $this->addRule($oNewRule); } $this->removeRule('background'); return; } $iNumBgPos = 0; foreach ($aValues as $mValue) { if (!$mValue instanceof Value) { $mValue = mb_strtolower($mValue); } if ($mValue instanceof URL) { $aBgProperties['background-image'] = $mValue; } elseif ($mValue instanceof Color) { $aBgProperties['background-color'] = $mValue; } elseif (in_array($mValue, ['scroll', 'fixed'])) { $aBgProperties['background-attachment'] = $mValue; } elseif (in_array($mValue, ['repeat', 'no-repeat', 'repeat-x', 'repeat-y'])) { $aBgProperties['background-repeat'] = $mValue; } elseif ( in_array($mValue, ['left', 'center', 'right', 'top', 'bottom']) || $mValue instanceof Size ) { if ($iNumBgPos == 0) { $aBgProperties['background-position'][0] = $mValue; $aBgProperties['background-position'][1] = 'center'; } else { $aBgProperties['background-position'][$iNumBgPos] = $mValue; } $iNumBgPos++; } } foreach ($aBgProperties as $sProperty => $mValue) { $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo()); $oNewRule->setIsImportant($oRule->getIsImportant()); $oNewRule->addValue($mValue); $this->addRule($oNewRule); } $this->removeRule('background'); } /** * @return void */ public function expandListStyleShorthand() { $aListProperties = [ 'list-style-type' => 'disc', 'list-style-position' => 'outside', 'list-style-image' => 'none', ]; $aListStyleTypes = [ 'none', 'disc', 'circle', 'square', 'decimal-leading-zero', 'decimal', 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', 'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'armenian', 'georgian', 'cjk-ideographic', 'hiragana', 'hira-gana-iroha', 'katakana-iroha', 'katakana', ]; $aListStylePositions = [ 'inside', 'outside', ]; $aRules = $this->getRulesAssoc(); if (!isset($aRules['list-style'])) { return; } $oRule = $aRules['list-style']; $mRuleValue = $oRule->getValue(); $aValues = []; if (!$mRuleValue instanceof RuleValueList) { $aValues[] = $mRuleValue; } else { $aValues = $mRuleValue->getListComponents(); } if (count($aValues) == 1 && $aValues[0] == 'inherit') { foreach ($aListProperties as $sProperty => $mValue) { $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo()); $oNewRule->addValue('inherit'); $oNewRule->setIsImportant($oRule->getIsImportant()); $this->addRule($oNewRule); } $this->removeRule('list-style'); return; } foreach ($aValues as $mValue) { if (!$mValue instanceof Value) { $mValue = mb_strtolower($mValue); } if ($mValue instanceof Url) { $aListProperties['list-style-image'] = $mValue; } elseif (in_array($mValue, $aListStyleTypes)) { $aListProperties['list-style-types'] = $mValue; } elseif (in_array($mValue, $aListStylePositions)) { $aListProperties['list-style-position'] = $mValue; } } foreach ($aListProperties as $sProperty => $mValue) { $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo()); $oNewRule->setIsImportant($oRule->getIsImportant()); $oNewRule->addValue($mValue); $this->addRule($oNewRule); } $this->removeRule('list-style'); } /** * @param array $aProperties * @param string $sShorthand * * @return void */ public function createShorthandProperties(array $aProperties, $sShorthand) { $aRules = $this->getRulesAssoc(); $aNewValues = []; foreach ($aProperties as $sProperty) { if (!isset($aRules[$sProperty])) { continue; } $oRule = $aRules[$sProperty]; if (!$oRule->getIsImportant()) { $mRuleValue = $oRule->getValue(); $aValues = []; if (!$mRuleValue instanceof RuleValueList) { $aValues[] = $mRuleValue; } else { $aValues = $mRuleValue->getListComponents(); } foreach ($aValues as $mValue) { $aNewValues[] = $mValue; } $this->removeRule($sProperty); } } if (count($aNewValues)) { $oNewRule = new Rule($sShorthand, $oRule->getLineNo(), $oRule->getColNo()); foreach ($aNewValues as $mValue) { $oNewRule->addValue($mValue); } $this->addRule($oNewRule); } } /** * @return void */ public function createBackgroundShorthand() { $aProperties = [ 'background-color', 'background-image', 'background-repeat', 'background-position', 'background-attachment', ]; $this->createShorthandProperties($aProperties, 'background'); } /** * @return void */ public function createListStyleShorthand() { $aProperties = [ 'list-style-type', 'list-style-position', 'list-style-image', ]; $this->createShorthandProperties($aProperties, 'list-style'); } /** * Combines `border-color`, `border-style` and `border-width` into `border`. * * Should be run after `create_dimensions_shorthand`! * * @return void */ public function createBorderShorthand() { $aProperties = [ 'border-width', 'border-style', 'border-color', ]; $this->createShorthandProperties($aProperties, 'border'); } /** * Looks for long format CSS dimensional properties * (margin, padding, border-color, border-style and border-width) * and converts them into shorthand CSS properties. * * @return void */ public function createDimensionsShorthand() { $aPositions = ['top', 'right', 'bottom', 'left']; $aExpansions = [ 'margin' => 'margin-%s', 'padding' => 'padding-%s', 'border-color' => 'border-%s-color', 'border-style' => 'border-%s-style', 'border-width' => 'border-%s-width', ]; $aRules = $this->getRulesAssoc(); foreach ($aExpansions as $sProperty => $sExpanded) { $aFoldable = []; foreach ($aRules as $sRuleName => $oRule) { foreach ($aPositions as $sPosition) { if ($sRuleName == sprintf($sExpanded, $sPosition)) { $aFoldable[$sRuleName] = $oRule; } } } // All four dimensions must be present if (count($aFoldable) == 4) { $aValues = []; foreach ($aPositions as $sPosition) { $oRule = $aRules[sprintf($sExpanded, $sPosition)]; $mRuleValue = $oRule->getValue(); $aRuleValues = []; if (!$mRuleValue instanceof RuleValueList) { $aRuleValues[] = $mRuleValue; } else { $aRuleValues = $mRuleValue->getListComponents(); } $aValues[$sPosition] = $aRuleValues; } $oNewRule = new Rule($sProperty, $oRule->getLineNo(), $oRule->getColNo()); if ((string)$aValues['left'][0] == (string)$aValues['right'][0]) { if ((string)$aValues['top'][0] == (string)$aValues['bottom'][0]) { if ((string)$aValues['top'][0] == (string)$aValues['left'][0]) { // All 4 sides are equal $oNewRule->addValue($aValues['top']); } else { // Top and bottom are equal, left and right are equal $oNewRule->addValue($aValues['top']); $oNewRule->addValue($aValues['left']); } } else { // Only left and right are equal $oNewRule->addValue($aValues['top']); $oNewRule->addValue($aValues['left']); $oNewRule->addValue($aValues['bottom']); } } else { // No sides are equal $oNewRule->addValue($aValues['top']); $oNewRule->addValue($aValues['left']); $oNewRule->addValue($aValues['bottom']); $oNewRule->addValue($aValues['right']); } $this->addRule($oNewRule); foreach ($aPositions as $sPosition) { $this->removeRule(sprintf($sExpanded, $sPosition)); } } } } /** * Looks for long format CSS font properties (e.g. `font-weight`) and * tries to convert them into a shorthand CSS `font` property. * * At least `font-size` AND `font-family` must be present in order to create a shorthand declaration. * * @return void */ public function createFontShorthand() { $aFontProperties = [ 'font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', 'font-family', ]; $aRules = $this->getRulesAssoc(); if (!isset($aRules['font-size']) || !isset($aRules['font-family'])) { return; } $oOldRule = isset($aRules['font-size']) ? $aRules['font-size'] : $aRules['font-family']; $oNewRule = new Rule('font', $oOldRule->getLineNo(), $oOldRule->getColNo()); unset($oOldRule); foreach (['font-style', 'font-variant', 'font-weight'] as $sProperty) { if (isset($aRules[$sProperty])) { $oRule = $aRules[$sProperty]; $mRuleValue = $oRule->getValue(); $aValues = []; if (!$mRuleValue instanceof RuleValueList) { $aValues[] = $mRuleValue; } else { $aValues = $mRuleValue->getListComponents(); } if ($aValues[0] !== 'normal') { $oNewRule->addValue($aValues[0]); } } } // Get the font-size value $oRule = $aRules['font-size']; $mRuleValue = $oRule->getValue(); $aFSValues = []; if (!$mRuleValue instanceof RuleValueList) { $aFSValues[] = $mRuleValue; } else { $aFSValues = $mRuleValue->getListComponents(); } // But wait to know if we have line-height to add it if (isset($aRules['line-height'])) { $oRule = $aRules['line-height']; $mRuleValue = $oRule->getValue(); $aLHValues = []; if (!$mRuleValue instanceof RuleValueList) { $aLHValues[] = $mRuleValue; } else { $aLHValues = $mRuleValue->getListComponents(); } if ($aLHValues[0] !== 'normal') { $val = new RuleValueList('/', $this->iLineNo); $val->addListComponent($aFSValues[0]); $val->addListComponent($aLHValues[0]); $oNewRule->addValue($val); } } else { $oNewRule->addValue($aFSValues[0]); } $oRule = $aRules['font-family']; $mRuleValue = $oRule->getValue(); $aFFValues = []; if (!$mRuleValue instanceof RuleValueList) { $aFFValues[] = $mRuleValue; } else { $aFFValues = $mRuleValue->getListComponents(); } $oFFValue = new RuleValueList(',', $this->iLineNo); $oFFValue->setListComponents($aFFValues); $oNewRule->addValue($oFFValue); $this->addRule($oNewRule); foreach ($aFontProperties as $sProperty) { $this->removeRule($sProperty); } } /** * @return string * * @throws OutputException */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string * * @throws OutputException */ public function render(OutputFormat $oOutputFormat) { if (count($this->aSelectors) === 0) { // If all the selectors have been removed, this declaration block becomes invalid throw new OutputException("Attempt to print declaration block with missing selector", $this->iLineNo); } $sResult = $oOutputFormat->sBeforeDeclarationBlock; $sResult .= $oOutputFormat->implode( $oOutputFormat->spaceBeforeSelectorSeparator() . ',' . $oOutputFormat->spaceAfterSelectorSeparator(), $this->aSelectors ); $sResult .= $oOutputFormat->sAfterDeclarationBlockSelectors; $sResult .= $oOutputFormat->spaceBeforeOpeningBrace() . '{'; $sResult .= parent::render($oOutputFormat); $sResult .= '}'; $sResult .= $oOutputFormat->sAfterDeclarationBlock; return $sResult; } } PK![~Iconvertformstools/pdf/dompdf/lib/php-css-parser/src/RuleSet/AtRuleSet.phpnu[sType = $sType; $this->sArgs = $sArgs; } /** * @return string */ public function atRuleName() { return $this->sType; } /** * @return string */ public function atRuleArgs() { return $this->sArgs; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { $sArgs = $this->sArgs; if ($sArgs) { $sArgs = ' ' . $sArgs; } $sResult = "@{$this->sType}$sArgs{$oOutputFormat->spaceBeforeOpeningBrace()}{"; $sResult .= parent::render($oOutputFormat); $sResult .= '}'; return $sResult; } } PK!QKGconvertformstools/pdf/dompdf/lib/php-css-parser/src/Comment/Comment.phpnu[sComment = $sComment; $this->iLineNo = $iLineNo; } /** * @return string */ public function getComment() { return $this->sComment; } /** * @return int */ public function getLineNo() { return $this->iLineNo; } /** * @param string $sComment * * @return void */ public function setComment($sComment) { $this->sComment = $sComment; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { return '/*' . $this->sComment . '*/'; } } PK!C!GKconvertformstools/pdf/dompdf/lib/php-css-parser/src/Comment/Commentable.phpnu[ $aComments * * @return void */ public function addComments(array $aComments); /** * @return array */ public function getComments(); /** * @param array $aComments * * @return void */ public function setComments(array $aComments); } PK!0 Mconvertformstools/pdf/dompdf/lib/php-css-parser/src/Property/CSSNamespace.phpnu[ */ protected $aComments; /** * @param string $mUrl * @param string|null $sPrefix * @param int $iLineNo */ public function __construct($mUrl, $sPrefix = null, $iLineNo = 0) { $this->mUrl = $mUrl; $this->sPrefix = $sPrefix; $this->iLineNo = $iLineNo; $this->aComments = []; } /** * @return int */ public function getLineNo() { return $this->iLineNo; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { return '@namespace ' . ($this->sPrefix === null ? '' : $this->sPrefix . ' ') . $this->mUrl->render($oOutputFormat) . ';'; } /** * @return string */ public function getUrl() { return $this->mUrl; } /** * @return string|null */ public function getPrefix() { return $this->sPrefix; } /** * @param string $mUrl * * @return void */ public function setUrl($mUrl) { $this->mUrl = $mUrl; } /** * @param string $sPrefix * * @return void */ public function setPrefix($sPrefix) { $this->sPrefix = $sPrefix; } /** * @return string */ public function atRuleName() { return 'namespace'; } /** * @return array */ public function atRuleArgs() { $aResult = [$this->mUrl]; if ($this->sPrefix) { array_unshift($aResult, $this->sPrefix); } return $aResult; } /** * @param array $aComments * * @return void */ public function addComments(array $aComments) { $this->aComments = array_merge($this->aComments, $aComments); } /** * @return array */ public function getComments() { return $this->aComments; } /** * @param array $aComments * * @return void */ public function setComments(array $aComments) { $this->aComments = $aComments; } } PK!K$A Hconvertformstools/pdf/dompdf/lib/php-css-parser/src/Property/Charset.phpnu[ */ protected $aComments; /** * @param string $sCharset * @param int $iLineNo */ public function __construct($sCharset, $iLineNo = 0) { $this->sCharset = $sCharset; $this->iLineNo = $iLineNo; $this->aComments = []; } /** * @return int */ public function getLineNo() { return $this->iLineNo; } /** * @param string $sCharset * * @return void */ public function setCharset($sCharset) { $this->sCharset = $sCharset; } /** * @return string */ public function getCharset() { return $this->sCharset; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { return "@charset {$this->sCharset->render($oOutputFormat)};"; } /** * @return string */ public function atRuleName() { return 'charset'; } /** * @return string */ public function atRuleArgs() { return $this->sCharset; } /** * @param array $aComments * * @return void */ public function addComments(array $aComments) { $this->aComments = array_merge($this->aComments, $aComments); } /** * @return array */ public function getComments() { return $this->aComments; } /** * @param array $aComments * * @return void */ public function setComments(array $aComments) { $this->aComments = $aComments; } } PK!) Gconvertformstools/pdf/dompdf/lib/php-css-parser/src/Property/Import.phpnu[ */ protected $aComments; /** * @param URL $oLocation * @param string $sMediaQuery * @param int $iLineNo */ public function __construct(URL $oLocation, $sMediaQuery, $iLineNo = 0) { $this->oLocation = $oLocation; $this->sMediaQuery = $sMediaQuery; $this->iLineNo = $iLineNo; $this->aComments = []; } /** * @return int */ public function getLineNo() { return $this->iLineNo; } /** * @param URL $oLocation * * @return void */ public function setLocation($oLocation) { $this->oLocation = $oLocation; } /** * @return URL */ public function getLocation() { return $this->oLocation; } /** * @return string */ public function __toString() { return $this->render(new OutputFormat()); } /** * @return string */ public function render(OutputFormat $oOutputFormat) { return "@import " . $this->oLocation->render($oOutputFormat) . ($this->sMediaQuery === null ? '' : ' ' . $this->sMediaQuery) . ';'; } /** * @return string */ public function atRuleName() { return 'import'; } /** * @return array */ public function atRuleArgs() { $aResult = [$this->oLocation]; if ($this->sMediaQuery) { array_push($aResult, $this->sMediaQuery); } return $aResult; } /** * @param array $aComments * * @return void */ public function addComments(array $aComments) { $this->aComments = array_merge($this->aComments, $aComments); } /** * @return array */ public function getComments() { return $this->aComments; } /** * @param array $aComments * * @return void */ public function setComments(array $aComments) { $this->aComments = $aComments; } } PK!Qconvertformstools/pdf/dompdf/lib/php-css-parser/src/Property/KeyframeSelector.phpnu[]* # any sequence of valid unescaped characters (?:\\\\.)? # a single escaped character (?:([\'"]).*?(?\~]+)[\w]+ # elements | \:{1,2}( # pseudo-elements after|before|first-letter|first-line|selection )) /ix'; /** * regexp for specificity calculations * * @var string */ const SELECTOR_VALIDATION_RX = '/ ^( (?: [a-zA-Z0-9\x{00A0}-\x{FFFF}_^$|*="\'~\[\]()\-\s\.:#+>]* # any sequence of valid unescaped characters (?:\\\\.)? # a single escaped character (?:([\'"]).*?(?setSelector($sSelector); if ($bCalculateSpecificity) { $this->getSpecificity(); } } /** * @return string */ public function getSelector() { return $this->sSelector; } /** * @param string $sSelector * * @return void */ public function setSelector($sSelector) { $this->sSelector = trim($sSelector); $this->iSpecificity = null; } /** * @return string */ public function __toString() { return $this->getSelector(); } /** * @return int */ public function getSpecificity() { if ($this->iSpecificity === null) { $a = 0; /// @todo should exclude \# as well as "#" $aMatches = null; $b = substr_count($this->sSelector, '#'); $c = preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $this->sSelector, $aMatches); $d = preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $this->sSelector, $aMatches); $this->iSpecificity = ($a * 1000) + ($b * 100) + ($c * 10) + $d; } return $this->iSpecificity; } } PK! EJ!!Gconvertformstools/pdf/dompdf/lib/php-css-parser/src/Property/AtRule.phpnu[ * @author Orion Richardson * @author Helmut Tischer * @author Ryan H. Masten * @author Brian Sweeney * @author Fabien Ménager * @license Public Domain http://creativecommons.org/licenses/publicdomain/ * @package Cpdf */ namespace Dompdf; use FontLib\Exception\FontNotFoundException; use FontLib\Font; use FontLib\BinaryStream; class Cpdf { const PDF_VERSION = '1.7'; const ACROFORM_SIG_SIGNATURESEXISTS = 0x0001; const ACROFORM_SIG_APPENDONLY = 0x0002; const ACROFORM_FIELD_BUTTON = 'Btn'; const ACROFORM_FIELD_TEXT = 'Tx'; const ACROFORM_FIELD_CHOICE = 'Ch'; const ACROFORM_FIELD_SIG = 'Sig'; const ACROFORM_FIELD_READONLY = 0x0001; const ACROFORM_FIELD_REQUIRED = 0x0002; const ACROFORM_FIELD_TEXT_MULTILINE = 0x1000; const ACROFORM_FIELD_TEXT_PASSWORD = 0x2000; const ACROFORM_FIELD_TEXT_RICHTEXT = 0x10000; const ACROFORM_FIELD_CHOICE_COMBO = 0x20000; const ACROFORM_FIELD_CHOICE_EDIT = 0x40000; const ACROFORM_FIELD_CHOICE_SORT = 0x80000; const ACROFORM_FIELD_CHOICE_MULTISELECT = 0x200000; const XOBJECT_SUBTYPE_FORM = 'Form'; /** * @var integer The current number of pdf objects in the document */ public $numObj = 0; /** * @var array This array contains all of the pdf objects, ready for final assembly */ public $objects = []; /** * @var integer The objectId (number within the objects array) of the document catalog */ public $catalogId; /** * @var integer The objectId (number within the objects array) of indirect references (Javascript EmbeddedFiles) */ protected $indirectReferenceId = 0; /** * @var integer The objectId (number within the objects array) */ protected $embeddedFilesId = 0; /** * AcroForm objectId * * @var integer */ public $acroFormId; /** * @var int */ public $signatureMaxLen = 5000; /** * @var array Array carrying information about the fonts that the system currently knows about * Used to ensure that a font is not loaded twice, among other things */ public $fonts = []; /** * @var string The default font metrics file to use if no other font has been loaded. * The path to the directory containing the font metrics should be included */ public $defaultFont = './fonts/Helvetica.afm'; /** * @string A record of the current font */ public $currentFont = ''; /** * @var string The current base font */ public $currentBaseFont = ''; /** * @var integer The number of the current font within the font array */ public $currentFontNum = 0; /** * @var integer */ public $currentNode; /** * @var integer Object number of the current page */ public $currentPage; /** * @var integer Object number of the currently active contents block */ public $currentContents; /** * @var integer Number of fonts within the system */ public $numFonts = 0; /** * @var integer Number of graphic state resources used */ private $numStates = 0; /** * @var array Number of graphic state resources used */ private $gstates = []; /** * @var array Current color for fill operations, defaults to inactive value, * all three components should be between 0 and 1 inclusive when active */ public $currentColor = null; /** * @var array Current color for stroke operations (lines etc.) */ public $currentStrokeColor = null; /** * @var string Fill rule (nonzero or evenodd) */ public $fillRule = "nonzero"; /** * @var string Current style that lines are drawn in */ public $currentLineStyle = ''; /** * @var array Current line transparency (partial graphics state) */ public $currentLineTransparency = ["mode" => "Normal", "opacity" => 1.0]; /** * array Current fill transparency (partial graphics state) */ public $currentFillTransparency = ["mode" => "Normal", "opacity" => 1.0]; /** * @var array An array which is used to save the state of the document, mainly the colors and styles * it is used to temporarily change to another state, then change back to what it was before */ public $stateStack = []; /** * @var integer Number of elements within the state stack */ public $nStateStack = 0; /** * @var integer Number of page objects within the document */ public $numPages = 0; /** * @var array Object Id storage stack */ public $stack = []; /** * @var integer Number of elements within the object Id storage stack */ public $nStack = 0; /** * an array which contains information about the objects which are not firmly attached to pages * these have been added with the addObject function */ public $looseObjects = []; /** * array contains information about how the loose objects are to be added to the document */ public $addLooseObjects = []; /** * @var integer The objectId of the information object for the document * this contains authorship, title etc. */ public $infoObject = 0; /** * @var integer Number of images being tracked within the document */ public $numImages = 0; /** * @var array An array containing options about the document * it defaults to turning on the compression of the objects */ public $options = ['compression' => true]; /** * @var integer The objectId of the first page of the document */ public $firstPageId; /** * @var integer The object Id of the procset object */ public $procsetObjectId; /** * @var array Store the information about the relationship between font families * this used so that the code knows which font is the bold version of another font, etc. * the value of this array is initialised in the constructor function. */ public $fontFamilies = []; /** * @var string Folder for php serialized formats of font metrics files. * If empty string, use same folder as original metrics files. * This can be passed in from class creator. * If this folder does not exist or is not writable, Cpdf will be **much** slower. * Because of potential trouble with php safe mode, folder cannot be created at runtime. */ public $fontcache = ''; /** * @var integer The version of the font metrics cache file. * This value must be manually incremented whenever the internal font data structure is modified. */ public $fontcacheVersion = 6; /** * @var string Temporary folder. * If empty string, will attempt system tmp folder. * This can be passed in from class creator. */ public $tmp = ''; /** * @var string Track if the current font is bolded or italicised */ public $currentTextState = ''; /** * @var string Messages are stored here during processing, these can be selected afterwards to give some useful debug information */ public $messages = ''; /** * @var string The encryption array for the document encryption is stored here */ public $arc4 = ''; /** * @var integer The object Id of the encryption information */ public $arc4_objnum = 0; /** * @var string The file identifier, used to uniquely identify a pdf document */ public $fileIdentifier = ''; /** * @var boolean A flag to say if a document is to be encrypted or not */ public $encrypted = false; /** * @var string The encryption key for the encryption of all the document content (structure is not encrypted) */ public $encryptionKey = ''; /** * @var array Array which forms a stack to keep track of nested callback functions */ public $callback = []; /** * @var integer The number of callback functions in the callback array */ public $nCallback = 0; /** * @var array Store label->id pairs for named destinations, these will be used to replace internal links * done this way so that destinations can be defined after the location that links to them */ public $destinations = []; /** * @var array Store the stack for the transaction commands, each item in here is a record of the values of all the * publiciables within the class, so that the user can rollback at will (from each 'start' command) * note that this includes the objects array, so these can be large. */ public $checkpoint = ''; /** * @var array Table of Image origin filenames and image labels which were already added with o_image(). * Allows to merge identical images */ public $imagelist = []; /** * @var array Table of already added alpha and plain image files for transparent PNG images. */ protected $imageAlphaList = []; /** * @var array List of temporary image files to be deleted after processing. */ protected $imageCache = []; /** * @var boolean Whether the text passed in should be treated as Unicode or just local character set. */ public $isUnicode = false; /** * @var string the JavaScript code of the document */ public $javascript = ''; /** * @var boolean whether the compression is possible */ protected $compressionReady = false; /** * @var array Current page size */ protected $currentPageSize = ["width" => 0, "height" => 0]; /** * @var array All the chars that will be required in the font subsets */ protected $stringSubsets = []; /** * @var string The target internal encoding */ protected static $targetEncoding = 'Windows-1252'; /** * @var array */ protected $byteRange = array(); /** * @var array The list of the core fonts */ protected static $coreFonts = [ 'courier', 'courier-bold', 'courier-oblique', 'courier-boldoblique', 'helvetica', 'helvetica-bold', 'helvetica-oblique', 'helvetica-boldoblique', 'times-roman', 'times-bold', 'times-italic', 'times-bolditalic', 'symbol', 'zapfdingbats' ]; /** * Class constructor * This will start a new document * * @param array $pageSize Array of 4 numbers, defining the bottom left and upper right corner of the page. first two are normally zero. * @param boolean $isUnicode Whether text will be treated as Unicode or not. * @param string $fontcache The font cache folder * @param string $tmp The temporary folder */ function __construct($pageSize = [0, 0, 612, 792], $isUnicode = false, $fontcache = '', $tmp = '') { $this->isUnicode = $isUnicode; $this->fontcache = rtrim($fontcache, DIRECTORY_SEPARATOR."/\\"); $this->tmp = ($tmp !== '' ? $tmp : sys_get_temp_dir()); $this->newDocument($pageSize); $this->compressionReady = function_exists('gzcompress'); if (in_array('Windows-1252', mb_list_encodings())) { self::$targetEncoding = 'Windows-1252'; } // also initialize the font families that are known about already $this->setFontFamily('init'); } public function __destruct() { foreach ($this->imageCache as $file) { if (file_exists($file)) { unlink($file); } } } /** * Document object methods (internal use only) * * There is about one object method for each type of object in the pdf document * Each function has the same call list ($id,$action,$options). * $id = the object ID of the object, or what it is to be if it is being created * $action = a string specifying the action to be performed, though ALL must support: * 'new' - create the object with the id $id * 'out' - produce the output for the pdf object * $options = optional, a string or array containing the various parameters for the object * * These, in conjunction with the output function are the ONLY way for output to be produced * within the pdf 'file'. */ /** * Destination object, used to specify the location for the user to jump to, presently on opening * * @param $id * @param $action * @param string $options * @return string|null */ protected function o_destination($id, $action, $options = '') { switch ($action) { case 'new': $this->objects[$id] = ['t' => 'destination', 'info' => []]; $tmp = ''; switch ($options['type']) { case 'XYZ': /** @noinspection PhpMissingBreakStatementInspection */ case 'FitR': $tmp = ' ' . $options['p3'] . $tmp; case 'FitH': case 'FitV': case 'FitBH': /** @noinspection PhpMissingBreakStatementInspection */ case 'FitBV': $tmp = ' ' . $options['p1'] . ' ' . $options['p2'] . $tmp; case 'Fit': case 'FitB': $tmp = $options['type'] . $tmp; $this->objects[$id]['info']['string'] = $tmp; $this->objects[$id]['info']['page'] = $options['page']; } break; case 'out': $o = &$this->objects[$id]; $tmp = $o['info']; $res = "\n$id 0 obj\n" . '[' . $tmp['page'] . ' 0 R /' . $tmp['string'] . "]\nendobj"; return $res; } return null; } /** * set the viewer preferences * * @param $id * @param $action * @param string|array $options * @return string|null */ protected function o_viewerPreferences($id, $action, $options = '') { switch ($action) { case 'new': $this->objects[$id] = ['t' => 'viewerPreferences', 'info' => []]; break; case 'add': $o = &$this->objects[$id]; foreach ($options as $k => $v) { switch ($k) { // Boolean keys case 'HideToolbar': case 'HideMenubar': case 'HideWindowUI': case 'FitWindow': case 'CenterWindow': case 'DisplayDocTitle': case 'PickTrayByPDFSize': $o['info'][$k] = (bool)$v; break; // Integer keys case 'NumCopies': $o['info'][$k] = (int)$v; break; // Name keys case 'ViewArea': case 'ViewClip': case 'PrintClip': case 'PrintArea': $o['info'][$k] = (string)$v; break; // Named with limited valid values case 'NonFullScreenPageMode': if (!in_array($v, ['UseNone', 'UseOutlines', 'UseThumbs', 'UseOC'])) { break; } $o['info'][$k] = $v; break; case 'Direction': if (!in_array($v, ['L2R', 'R2L'])) { break; } $o['info'][$k] = $v; break; case 'PrintScaling': if (!in_array($v, ['None', 'AppDefault'])) { break; } $o['info'][$k] = $v; break; case 'Duplex': if (!in_array($v, ['None', 'Simplex', 'DuplexFlipShortEdge', 'DuplexFlipLongEdge'])) { break; } $o['info'][$k] = $v; break; // Integer array case 'PrintPageRange': // Cast to integer array foreach ($v as $vK => $vV) { $v[$vK] = (int)$vV; } $o['info'][$k] = array_values($v); break; } } break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< "; foreach ($o['info'] as $k => $v) { if (is_string($v)) { $v = '/' . $v; } elseif (is_int($v)) { $v = (string) $v; } elseif (is_bool($v)) { $v = ($v ? 'true' : 'false'); } elseif (is_array($v)) { $v = '[' . implode(' ', $v) . ']'; } $res .= "\n/$k $v"; } $res .= "\n>>\nendobj"; return $res; } return null; } /** * define the document catalog, the overall controller for the document * * @param $id * @param $action * @param string|array $options * @return string|null */ protected function o_catalog($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'catalog', 'info' => []]; $this->catalogId = $id; break; case 'acroform': case 'outlines': case 'pages': case 'openHere': case 'names': $o['info'][$action] = $options; break; case 'viewerPreferences': if (!isset($o['info']['viewerPreferences'])) { $this->numObj++; $this->o_viewerPreferences($this->numObj, 'new'); $o['info']['viewerPreferences'] = $this->numObj; } $vp = $o['info']['viewerPreferences']; $this->o_viewerPreferences($vp, 'add', $options); break; case 'out': $res = "\n$id 0 obj\n<< /Type /Catalog"; foreach ($o['info'] as $k => $v) { switch ($k) { case 'outlines': $res .= "\n/Outlines $v 0 R"; break; case 'pages': $res .= "\n/Pages $v 0 R"; break; case 'viewerPreferences': $res .= "\n/ViewerPreferences $v 0 R"; break; case 'openHere': $res .= "\n/OpenAction $v 0 R"; break; case 'names': $res .= "\n/Names $v 0 R"; break; case 'acroform': $res .= "\n/AcroForm $v 0 R"; break; } } $res .= " >>\nendobj"; return $res; } return null; } /** * object which is a parent to the pages in the document * * @param $id * @param $action * @param string $options * @return string|null */ protected function o_pages($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'pages', 'info' => []]; $this->o_catalog($this->catalogId, 'pages', $id); break; case 'page': if (!is_array($options)) { // then it will just be the id of the new page $o['info']['pages'][] = $options; } else { // then it should be an array having 'id','rid','pos', where rid=the page to which this one will be placed relative // and pos is either 'before' or 'after', saying where this page will fit. if (isset($options['id']) && isset($options['rid']) && isset($options['pos'])) { $i = array_search($options['rid'], $o['info']['pages']); if (isset($o['info']['pages'][$i]) && $o['info']['pages'][$i] == $options['rid']) { // then there is a match // make a space switch ($options['pos']) { case 'before': $k = $i; break; case 'after': $k = $i + 1; break; default: $k = -1; break; } if ($k >= 0) { for ($j = count($o['info']['pages']) - 1; $j >= $k; $j--) { $o['info']['pages'][$j + 1] = $o['info']['pages'][$j]; } $o['info']['pages'][$k] = $options['id']; } } } } break; case 'procset': $o['info']['procset'] = $options; break; case 'mediaBox': $o['info']['mediaBox'] = $options; // which should be an array of 4 numbers $this->currentPageSize = ['width' => $options[2], 'height' => $options[3]]; break; case 'font': $o['info']['fonts'][] = ['objNum' => $options['objNum'], 'fontNum' => $options['fontNum']]; break; case 'extGState': $o['info']['extGStates'][] = ['objNum' => $options['objNum'], 'stateNum' => $options['stateNum']]; break; case 'xObject': $o['info']['xObjects'][] = ['objNum' => $options['objNum'], 'label' => $options['label']]; break; case 'out': if (count($o['info']['pages'])) { $res = "\n$id 0 obj\n<< /Type /Pages\n/Kids ["; foreach ($o['info']['pages'] as $v) { $res .= "$v 0 R\n"; } $res .= "]\n/Count " . count($this->objects[$id]['info']['pages']); if ((isset($o['info']['fonts']) && count($o['info']['fonts'])) || isset($o['info']['procset']) || (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) ) { $res .= "\n/Resources <<"; if (isset($o['info']['procset'])) { $res .= "\n/ProcSet " . $o['info']['procset'] . " 0 R"; } if (isset($o['info']['fonts']) && count($o['info']['fonts'])) { $res .= "\n/Font << "; foreach ($o['info']['fonts'] as $finfo) { $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; } $res .= "\n>>"; } if (isset($o['info']['xObjects']) && count($o['info']['xObjects'])) { $res .= "\n/XObject << "; foreach ($o['info']['xObjects'] as $finfo) { $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; } $res .= "\n>>"; } if (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) { $res .= "\n/ExtGState << "; foreach ($o['info']['extGStates'] as $gstate) { $res .= "\n/GS" . $gstate['stateNum'] . " " . $gstate['objNum'] . " 0 R"; } $res .= "\n>>"; } $res .= "\n>>"; if (isset($o['info']['mediaBox'])) { $tmp = $o['info']['mediaBox']; $res .= "\n/MediaBox [" . sprintf( '%.3F %.3F %.3F %.3F', $tmp[0], $tmp[1], $tmp[2], $tmp[3] ) . ']'; } } $res .= "\n >>\nendobj"; } else { $res = "\n$id 0 obj\n<< /Type /Pages\n/Count 0\n>>\nendobj"; } return $res; } return null; } /** * define the outlines in the doc, empty for now * * @param $id * @param $action * @param string $options * @return string|null */ protected function o_outlines($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'outlines', 'info' => ['outlines' => []]]; $this->o_catalog($this->catalogId, 'outlines', $id); break; case 'outline': $o['info']['outlines'][] = $options; break; case 'out': if (count($o['info']['outlines'])) { $res = "\n$id 0 obj\n<< /Type /Outlines /Kids ["; foreach ($o['info']['outlines'] as $v) { $res .= "$v 0 R "; } $res .= "] /Count " . count($o['info']['outlines']) . " >>\nendobj"; } else { $res = "\n$id 0 obj\n<< /Type /Outlines /Count 0 >>\nendobj"; } return $res; } return null; } /** * an object to hold the font description * * @param $id * @param $action * @param string|array $options * @return string|null * @throws FontNotFoundException */ protected function o_font($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'font', 'info' => [ 'name' => $options['name'], 'fontFileName' => $options['fontFileName'], 'SubType' => 'Type1', 'isSubsetting' => $options['isSubsetting'] ] ]; $fontNum = $this->numFonts; $this->objects[$id]['info']['fontNum'] = $fontNum; // deal with the encoding and the differences if (isset($options['differences'])) { // then we'll need an encoding dictionary $this->numObj++; $this->o_fontEncoding($this->numObj, 'new', $options); $this->objects[$id]['info']['encodingDictionary'] = $this->numObj; } else { if (isset($options['encoding'])) { // we can specify encoding here switch ($options['encoding']) { case 'WinAnsiEncoding': case 'MacRomanEncoding': case 'MacExpertEncoding': $this->objects[$id]['info']['encoding'] = $options['encoding']; break; case 'none': break; default: $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; break; } } else { $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; } } if ($this->fonts[$options['fontFileName']]['isUnicode']) { // For Unicode fonts, we need to incorporate font data into // sub-sections that are linked from the primary font section. // Look at o_fontGIDtoCID and o_fontDescendentCID functions // for more information. // // All of this code is adapted from the excellent changes made to // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) $toUnicodeId = ++$this->numObj; $this->o_toUnicode($toUnicodeId, 'new'); $this->objects[$id]['info']['toUnicode'] = $toUnicodeId; $cidFontId = ++$this->numObj; $this->o_fontDescendentCID($cidFontId, 'new', $options); $this->objects[$id]['info']['cidFont'] = $cidFontId; } // also tell the pages node about the new font $this->o_pages($this->currentNode, 'font', ['fontNum' => $fontNum, 'objNum' => $id]); break; case 'add': $font_options = $this->processFont($id, $o['info']); if ($font_options !== false) { foreach ($font_options as $k => $v) { switch ($k) { case 'BaseFont': $o['info']['name'] = $v; break; case 'FirstChar': case 'LastChar': case 'Widths': case 'FontDescriptor': case 'SubType': $this->addMessage('o_font ' . $k . " : " . $v); $o['info'][$k] = $v; break; } } // pass values down to descendent font if (isset($o['info']['cidFont'])) { $this->o_fontDescendentCID($o['info']['cidFont'], 'add', $font_options); } } break; case 'out': if ($this->fonts[$this->objects[$id]['info']['fontFileName']]['isUnicode']) { // For Unicode fonts, we need to incorporate font data into // sub-sections that are linked from the primary font section. // Look at o_fontGIDtoCID and o_fontDescendentCID functions // for more information. // // All of this code is adapted from the excellent changes made to // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) $res = "\n$id 0 obj\n<fonts[$fontFileName])) { return false; } $font = &$this->fonts[$fontFileName]; $fileSuffix = $font['fileSuffix']; $fileSuffixLower = strtolower($font['fileSuffix']); $fbfile = "$fontFileName.$fileSuffix"; $isTtfFont = $fileSuffixLower === 'ttf'; $isPfbFont = $fileSuffixLower === 'pfb'; $this->addMessage('selectFont: checking for - ' . $fbfile); if (!$fileSuffix) { $this->addMessage( 'selectFont: pfb or ttf file not found, ok if this is one of the 14 standard fonts' ); return false; } else { $adobeFontName = isset($font['PostScriptName']) ? $font['PostScriptName'] : $font['FontName']; // $fontObj = $this->numObj; $this->addMessage("selectFont: adding font file - $fbfile - $adobeFontName"); // find the array of font widths, and put that into an object. $firstChar = -1; $lastChar = 0; $widths = []; $cid_widths = []; foreach ($font['C'] as $num => $d) { if (intval($num) > 0 || $num == '0') { if (!$font['isUnicode']) { // With Unicode, widths array isn't used if ($lastChar > 0 && $num > $lastChar + 1) { for ($i = $lastChar + 1; $i < $num; $i++) { $widths[] = 0; } } } $widths[] = $d; if ($font['isUnicode']) { $cid_widths[$num] = $d; } if ($firstChar == -1) { $firstChar = $num; } $lastChar = $num; } } // also need to adjust the widths for the differences array if (isset($object['differences'])) { foreach ($object['differences'] as $charNum => $charName) { if ($charNum > $lastChar) { if (!$object['isUnicode']) { // With Unicode, widths array isn't used for ($i = $lastChar + 1; $i <= $charNum; $i++) { $widths[] = 0; } } $lastChar = $charNum; } if (isset($font['C'][$charName])) { $widths[$charNum - $firstChar] = $font['C'][$charName]; if ($font['isUnicode']) { $cid_widths[$charName] = $font['C'][$charName]; } } } } if ($font['isUnicode']) { $font['CIDWidths'] = $cid_widths; } $this->addMessage('selectFont: FirstChar = ' . $firstChar); $this->addMessage('selectFont: LastChar = ' . $lastChar); $widthid = -1; if (!$font['isUnicode']) { // With Unicode, widths array isn't used $this->numObj++; $this->o_contents($this->numObj, 'new', 'raw'); $this->objects[$this->numObj]['c'] .= '[' . implode(' ', $widths) . ']'; $widthid = $this->numObj; } $missing_width = 500; $stemV = 70; if (isset($font['MissingWidth'])) { $missing_width = $font['MissingWidth']; } if (isset($font['StdVW'])) { $stemV = $font['StdVW']; } else { if (isset($font['Weight']) && preg_match('!(bold|black)!i', $font['Weight'])) { $stemV = 120; } } // load the pfb file, and put that into an object too. // note that pdf supports only binary format type 1 font files, though there is a // simple utility to convert them from pfa to pfb. if (!$font['isSubsetting']) { $data = file_get_contents($fbfile); } else { $adobeFontName = $this->getFontSubsettingTag($font) . '+' . $adobeFontName; $this->stringSubsets[$fontFileName][] = 32; // Force space if not in yet $subset = $this->stringSubsets[$fontFileName]; sort($subset); // Load font $font_obj = Font::load($fbfile); $font_obj->parse(); // Define subset $font_obj->setSubset($subset); $font_obj->reduce(); // Write new font $tmp_name = @tempnam($this->tmp, "cpdf_subset_"); $font_obj->open($tmp_name, BinaryStream::modeReadWrite); $font_obj->encode(["OS/2"]); $font_obj->close(); // Parse the new font to get cid2gid and widths $font_obj = Font::load($tmp_name); // Find Unicode char map table $subtable = null; foreach ($font_obj->getData("cmap", "subtables") as $_subtable) { if ($_subtable["platformID"] == 0 || $_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) { $subtable = $_subtable; break; } } if ($subtable) { $glyphIndexArray = $subtable["glyphIndexArray"]; $hmtx = $font_obj->getData("hmtx"); unset($glyphIndexArray[0xFFFF]); $cidtogid = str_pad('', max(array_keys($glyphIndexArray)) * 2 + 1, "\x00"); $font['CIDWidths'] = []; foreach ($glyphIndexArray as $cid => $gid) { if ($cid >= 0 && $cid < 0xFFFF && $gid) { $cidtogid[$cid * 2] = chr($gid >> 8); $cidtogid[$cid * 2 + 1] = chr($gid & 0xFF); } $width = $font_obj->normalizeFUnit(isset($hmtx[$gid]) ? $hmtx[$gid][0] : $hmtx[0][0]); $font['CIDWidths'][$cid] = $width; } $font['CIDtoGID'] = base64_encode(gzcompress($cidtogid)); $font['CIDtoGID_Compressed'] = true; $data = file_get_contents($tmp_name); } else { $data = file_get_contents($fbfile); } $font_obj->close(); unlink($tmp_name); } // create the font descriptor $this->numObj++; $fontDescriptorId = $this->numObj; $this->numObj++; $pfbid = $this->numObj; // determine flags (more than a little flakey, hopefully will not matter much) $flags = 0; if ($font['ItalicAngle'] != 0) { $flags += pow(2, 6); } if ($font['IsFixedPitch'] === 'true') { $flags += 1; } $flags += pow(2, 5); // assume non-sybolic $list = [ 'Ascent' => 'Ascender', 'CapHeight' => 'Ascender', //FIXME: php-font-lib is not grabbing this value, so we'll fake it and use the Ascender value // 'CapHeight' 'MissingWidth' => 'MissingWidth', 'Descent' => 'Descender', 'FontBBox' => 'FontBBox', 'ItalicAngle' => 'ItalicAngle' ]; $fdopt = [ 'Flags' => $flags, 'FontName' => $adobeFontName, 'StemV' => $stemV ]; foreach ($list as $k => $v) { if (isset($font[$v])) { $fdopt[$k] = $font[$v]; } } if ($isPfbFont) { $fdopt['FontFile'] = $pfbid; } elseif ($isTtfFont) { $fdopt['FontFile2'] = $pfbid; } $this->o_fontDescriptor($fontDescriptorId, 'new', $fdopt); // embed the font program $this->o_contents($this->numObj, 'new'); $this->objects[$pfbid]['c'] .= $data; // determine the cruicial lengths within this file if ($isPfbFont) { $l1 = strpos($data, 'eexec') + 6; $l2 = strpos($data, '00000000') - $l1; $l3 = mb_strlen($data, '8bit') - $l2 - $l1; $this->o_contents( $this->numObj, 'add', ['Length1' => $l1, 'Length2' => $l2, 'Length3' => $l3] ); } elseif ($isTtfFont) { $l1 = mb_strlen($data, '8bit'); $this->o_contents($this->numObj, 'add', ['Length1' => $l1]); } // tell the font object about all this new stuff $options = [ 'BaseFont' => $adobeFontName, 'MissingWidth' => $missing_width, 'Widths' => $widthid, 'FirstChar' => $firstChar, 'LastChar' => $lastChar, 'FontDescriptor' => $fontDescriptorId ]; if ($isTtfFont) { $options['SubType'] = 'TrueType'; } $this->addMessage("adding extra info to font.($fontObjId)"); foreach ($options as $fk => $fv) { $this->addMessage("$fk : $fv"); } } return $options; } /** * A toUnicode section, needed for unicode fonts * * @param $id * @param $action * @return null|string */ protected function o_toUnicode($id, $action) { switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'toUnicode' ]; break; case 'add': break; case 'out': $ordering = 'UCS'; $registry = 'Adobe'; if ($this->encrypted) { $this->encryptInit($id); $ordering = $this->ARC4($ordering); $registry = $this->filterText($this->ARC4($registry), false, false); } $stream = <<> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 1 beginbfrange <0000> <0000> endbfrange endcmap CMapName currentdict /CMap defineresource pop end end EOT; $res = "\n$id 0 obj\n"; $res .= "<>\n"; $res .= "stream\n" . $stream . "\nendstream" . "\nendobj";; return $res; } return null; } /** * a font descriptor, needed for including additional fonts * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_fontDescriptor($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'fontDescriptor', 'info' => $options]; break; case 'out': $res = "\n$id 0 obj\n<< /Type /FontDescriptor\n"; foreach ($o['info'] as $label => $value) { switch ($label) { case 'Ascent': case 'CapHeight': case 'Descent': case 'Flags': case 'ItalicAngle': case 'StemV': case 'AvgWidth': case 'Leading': case 'MaxWidth': case 'MissingWidth': case 'StemH': case 'XHeight': case 'CharSet': if (mb_strlen($value, '8bit')) { $res .= "/$label $value\n"; } break; case 'FontFile': case 'FontFile2': case 'FontFile3': $res .= "/$label $value 0 R\n"; break; case 'FontBBox': $res .= "/$label [$value[0] $value[1] $value[2] $value[3]]\n"; break; case 'FontName': $res .= "/$label /$value\n"; break; } } $res .= ">>\nendobj"; return $res; } return null; } /** * the font encoding * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_fontEncoding($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': // the options array should contain 'differences' and maybe 'encoding' $this->objects[$id] = ['t' => 'fontEncoding', 'info' => $options]; break; case 'out': $res = "\n$id 0 obj\n<< /Type /Encoding\n"; if (!isset($o['info']['encoding'])) { $o['info']['encoding'] = 'WinAnsiEncoding'; } if ($o['info']['encoding'] !== 'none') { $res .= "/BaseEncoding /" . $o['info']['encoding'] . "\n"; } $res .= "/Differences \n["; $onum = -100; foreach ($o['info']['differences'] as $num => $label) { if ($num != $onum + 1) { // we cannot make use of consecutive numbering $res .= "\n$num /$label"; } else { $res .= " /$label"; } $onum = $num; } $res .= "\n]\n>>\nendobj"; return $res; } return null; } /** * a descendent cid font, needed for unicode fonts * * @param $id * @param $action * @param string|array $options * @return null|string */ protected function o_fontDescendentCID($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'fontDescendentCID', 'info' => $options]; // we need a CID system info section $cidSystemInfoId = ++$this->numObj; $this->o_cidSystemInfo($cidSystemInfoId, 'new'); $this->objects[$id]['info']['cidSystemInfo'] = $cidSystemInfoId; // and a CID to GID map $cidToGidMapId = ++$this->numObj; $this->o_fontGIDtoCIDMap($cidToGidMapId, 'new', $options); $this->objects[$id]['info']['cidToGidMap'] = $cidToGidMapId; break; case 'add': foreach ($options as $k => $v) { switch ($k) { case 'BaseFont': $o['info']['name'] = $v; break; case 'FirstChar': case 'LastChar': case 'MissingWidth': case 'FontDescriptor': case 'SubType': $this->addMessage("o_fontDescendentCID $k : $v"); $o['info'][$k] = $v; break; } } // pass values down to cid to gid map $this->o_fontGIDtoCIDMap($o['info']['cidToGidMap'], 'add', $options); break; case 'out': $res = "\n$id 0 obj\n"; $res .= "<fonts[$o['info']['fontFileName']]['CIDWidths'])) { $cid_widths = &$this->fonts[$o['info']['fontFileName']]['CIDWidths']; $w = ''; foreach ($cid_widths as $cid => $width) { $w .= "$cid [$width] "; } $res .= "/W [$w]\n"; } $res .= "/CIDToGIDMap " . $o['info']['cidToGidMap'] . " 0 R\n"; $res .= ">>\n"; $res .= "endobj"; return $res; } return null; } /** * CID system info section, needed for unicode fonts * * @param $id * @param $action * @return null|string */ protected function o_cidSystemInfo($id, $action) { switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'cidSystemInfo' ]; break; case 'add': break; case 'out': $ordering = 'UCS'; $registry = 'Adobe'; if ($this->encrypted) { $this->encryptInit($id); $ordering = $this->ARC4($ordering); $registry = $this->ARC4($registry); } $res = "\n$id 0 obj\n"; $res .= '<objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'fontGIDtoCIDMap', 'info' => $options]; break; case 'out': $res = "\n$id 0 obj\n"; $fontFileName = $o['info']['fontFileName']; $tmp = $this->fonts[$fontFileName]['CIDtoGID'] = base64_decode($this->fonts[$fontFileName]['CIDtoGID']); $compressed = isset($this->fonts[$fontFileName]['CIDtoGID_Compressed']) && $this->fonts[$fontFileName]['CIDtoGID_Compressed']; if (!$compressed && isset($o['raw'])) { $res .= $tmp; } else { $res .= "<<"; if (!$compressed && $this->compressionReady && $this->options['compression']) { // then implement ZLIB based compression on this content stream $compressed = true; $tmp = gzcompress($tmp, 6); } if ($compressed) { $res .= "\n/Filter /FlateDecode"; } if ($this->encrypted) { $this->encryptInit($id); $tmp = $this->ARC4($tmp); } $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream"; } $res .= "\nendobj"; return $res; } return null; } /** * the document procset, solves some problems with printing to old PS printers * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_procset($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'procset', 'info' => ['PDF' => 1, 'Text' => 1]]; $this->o_pages($this->currentNode, 'procset', $id); $this->procsetObjectId = $id; break; case 'add': // this is to add new items to the procset list, despite the fact that this is considered // obsolete, the items are required for printing to some postscript printers switch ($options) { case 'ImageB': case 'ImageC': case 'ImageI': $o['info'][$options] = 1; break; } break; case 'out': $res = "\n$id 0 obj\n["; foreach ($o['info'] as $label => $val) { $res .= "/$label "; } $res .= "]\nendobj"; return $res; } return null; } /** * define the document information * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_info($id, $action, $options = '') { switch ($action) { case 'new': $this->infoObject = $id; $date = 'D:' . @date('Ymd'); $this->objects[$id] = [ 't' => 'info', 'info' => [ 'Producer' => 'CPDF (dompdf)', 'CreationDate' => $date ] ]; break; case 'Title': case 'Author': case 'Subject': case 'Keywords': case 'Creator': case 'Producer': case 'CreationDate': case 'ModDate': case 'Trapped': $this->objects[$id]['info'][$action] = $options; break; case 'out': $encrypted = $this->encrypted; if ($encrypted) { $this->encryptInit($id); } $res = "\n$id 0 obj\n<<\n"; $o = &$this->objects[$id]; foreach ($o['info'] as $k => $v) { $res .= "/$k ("; // dates must be outputted as-is, without Unicode transformations if ($k !== 'CreationDate' && $k !== 'ModDate') { $v = $this->utf8toUtf16BE($v); } if ($encrypted) { $v = $this->ARC4($v); } $res .= $this->filterText($v, false, false); $res .= ")\n"; } $res .= ">>\nendobj"; return $res; } return null; } /** * an action object, used to link to URLS initially * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_action($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': if (is_array($options)) { $this->objects[$id] = ['t' => 'action', 'info' => $options, 'type' => $options['type']]; } else { // then assume a URI action $this->objects[$id] = ['t' => 'action', 'info' => $options, 'type' => 'URI']; } break; case 'out': if ($this->encrypted) { $this->encryptInit($id); } $res = "\n$id 0 obj\n<< /Type /Action"; switch ($o['type']) { case 'ilink': if (!isset($this->destinations[(string)$o['info']['label']])) { break; } // there will be an 'label' setting, this is the name of the destination $res .= "\n/S /GoTo\n/D " . $this->destinations[(string)$o['info']['label']] . " 0 R"; break; case 'URI': $res .= "\n/S /URI\n/URI ("; if ($this->encrypted) { $res .= $this->filterText($this->ARC4($o['info']), false, false); } else { $res .= $this->filterText($o['info'], false, false); } $res .= ")"; break; } $res .= "\n>>\nendobj"; return $res; } return null; } /** * an annotation object, this will add an annotation to the current page. * initially will support just link annotations * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_annotation($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': // add the annotation to the current page $pageId = $this->currentPage; $this->o_page($pageId, 'annot', $id); // and add the action object which is going to be required switch ($options['type']) { case 'link': $this->objects[$id] = ['t' => 'annotation', 'info' => $options]; $this->numObj++; $this->o_action($this->numObj, 'new', $options['url']); $this->objects[$id]['info']['actionId'] = $this->numObj; break; case 'ilink': // this is to a named internal link $label = $options['label']; $this->objects[$id] = ['t' => 'annotation', 'info' => $options]; $this->numObj++; $this->o_action($this->numObj, 'new', ['type' => 'ilink', 'label' => $label]); $this->objects[$id]['info']['actionId'] = $this->numObj; break; } break; case 'out': $res = "\n$id 0 obj\n<< /Type /Annot"; switch ($o['info']['type']) { case 'link': case 'ilink': $res .= "\n/Subtype /Link"; break; } $res .= "\n/A " . $o['info']['actionId'] . " 0 R"; $res .= "\n/Border [0 0 0]"; $res .= "\n/H /I"; $res .= "\n/Rect [ "; foreach ($o['info']['rect'] as $v) { $res .= sprintf("%.4F ", $v); } $res .= "]"; $res .= "\n>>\nendobj"; return $res; } return null; } /** * a page object, it also creates a contents object to hold its contents * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_page($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->numPages++; $this->objects[$id] = [ 't' => 'page', 'info' => [ 'parent' => $this->currentNode, 'pageNum' => $this->numPages, 'mediaBox' => $this->objects[$this->currentNode]['info']['mediaBox'] ] ]; if (is_array($options)) { // then this must be a page insertion, array should contain 'rid','pos'=[before|after] $options['id'] = $id; $this->o_pages($this->currentNode, 'page', $options); } else { $this->o_pages($this->currentNode, 'page', $id); } $this->currentPage = $id; //make a contents object to go with this page $this->numObj++; $this->o_contents($this->numObj, 'new', $id); $this->currentContents = $this->numObj; $this->objects[$id]['info']['contents'] = []; $this->objects[$id]['info']['contents'][] = $this->numObj; $match = ($this->numPages % 2 ? 'odd' : 'even'); foreach ($this->addLooseObjects as $oId => $target) { if ($target === 'all' || $match === $target) { $this->objects[$id]['info']['contents'][] = $oId; } } break; case 'content': $o['info']['contents'][] = $options; break; case 'annot': // add an annotation to this page if (!isset($o['info']['annot'])) { $o['info']['annot'] = []; } // $options should contain the id of the annotation dictionary $o['info']['annot'][] = $options; break; case 'out': $res = "\n$id 0 obj\n<< /Type /Page"; if (isset($o['info']['mediaBox'])) { $tmp = $o['info']['mediaBox']; $res .= "\n/MediaBox [" . sprintf( '%.3F %.3F %.3F %.3F', $tmp[0], $tmp[1], $tmp[2], $tmp[3] ) . ']'; } $res .= "\n/Parent " . $o['info']['parent'] . " 0 R"; if (isset($o['info']['annot'])) { $res .= "\n/Annots ["; foreach ($o['info']['annot'] as $aId) { $res .= " $aId 0 R"; } $res .= " ]"; } $count = count($o['info']['contents']); if ($count == 1) { $res .= "\n/Contents " . $o['info']['contents'][0] . " 0 R"; } else { if ($count > 1) { $res .= "\n/Contents [\n"; // reverse the page contents so added objects are below normal content //foreach (array_reverse($o['info']['contents']) as $cId) { // Back to normal now that I've got transparency working --Benj foreach ($o['info']['contents'] as $cId) { $res .= "$cId 0 R\n"; } $res .= "]"; } } $res .= "\n>>\nendobj"; return $res; } return null; } /** * the contents objects hold all of the content which appears on pages * * @param $id * @param $action * @param string|array $options * @return null|string */ protected function o_contents($id, $action, $options = '') { if ($action !== 'new') { $o = &$this->objects[$id]; } switch ($action) { case 'new': $this->objects[$id] = ['t' => 'contents', 'c' => '', 'info' => []]; if (mb_strlen($options, '8bit') && intval($options)) { // then this contents is the primary for a page $this->objects[$id]['onPage'] = $options; } else { if ($options === 'raw') { // then this page contains some other type of system object $this->objects[$id]['raw'] = 1; } } break; case 'add': // add more options to the declaration foreach ($options as $k => $v) { $o['info'][$k] = $v; } case 'out': $tmp = $o['c']; $res = "\n$id 0 obj\n"; if (isset($this->objects[$id]['raw'])) { $res .= $tmp; } else { $res .= "<<"; if ($this->compressionReady && $this->options['compression']) { // then implement ZLIB based compression on this content stream $res .= " /Filter /FlateDecode"; $tmp = gzcompress($tmp, 6); } if ($this->encrypted) { $this->encryptInit($id); $tmp = $this->ARC4($tmp); } foreach ($o['info'] as $k => $v) { $res .= "\n/$k $v"; } $res .= "\n/Length " . mb_strlen($tmp, '8bit') . " >>\nstream\n$tmp\nendstream"; } $res .= "\nendobj"; return $res; } return null; } /** * @param $id * @param $action * @return string|null */ protected function o_embedjs($id, $action) { switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'embedjs', 'info' => [ 'Names' => '[(EmbeddedJS) ' . ($id + 1) . ' 0 R]' ] ]; break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< "; foreach ($o['info'] as $k => $v) { $res .= "\n/$k $v"; } $res .= "\n>>\nendobj"; return $res; } return null; } /** * @param $id * @param $action * @param string $code * @return null|string */ protected function o_javascript($id, $action, $code = '') { switch ($action) { case 'new': $this->objects[$id] = [ 't' => 'javascript', 'info' => [ 'S' => '/JavaScript', 'JS' => '(' . $this->filterText($code, true, false) . ')', ] ]; break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< "; foreach ($o['info'] as $k => $v) { $res .= "\n/$k $v"; } $res .= "\n>>\nendobj"; return $res; } return null; } /** * an image object, will be an XObject in the document, includes description and data * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_image($id, $action, $options = '') { switch ($action) { case 'new': // make the new object $this->objects[$id] = ['t' => 'image', 'data' => &$options['data'], 'info' => []]; $info =& $this->objects[$id]['info']; $info['Type'] = '/XObject'; $info['Subtype'] = '/Image'; $info['Width'] = $options['iw']; $info['Height'] = $options['ih']; if (isset($options['masked']) && $options['masked']) { $info['SMask'] = ($this->numObj - 1) . ' 0 R'; } if (!isset($options['type']) || $options['type'] === 'jpg') { if (!isset($options['channels'])) { $options['channels'] = 3; } switch ($options['channels']) { case 1: $info['ColorSpace'] = '/DeviceGray'; break; case 4: $info['ColorSpace'] = '/DeviceCMYK'; break; default: $info['ColorSpace'] = '/DeviceRGB'; break; } if ($info['ColorSpace'] === '/DeviceCMYK') { $info['Decode'] = '[1 0 1 0 1 0 1 0]'; } $info['Filter'] = '/DCTDecode'; $info['BitsPerComponent'] = 8; } else { if ($options['type'] === 'png') { $info['Filter'] = '/FlateDecode'; $info['DecodeParms'] = '<< /Predictor 15 /Colors ' . $options['ncolor'] . ' /Columns ' . $options['iw'] . ' /BitsPerComponent ' . $options['bitsPerComponent'] . '>>'; if ($options['isMask']) { $info['ColorSpace'] = '/DeviceGray'; } else { if (mb_strlen($options['pdata'], '8bit')) { $tmp = ' [ /Indexed /DeviceRGB ' . (mb_strlen($options['pdata'], '8bit') / 3 - 1) . ' '; $this->numObj++; $this->o_contents($this->numObj, 'new'); $this->objects[$this->numObj]['c'] = $options['pdata']; $tmp .= $this->numObj . ' 0 R'; $tmp .= ' ]'; $info['ColorSpace'] = $tmp; if (isset($options['transparency'])) { $transparency = $options['transparency']; switch ($transparency['type']) { case 'indexed': $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; $info['Mask'] = $tmp; break; case 'color-key': $tmp = ' [ ' . $transparency['r'] . ' ' . $transparency['r'] . $transparency['g'] . ' ' . $transparency['g'] . $transparency['b'] . ' ' . $transparency['b'] . ' ] '; $info['Mask'] = $tmp; break; } } } else { if (isset($options['transparency'])) { $transparency = $options['transparency']; switch ($transparency['type']) { case 'indexed': $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; $info['Mask'] = $tmp; break; case 'color-key': $tmp = ' [ ' . $transparency['r'] . ' ' . $transparency['r'] . ' ' . $transparency['g'] . ' ' . $transparency['g'] . ' ' . $transparency['b'] . ' ' . $transparency['b'] . ' ] '; $info['Mask'] = $tmp; break; } } $info['ColorSpace'] = '/' . $options['color']; } } $info['BitsPerComponent'] = $options['bitsPerComponent']; } } // assign it a place in the named resource dictionary as an external object, according to // the label passed in with it. $this->o_pages($this->currentNode, 'xObject', ['label' => $options['label'], 'objNum' => $id]); // also make sure that we have the right procset object for it. $this->o_procset($this->procsetObjectId, 'add', 'ImageC'); break; case 'out': $o = &$this->objects[$id]; $tmp = &$o['data']; $res = "\n$id 0 obj\n<<"; foreach ($o['info'] as $k => $v) { $res .= "\n/$k $v"; } if ($this->encrypted) { $this->encryptInit($id); $tmp = $this->ARC4($tmp); } $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream\nendobj"; return $res; } return null; } /** * graphics state object * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_extGState($id, $action, $options = "") { static $valid_params = [ "LW", "LC", "LC", "LJ", "ML", "D", "RI", "OP", "op", "OPM", "Font", "BG", "BG2", "UCR", "TR", "TR2", "HT", "FL", "SM", "SA", "BM", "SMask", "CA", "ca", "AIS", "TK" ]; switch ($action) { case "new": $this->objects[$id] = ['t' => 'extGState', 'info' => $options]; // Tell the pages about the new resource $this->numStates++; $this->o_pages($this->currentNode, 'extGState', ["objNum" => $id, "stateNum" => $this->numStates]); break; case "out": $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< /Type /ExtGState\n"; foreach ($o["info"] as $k => $v) { if (!in_array($k, $valid_params)) { continue; } $res .= "/$k $v\n"; } $res .= ">>\nendobj"; return $res; } return null; } /** * @param integer $id * @param string $action * @param mixed $options * @return string */ protected function o_xobject($id, $action, $options = '') { switch ($action) { case 'new': $this->objects[$id] = ['t' => 'xobject', 'info' => $options, 'c' => '']; break; case 'procset': $this->objects[$id]['procset'] = $options; break; case 'font': $this->objects[$id]['fonts'][$options['fontNum']] = [ 'objNum' => $options['objNum'], 'fontNum' => $options['fontNum'] ]; break; case 'xObject': $this->objects[$id]['xObjects'][] = ['objNum' => $options['objNum'], 'label' => $options['label']]; break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< /Type /XObject\n"; foreach ($o["info"] as $k => $v) { switch($k) { case 'Subtype': $res .= "/Subtype /$v\n"; break; case 'bbox': $res .= "/BBox ["; foreach ($v as $value) { $res .= sprintf("%.4F ", $value); } $res .= "]\n"; break; default: $res .= "/$k $v\n"; break; } } $res .= "/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]\n"; $res .= "/Resources <<"; if (isset($o['procset'])) { $res .= "\n/ProcSet " . $o['procset'] . " 0 R"; } else { $res .= "\n/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"; } if (isset($o['fonts']) && count($o['fonts'])) { $res .= "\n/Font << "; foreach ($o['fonts'] as $finfo) { $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; } $res .= "\n>>"; } if (isset($o['xObjects']) && count($o['xObjects'])) { $res .= "\n/XObject << "; foreach ($o['xObjects'] as $finfo) { $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; } $res .= "\n>>"; } $res .= "\n>>\n"; $tmp = $o["c"]; if ($this->compressionReady && $this->options['compression']) { // then implement ZLIB based compression on this content stream $res .= " /Filter /FlateDecode\n"; $tmp = gzcompress($tmp, 6); } if ($this->encrypted) { $this->encryptInit($id); $tmp = $this->ARC4($tmp); } $res .= "/Length " . mb_strlen($tmp, '8bit') . " >>\n"; $res .= "stream\n" . $tmp . "\nendstream" . "\nendobj";; return $res; } return null; } /** * @param $id * @param $action * @param string $options * @return null|string */ protected function o_acroform($id, $action, $options = '') { switch ($action) { case "new": $this->o_catalog($this->catalogId, 'acroform', $id); $this->objects[$id] = array('t' => 'acroform', 'info' => $options); break; case 'addfield': $this->objects[$id]['info']['Fields'][] = $options; break; case 'font': $this->objects[$id]['fonts'][$options['fontNum']] = [ 'objNum' => $options['objNum'], 'fontNum' => $options['fontNum'] ]; break; case "out": $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<<"; foreach ($o["info"] as $k => $v) { switch($k) { case 'Fields': $res .= " /Fields ["; foreach ($v as $i) { $res .= "$i 0 R "; } $res .= "]\n"; break; default: $res .= "/$k $v\n"; } } $res .= "/DR <<\n"; if (isset($o['fonts']) && count($o['fonts'])) { $res .= "/Font << \n"; foreach ($o['fonts'] as $finfo) { $res .= "/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R\n"; } $res .= ">>\n"; } $res .= ">>\n"; $res .= ">>\nendobj"; return $res; } return null; } /** * @param $id * @param $action * @param mixed $options * @return null|string */ protected function o_field($id, $action, $options = '') { switch ($action) { case "new": $this->o_page($options['pageid'], 'annot', $id); $this->o_acroform($this->acroFormId, 'addfield', $id); $this->objects[$id] = ['t' => 'field', 'info' => $options]; break; case 'set': $this->objects[$id]['info'] = array_merge($this->objects[$id]['info'], $options); break; case "out": $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<< /Type /Annot /Subtype /Widget \n"; $encrypted = $this->encrypted; if ($encrypted) { $this->encryptInit($id); } foreach ($o["info"] as $k => $v) { switch ($k) { case 'pageid': $res .= "/P $v 0 R\n"; break; case 'value': if ($encrypted) { $v = $this->filterText($this->ARC4($v), false, false); } $res .= "/V ($v)\n"; break; case 'refvalue': $res .= "/V $v 0 R\n"; break; case 'da': if ($encrypted) { $v = $this->filterText($this->ARC4($v), false, false); } $res .= "/DA ($v)\n"; break; case 'options': $res .= "/Opt [\n"; foreach ($v as $opt) { if ($encrypted) { $opt = $this->filterText($this->ARC4($opt), false, false); } $res .= "($opt)\n"; } $res .= "]\n"; break; case 'rect': $res .= "/Rect ["; foreach ($v as $value) { $res .= sprintf("%.4F ", $value); } $res .= "]\n"; break; case 'appearance': $res .= "/AP << "; foreach ($v as $a => $ref) { $res .= "/$a $ref 0 R "; } $res .= ">>\n"; break; case 'T': if($encrypted) { $v = $this->filterText($this->ARC4($v), false, false); } $res .= "/T ($v)\n"; break; default: $res .= "/$k $v\n"; } } $res .= ">>\nendobj"; return $res; } return null; } /** * * @param $id * @param $action * @param string $options * @return null|string */ protected function o_sig($id, $action, $options = '') { $sign_maxlen = $this->signatureMaxLen; switch ($action) { case "new": $this->objects[$id] = array('t' => 'sig', 'info' => $options); $this->byteRange[$id] = ['t' => 'sig']; break; case 'byterange': $o = &$this->objects[$id]; $content =& $options['content']; $content_len = strlen($content); $pos = strpos($content, sprintf("/ByteRange [ %'.010d", $id)); $len = strlen('/ByteRange [ ********** ********** ********** ********** ]'); $rangeStartPos = $pos + $len + 1 + 10; // before '<' $content = substr_replace($content, str_pad(sprintf('/ByteRange [ 0 %u %u %u ]', $rangeStartPos, $rangeStartPos + $sign_maxlen + 2, $content_len - 2 - $sign_maxlen - $rangeStartPos ), $len, ' ', STR_PAD_RIGHT), $pos, $len); $fuid = uniqid(); $tmpInput = $this->tmp . "/pkcs7.tmp." . $fuid . '.in'; $tmpOutput = $this->tmp . "/pkcs7.tmp." . $fuid . '.out'; if (file_put_contents($tmpInput, substr($content, 0, $rangeStartPos)) === false) { throw new \Exception("Unable to write temporary file for signing."); } if (file_put_contents($tmpInput, substr($content, $rangeStartPos + 2 + $sign_maxlen), FILE_APPEND) === false) { throw new \Exception("Unable to write temporary file for signing."); } if (openssl_pkcs7_sign($tmpInput, $tmpOutput, $o['info']['SignCert'], array($o['info']['PrivKey'], $o['info']['Password']), array(), PKCS7_BINARY | PKCS7_DETACHED) === false) { throw new \Exception("Failed to prepare signature."); } $signature = file_get_contents($tmpOutput); unlink($tmpInput); unlink($tmpOutput); $sign = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13)); list($head, $signature) = explode("\n\n", $sign); $signature = base64_decode(trim($signature)); $signature = current(unpack('H*', $signature)); $signature = str_pad($signature, $sign_maxlen, '0'); $siglen = strlen($signature); if (strlen($signature) > $sign_maxlen) { throw new \Exception("Signature length ($siglen) exceeds the $sign_maxlen limit."); } $content = substr_replace($content, $signature, $rangeStartPos + 1, $sign_maxlen); break; case "out": $res = "\n$id 0 obj\n<<\n"; $encrypted = $this->encrypted; if ($encrypted) { $this->encryptInit($id); } $res .= "/ByteRange " .sprintf("[ %'.010d ********** ********** ********** ]\n", $id); $res .= "/Contents <" . str_pad('', $sign_maxlen, '0') . ">\n"; $res .= "/Filter/Adobe.PPKLite\n"; //PPKMS \n"; $res .= "/Type/Sig/SubFilter/adbe.pkcs7.detached \n"; $date = "D:" . substr_replace(date('YmdHisO'), '\'', -2, 0) . '\''; if ($encrypted) { $date = $this->ARC4($date); } $res .= "/M ($date)\n"; $res .= "/Prop_Build << /App << /Name /DomPDF >> /Filter << /Name /Adobe.PPKLite >> >>\n"; $o = &$this->objects[$id]; foreach ($o['info'] as $k => $v) { switch($k) { case 'Name': case 'Location': case 'Reason': case 'ContactInfo': if ($v !== null && $v !== '') { $res .= "/$k (" . ($encrypted ? $this->filterText($this->ARC4($v), false, false) : $v) . ") \n"; } break; } } $res .= ">>\nendobj"; return $res; } return null; } /** * encryption object. * * @param $id * @param $action * @param string $options * @return string|null */ protected function o_encryption($id, $action, $options = '') { switch ($action) { case 'new': // make the new object $this->objects[$id] = ['t' => 'encryption', 'info' => $options]; $this->arc4_objnum = $id; break; case 'keys': // figure out the additional parameters required $pad = chr(0x28) . chr(0xBF) . chr(0x4E) . chr(0x5E) . chr(0x4E) . chr(0x75) . chr(0x8A) . chr(0x41) . chr(0x64) . chr(0x00) . chr(0x4E) . chr(0x56) . chr(0xFF) . chr(0xFA) . chr(0x01) . chr(0x08) . chr(0x2E) . chr(0x2E) . chr(0x00) . chr(0xB6) . chr(0xD0) . chr(0x68) . chr(0x3E) . chr(0x80) . chr(0x2F) . chr(0x0C) . chr(0xA9) . chr(0xFE) . chr(0x64) . chr(0x53) . chr(0x69) . chr(0x7A); $info = $this->objects[$id]['info']; $len = mb_strlen($info['owner'], '8bit'); if ($len > 32) { $owner = substr($info['owner'], 0, 32); } else { if ($len < 32) { $owner = $info['owner'] . substr($pad, 0, 32 - $len); } else { $owner = $info['owner']; } } $len = mb_strlen($info['user'], '8bit'); if ($len > 32) { $user = substr($info['user'], 0, 32); } else { if ($len < 32) { $user = $info['user'] . substr($pad, 0, 32 - $len); } else { $user = $info['user']; } } $tmp = $this->md5_16($owner); $okey = substr($tmp, 0, 5); $this->ARC4_init($okey); $ovalue = $this->ARC4($user); $this->objects[$id]['info']['O'] = $ovalue; // now make the u value, phew. $tmp = $this->md5_16( $user . $ovalue . chr($info['p']) . chr(255) . chr(255) . chr(255) . hex2bin($this->fileIdentifier) ); $ukey = substr($tmp, 0, 5); $this->ARC4_init($ukey); $this->encryptionKey = $ukey; $this->encrypted = true; $uvalue = $this->ARC4($pad); $this->objects[$id]['info']['U'] = $uvalue; // initialize the arc4 array break; case 'out': $o = &$this->objects[$id]; $res = "\n$id 0 obj\n<<"; $res .= "\n/Filter /Standard"; $res .= "\n/V 1"; $res .= "\n/R 2"; $res .= "\n/O (" . $this->filterText($o['info']['O'], false, false) . ')'; $res .= "\n/U (" . $this->filterText($o['info']['U'], false, false) . ')'; // and the p-value needs to be converted to account for the twos-complement approach $o['info']['p'] = (($o['info']['p'] ^ 255) + 1) * -1; $res .= "\n/P " . ($o['info']['p']); $res .= "\n>>\nendobj"; return $res; } return null; } protected function o_indirect_references($id, $action, $options = null) { switch ($action) { case 'new': case 'add': if ($id === 0) { $id = ++$this->numObj; $this->o_catalog($this->catalogId, 'names', $id); $this->objects[$id] = ['t' => 'indirect_references', 'info' => $options]; $this->indirectReferenceId = $id; } else { $this->objects[$id]['info'] = array_merge($this->objects[$id]['info'], $options); } break; case 'out': $res = "\n$id 0 obj << "; foreach($this->objects[$id]['info'] as $referenceObjName => $referenceObjId) { $res .= "/$referenceObjName $referenceObjId 0 R "; } $res .= ">> endobj"; return $res; } return null; } protected function o_names($id, $action, $options = null) { switch ($action) { case 'new': case 'add': if ($id === 0) { $id = ++$this->numObj; $this->objects[$id] = ['t' => 'names', 'info' => [$options]]; $this->o_indirect_references($this->indirectReferenceId, 'add', ['EmbeddedFiles' => $id]); $this->embeddedFilesId = $id; } else { $this->objects[$id]['info'][] = $options; } break; case 'out': $info = &$this->objects[$id]['info']; $res = ''; if (count($info) > 0) { $res = "\n$id 0 obj << /Names [ "; if ($this->encrypted) { $this->encryptInit($id); } foreach ($info as $entry) { if ($this->encrypted) { $filename = $this->ARC4($entry['filename']); } else { $filename = $entry['filename']; } $res .= "($filename) " . $entry['dict_reference'] . " 0 R "; } $res .= "] >> endobj"; } return $res; } return null; } protected function o_embedded_file_dictionary($id, $action, $options = null) { switch ($action) { case 'new': $embeddedFileId = ++$this->numObj; $options['embedded_reference'] = $embeddedFileId; $this->objects[$id] = ['t' => 'embedded_file_dictionary', 'info' => $options]; $this->o_embedded_file($embeddedFileId, 'new', $options); $options['dict_reference'] = $id; $this->o_names($this->embeddedFilesId, 'add', $options); break; case 'out': $info = &$this->objects[$id]['info']; $filename = $this->utf8toUtf16BE($info['filename']); $description = $this->utf8toUtf16BE($info['description']); if ($this->encrypted) { $this->encryptInit($id); $filename = $this->ARC4($filename); $description = $this->ARC4($description); } $filename = $this->filterText($filename, false, false); $description = $this->filterText($description, false, false); $res = "\n$id 0 obj <>"; $res .= " /F ($filename) /UF ($filename) /Desc ($description)"; $res .= " >> endobj"; return $res; } return null; } protected function o_embedded_file($id, $action, $options = null): ?string { switch ($action) { case 'new': $this->objects[$id] = ['t' => 'embedded_file', 'info' => $options]; break; case 'out': $info = &$this->objects[$id]['info']; if ($this->compressionReady) { $filepath = $info['filepath']; $checksum = md5_file($filepath); $f = fopen($filepath, "rb"); $file_content_compressed = ''; $deflateContext = deflate_init(ZLIB_ENCODING_DEFLATE, ['level' => 6]); while (($block = fread($f, 8192))) { $file_content_compressed .= deflate_add($deflateContext, $block, ZLIB_NO_FLUSH); } $file_content_compressed .= deflate_add($deflateContext, '', ZLIB_FINISH); $file_size_uncompressed = ftell($f); fclose($f); } else { $file_content = file_get_contents($info['filepath']); $file_size_uncompressed = mb_strlen($file_content, '8bit'); $checksum = md5($file_content); } if ($this->encrypted) { $this->encryptInit($id); $checksum = $this->ARC4($checksum); $file_content_compressed = $this->ARC4($file_content_compressed); } $file_size_compressed = mb_strlen($file_content_compressed, '8bit'); $res = "\n$id 0 obj <>" . " /Type/EmbeddedFile /Filter/FlateDecode" . " /Length $file_size_compressed >> stream\n$file_content_compressed\nendstream\nendobj"; return $res; } return null; } /** * ARC4 functions * A series of function to implement ARC4 encoding in PHP */ /** * calculate the 16 byte version of the 128 bit md5 digest of the string * * @param $string * @return string */ function md5_16($string) { $tmp = md5($string); $out = ''; for ($i = 0; $i <= 30; $i = $i + 2) { $out .= chr(hexdec(substr($tmp, $i, 2))); } return $out; } /** * initialize the encryption for processing a particular object * * @param $id */ function encryptInit($id) { $tmp = $this->encryptionKey; $hex = dechex($id); if (mb_strlen($hex, '8bit') < 6) { $hex = substr('000000', 0, 6 - mb_strlen($hex, '8bit')) . $hex; } $tmp .= chr(hexdec(substr($hex, 4, 2))) . chr(hexdec(substr($hex, 2, 2))) . chr(hexdec(substr($hex, 0, 2))) . chr(0) . chr(0) ; $key = $this->md5_16($tmp); $this->ARC4_init(substr($key, 0, 10)); } /** * initialize the ARC4 encryption * * @param string $key */ function ARC4_init($key = '') { $this->arc4 = ''; // setup the control array if (mb_strlen($key, '8bit') == 0) { return; } $k = ''; while (mb_strlen($k, '8bit') < 256) { $k .= $key; } $k = substr($k, 0, 256); for ($i = 0; $i < 256; $i++) { $this->arc4 .= chr($i); } $j = 0; for ($i = 0; $i < 256; $i++) { $t = $this->arc4[$i]; $j = ($j + ord($t) + ord($k[$i])) % 256; $this->arc4[$i] = $this->arc4[$j]; $this->arc4[$j] = $t; } } /** * ARC4 encrypt a text string * * @param $text * @return string */ function ARC4($text) { $len = mb_strlen($text, '8bit'); $a = 0; $b = 0; $c = $this->arc4; $out = ''; for ($i = 0; $i < $len; $i++) { $a = ($a + 1) % 256; $t = $c[$a]; $b = ($b + ord($t)) % 256; $c[$a] = $c[$b]; $c[$b] = $t; $k = ord($c[(ord($c[$a]) + ord($c[$b])) % 256]); $out .= chr(ord($text[$i]) ^ $k); } return $out; } /** * functions which can be called to adjust or add to the document */ /** * add a link in the document to an external URL * * @param $url * @param $x0 * @param $y0 * @param $x1 * @param $y1 */ function addLink($url, $x0, $y0, $x1, $y1) { $this->numObj++; $info = ['type' => 'link', 'url' => $url, 'rect' => [$x0, $y0, $x1, $y1]]; $this->o_annotation($this->numObj, 'new', $info); } /** * add a link in the document to an internal destination (ie. within the document) * * @param $label * @param $x0 * @param $y0 * @param $x1 * @param $y1 */ function addInternalLink($label, $x0, $y0, $x1, $y1) { $this->numObj++; $info = ['type' => 'ilink', 'label' => $label, 'rect' => [$x0, $y0, $x1, $y1]]; $this->o_annotation($this->numObj, 'new', $info); } /** * set the encryption of the document * can be used to turn it on and/or set the passwords which it will have. * also the functions that the user will have are set here, such as print, modify, add * * @param string $userPass * @param string $ownerPass * @param array $pc */ function setEncryption($userPass = '', $ownerPass = '', $pc = []) { $p = bindec("11000000"); $options = ['print' => 4, 'modify' => 8, 'copy' => 16, 'add' => 32]; foreach ($pc as $k => $v) { if ($v && isset($options[$k])) { $p += $options[$k]; } else { if (isset($options[$v])) { $p += $options[$v]; } } } // implement encryption on the document if ($this->arc4_objnum == 0) { // then the block does not exist already, add it. $this->numObj++; if (mb_strlen($ownerPass) == 0) { $ownerPass = $userPass; } $this->o_encryption($this->numObj, 'new', ['user' => $userPass, 'owner' => $ownerPass, 'p' => $p]); } } /** * should be used for internal checks, not implemented as yet */ function checkAllHere() { } /** * return the pdf stream as a string returned from the function * * @param bool $debug * @return string */ function output($debug = false) { if ($debug) { // turn compression off $this->options['compression'] = false; } if ($this->javascript) { $this->numObj++; $js_id = $this->numObj; $this->o_embedjs($js_id, 'new'); $this->o_javascript(++$this->numObj, 'new', $this->javascript); $id = $this->catalogId; $this->o_indirect_references($this->indirectReferenceId, 'add', ['JavaScript' => $js_id]); } if ($this->fileIdentifier === '') { $tmp = implode('', $this->objects[$this->infoObject]['info']); $this->fileIdentifier = md5('DOMPDF' . __FILE__ . $tmp . microtime() . mt_rand()); } if ($this->arc4_objnum) { $this->o_encryption($this->arc4_objnum, 'keys'); $this->ARC4_init($this->encryptionKey); } $this->checkAllHere(); $xref = []; $content = '%PDF-' . self::PDF_VERSION; $pos = mb_strlen($content, '8bit'); // pre-process o_font objects before output of all objects foreach ($this->objects as $k => $v) { if ($v['t'] === 'font') { $this->o_font($k, 'add'); } } foreach ($this->objects as $k => $v) { $tmp = 'o_' . $v['t']; $cont = $this->$tmp($k, 'out'); $content .= $cont; $xref[] = $pos + 1; //+1 to account for \n at the start of each object $pos += mb_strlen($cont, '8bit'); } $content .= "\nxref\n0 " . (count($xref) + 1) . "\n0000000000 65535 f \n"; foreach ($xref as $p) { $content .= str_pad($p, 10, "0", STR_PAD_LEFT) . " 00000 n \n"; } $content .= "trailer\n<<\n" . '/Size ' . (count($xref) + 1) . "\n" . '/Root 1 0 R' . "\n" . '/Info ' . $this->infoObject . " 0 R\n" ; // if encryption has been applied to this document then add the marker for this dictionary if ($this->arc4_objnum > 0) { $content .= '/Encrypt ' . $this->arc4_objnum . " 0 R\n"; } $content .= '/ID[<' . $this->fileIdentifier . '><' . $this->fileIdentifier . ">]\n"; // account for \n added at start of xref table $pos++; $content .= ">>\nstartxref\n$pos\n%%EOF\n"; if (count($this->byteRange) > 0) { foreach ($this->byteRange as $k => $v) { $tmp = 'o_' . $v['t']; $this->$tmp($k, 'byterange', ['content' => &$content]); } } return $content; } /** * initialize a new document * if this is called on an existing document results may be unpredictable, but the existing document would be lost at minimum * this function is called automatically by the constructor function * * @param array $pageSize */ private function newDocument($pageSize = [0, 0, 612, 792]) { $this->numObj = 0; $this->objects = []; $this->numObj++; $this->o_catalog($this->numObj, 'new'); $this->numObj++; $this->o_outlines($this->numObj, 'new'); $this->numObj++; $this->o_pages($this->numObj, 'new'); $this->o_pages($this->numObj, 'mediaBox', $pageSize); $this->currentNode = 3; $this->numObj++; $this->o_procset($this->numObj, 'new'); $this->numObj++; $this->o_info($this->numObj, 'new'); $this->numObj++; $this->o_page($this->numObj, 'new'); // need to store the first page id as there is no way to get it to the user during // startup $this->firstPageId = $this->currentContents; } /** * open the font file and return a php structure containing it. * first check if this one has been done before and saved in a form more suited to php * note that if a php serialized version does not exist it will try and make one, but will * require write access to the directory to do it... it is MUCH faster to have these serialized * files. * * @param $font */ private function openFont($font) { // assume that $font contains the path and file but not the extension $name = basename($font); $dir = dirname($font) . '/'; $fontcache = $this->fontcache; if ($fontcache == '') { $fontcache = rtrim($dir, DIRECTORY_SEPARATOR."/\\"); } //$name filename without folder and extension of font metrics //$dir folder of font metrics //$fontcache folder of runtime created php serialized version of font metrics. // If this is not given, the same folder as the font metrics will be used. // Storing and reusing serialized versions improves speed much $this->addMessage("openFont: $font - $name"); if (!$this->isUnicode || in_array(mb_strtolower(basename($name)), self::$coreFonts)) { $metrics_name = "$name.afm"; } else { $metrics_name = "$name.ufm"; } $cache_name = "$metrics_name.php"; $this->addMessage("metrics: $metrics_name, cache: $cache_name"); if (file_exists($fontcache . '/' . $cache_name)) { $this->addMessage("openFont: php file exists $fontcache/$cache_name"); $this->fonts[$font] = require($fontcache . '/' . $cache_name); if (!isset($this->fonts[$font]['_version_']) || $this->fonts[$font]['_version_'] != $this->fontcacheVersion) { // if the font file is old, then clear it out and prepare for re-creation $this->addMessage('openFont: clear out, make way for new version.'); $this->fonts[$font] = null; unset($this->fonts[$font]); } } else { $old_cache_name = "php_$metrics_name"; if (file_exists($fontcache . '/' . $old_cache_name)) { $this->addMessage( "openFont: php file doesn't exist $fontcache/$cache_name, creating it from the old format" ); $old_cache = file_get_contents($fontcache . '/' . $old_cache_name); file_put_contents($fontcache . '/' . $cache_name, 'openFont($font); return; } } if (!isset($this->fonts[$font]) && file_exists($dir . $metrics_name)) { // then rebuild the php_.afm file from the .afm file $this->addMessage("openFont: build php file from $dir$metrics_name"); $data = []; // 20 => 'space' $data['codeToName'] = []; // Since we're not going to enable Unicode for the core fonts we need to use a font-based // setting for Unicode support rather than a global setting. $data['isUnicode'] = (strtolower(substr($metrics_name, -3)) !== 'afm'); $cidtogid = ''; if ($data['isUnicode']) { $cidtogid = str_pad('', 256 * 256 * 2, "\x00"); } $file = file($dir . $metrics_name); foreach ($file as $rowA) { $row = trim($rowA); $pos = strpos($row, ' '); if ($pos) { // then there must be some keyword $key = substr($row, 0, $pos); switch ($key) { case 'FontName': case 'FullName': case 'FamilyName': case 'PostScriptName': case 'Weight': case 'ItalicAngle': case 'IsFixedPitch': case 'CharacterSet': case 'UnderlinePosition': case 'UnderlineThickness': case 'Version': case 'EncodingScheme': case 'CapHeight': case 'XHeight': case 'Ascender': case 'Descender': case 'StdHW': case 'StdVW': case 'StartCharMetrics': case 'FontHeightOffset': // OAR - Added so we can offset the height calculation of a Windows font. Otherwise it's too big. $data[$key] = trim(substr($row, $pos)); break; case 'FontBBox': $data[$key] = explode(' ', trim(substr($row, $pos))); break; //C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; case 'C': // Found in AFM files $bits = explode(';', trim($row)); $dtmp = ['C' => null, 'N' => null, 'WX' => null, 'B' => []]; foreach ($bits as $bit) { $bits2 = explode(' ', trim($bit)); if (mb_strlen($bits2[0], '8bit') == 0) { continue; } if (count($bits2) > 2) { $dtmp[$bits2[0]] = []; for ($i = 1; $i < count($bits2); $i++) { $dtmp[$bits2[0]][] = $bits2[$i]; } } else { if (count($bits2) == 2) { $dtmp[$bits2[0]] = $bits2[1]; } } } $c = (int)$dtmp['C']; $n = $dtmp['N']; $width = floatval($dtmp['WX']); if ($c >= 0) { if (!ctype_xdigit($n) || $c != hexdec($n)) { $data['codeToName'][$c] = $n; } $data['C'][$c] = $width; } elseif (isset($n)) { $data['C'][$n] = $width; } if (!isset($data['MissingWidth']) && $c === -1 && $n === '.notdef') { $data['MissingWidth'] = $width; } break; // U 827 ; WX 0 ; N squaresubnosp ; G 675 ; case 'U': // Found in UFM files if (!$data['isUnicode']) { break; } $bits = explode(';', trim($row)); $dtmp = ['G' => null, 'N' => null, 'U' => null, 'WX' => null]; foreach ($bits as $bit) { $bits2 = explode(' ', trim($bit)); if (mb_strlen($bits2[0], '8bit') === 0) { continue; } if (count($bits2) > 2) { $dtmp[$bits2[0]] = []; for ($i = 1; $i < count($bits2); $i++) { $dtmp[$bits2[0]][] = $bits2[$i]; } } else { if (count($bits2) == 2) { $dtmp[$bits2[0]] = $bits2[1]; } } } $c = (int)$dtmp['U']; $n = $dtmp['N']; $glyph = $dtmp['G']; $width = floatval($dtmp['WX']); if ($c >= 0) { // Set values in CID to GID map if ($c >= 0 && $c < 0xFFFF && $glyph) { $cidtogid[$c * 2] = chr($glyph >> 8); $cidtogid[$c * 2 + 1] = chr($glyph & 0xFF); } if (!ctype_xdigit($n) || $c != hexdec($n)) { $data['codeToName'][$c] = $n; } $data['C'][$c] = $width; } elseif (isset($n)) { $data['C'][$n] = $width; } if (!isset($data['MissingWidth']) && $c === -1 && $n === '.notdef') { $data['MissingWidth'] = $width; } break; case 'KPX': break; // don't include them as they are not used yet //KPX Adieresis yacute -40 /*$bits = explode(' ', trim($row)); $data['KPX'][$bits[1]][$bits[2]] = $bits[3]; break;*/ } } } if ($this->compressionReady && $this->options['compression']) { // then implement ZLIB based compression on CIDtoGID string $data['CIDtoGID_Compressed'] = true; $cidtogid = gzcompress($cidtogid, 6); } $data['CIDtoGID'] = base64_encode($cidtogid); $data['_version_'] = $this->fontcacheVersion; $this->fonts[$font] = $data; //Because of potential trouble with php safe mode, expect that the folder already exists. //If not existing, this will hit performance because of missing cached results. if (is_dir($fontcache) && is_writable($fontcache)) { file_put_contents($fontcache . '/' . $cache_name, 'fonts[$font])) { $this->addMessage("openFont: no font file found for $font. Do you need to run load_font.php?"); } //pre_r($this->messages); } /** * if the font is not loaded then load it and make the required object * else just make it the current font * the encoding array can contain 'encoding'=> 'none','WinAnsiEncoding','MacRomanEncoding' or 'MacExpertEncoding' * note that encoding='none' will need to be used for symbolic fonts * and 'differences' => an array of mappings between numbers 0->255 and character names. * * @param $fontName * @param string $encoding * @param bool $set * @param bool $isSubsetting * @return int * @throws FontNotFoundException */ function selectFont($fontName, $encoding = '', $set = true, $isSubsetting = true) { if ($fontName === null || $fontName === '') { return $this->currentFontNum; } $ext = substr($fontName, -4); if ($ext === '.afm' || $ext === '.ufm') { $fontName = substr($fontName, 0, mb_strlen($fontName) - 4); } if (!isset($this->fonts[$fontName])) { $this->addMessage("selectFont: selecting - $fontName - $encoding, $set"); // load the file $this->openFont($fontName); if (isset($this->fonts[$fontName])) { $this->numObj++; $this->numFonts++; $font = &$this->fonts[$fontName]; $name = basename($fontName); $options = ['name' => $name, 'fontFileName' => $fontName, 'isSubsetting' => $isSubsetting]; if (is_array($encoding)) { // then encoding and differences might be set if (isset($encoding['encoding'])) { $options['encoding'] = $encoding['encoding']; } if (isset($encoding['differences'])) { $options['differences'] = $encoding['differences']; } } else { if (mb_strlen($encoding, '8bit')) { // then perhaps only the encoding has been set $options['encoding'] = $encoding; } } $this->o_font($this->numObj, 'new', $options); if (file_exists("$fontName.ttf")) { $fileSuffix = 'ttf'; } elseif (file_exists("$fontName.TTF")) { $fileSuffix = 'TTF'; } elseif (file_exists("$fontName.pfb")) { $fileSuffix = 'pfb'; } elseif (file_exists("$fontName.PFB")) { $fileSuffix = 'PFB'; } else { $fileSuffix = ''; } $font['fileSuffix'] = $fileSuffix; $font['fontNum'] = $this->numFonts; $font['isSubsetting'] = $isSubsetting && $font['isUnicode'] && strtolower($fileSuffix) === 'ttf'; // also set the differences here, note that this means that these will take effect only the //first time that a font is selected, else they are ignored if (isset($options['differences'])) { $font['differences'] = $options['differences']; } } } if ($set && isset($this->fonts[$fontName])) { // so if for some reason the font was not set in the last one then it will not be selected $this->currentBaseFont = $fontName; // the next lines mean that if a new font is selected, then the current text state will be // applied to it as well. $this->currentFont = $this->currentBaseFont; $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; } return $this->currentFontNum; } /** * sets up the current font, based on the font families, and the current text state * note that this system is quite flexible, a bold-italic font can be completely different to a * italic-bold font, and even bold-bold will have to be defined within the family to have meaning * This function is to be called whenever the currentTextState is changed, it will update * the currentFont setting to whatever the appropriate family one is. * If the user calls selectFont themselves then that will reset the currentBaseFont, and the currentFont * This function will change the currentFont to whatever it should be, but will not change the * currentBaseFont. */ private function setCurrentFont() { // if (strlen($this->currentBaseFont) == 0){ // // then assume an initial font // $this->selectFont($this->defaultFont); // } // $cf = substr($this->currentBaseFont,strrpos($this->currentBaseFont,'/')+1); // if (strlen($this->currentTextState) // && isset($this->fontFamilies[$cf]) // && isset($this->fontFamilies[$cf][$this->currentTextState])){ // // then we are in some state or another // // and this font has a family, and the current setting exists within it // // select the font, then return it // $nf = substr($this->currentBaseFont,0,strrpos($this->currentBaseFont,'/')+1).$this->fontFamilies[$cf][$this->currentTextState]; // $this->selectFont($nf,'',0); // $this->currentFont = $nf; // $this->currentFontNum = $this->fonts[$nf]['fontNum']; // } else { // // the this font must not have the right family member for the current state // // simply assume the base font $this->currentFont = $this->currentBaseFont; $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; // } } /** * function for the user to find out what the ID is of the first page that was created during * startup - useful if they wish to add something to it later. * * @return int */ function getFirstPageId() { return $this->firstPageId; } /** * add content to the currently active object * * @param $content */ private function addContent($content) { $this->objects[$this->currentContents]['c'] .= $content; } /** * sets the color for fill operations * * @param $color * @param bool $force */ function setColor($color, $force = false) { $new_color = [$color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null]; if (!$force && $this->currentColor == $new_color) { return; } if (isset($new_color[3])) { $this->currentColor = $new_color; $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F k", $this->currentColor)); } else { if (isset($new_color[2])) { $this->currentColor = $new_color; $this->addContent(vsprintf("\n%.3F %.3F %.3F rg", $this->currentColor)); } } } /** * sets the color for fill operations * * @param $fillRule */ function setFillRule($fillRule) { if (!in_array($fillRule, ["nonzero", "evenodd"])) { return; } $this->fillRule = $fillRule; } /** * sets the color for stroke operations * * @param $color * @param bool $force */ function setStrokeColor($color, $force = false) { $new_color = [$color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null]; if (!$force && $this->currentStrokeColor == $new_color) { return; } if (isset($new_color[3])) { $this->currentStrokeColor = $new_color; $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F K", $this->currentStrokeColor)); } else { if (isset($new_color[2])) { $this->currentStrokeColor = $new_color; $this->addContent(vsprintf("\n%.3F %.3F %.3F RG", $this->currentStrokeColor)); } } } /** * Set the graphics state for compositions * * @param $parameters */ function setGraphicsState($parameters) { // Create a new graphics state object if necessary if (($gstate = array_search($parameters, $this->gstates)) === false) { $this->numObj++; $this->o_extGState($this->numObj, 'new', $parameters); $gstate = $this->numStates; $this->gstates[$gstate] = $parameters; } $this->addContent("\n/GS$gstate gs"); } /** * Set current blend mode & opacity for lines. * * Valid blend modes are: * * Normal, Multiply, Screen, Overlay, Darken, Lighten, * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, * Exclusion * * @param string $mode the blend mode to use * @param float $opacity 0.0 fully transparent, 1.0 fully opaque */ function setLineTransparency($mode, $opacity) { static $blend_modes = [ "Normal", "Multiply", "Screen", "Overlay", "Darken", "Lighten", "ColorDogde", "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion" ]; if (!in_array($mode, $blend_modes)) { $mode = "Normal"; } if (is_null($this->currentLineTransparency)) { $this->currentLineTransparency = []; } if ($mode === (key_exists('mode', $this->currentLineTransparency) ? $this->currentLineTransparency['mode'] : '') && $opacity === (key_exists('opacity', $this->currentLineTransparency) ? $this->currentLineTransparency["opacity"] : '')) { return; } $this->currentLineTransparency["mode"] = $mode; $this->currentLineTransparency["opacity"] = $opacity; $options = [ "BM" => "/$mode", "CA" => (float)$opacity ]; $this->setGraphicsState($options); } /** * Set current blend mode & opacity for filled objects. * * Valid blend modes are: * * Normal, Multiply, Screen, Overlay, Darken, Lighten, * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, * Exclusion * * @param string $mode the blend mode to use * @param float $opacity 0.0 fully transparent, 1.0 fully opaque */ function setFillTransparency($mode, $opacity) { static $blend_modes = [ "Normal", "Multiply", "Screen", "Overlay", "Darken", "Lighten", "ColorDogde", "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion" ]; if (!in_array($mode, $blend_modes)) { $mode = "Normal"; } if (is_null($this->currentFillTransparency)) { $this->currentFillTransparency = []; } if ($mode === (key_exists('mode', $this->currentFillTransparency) ? $this->currentFillTransparency['mode'] : '') && $opacity === (key_exists('opacity', $this->currentFillTransparency) ? $this->currentFillTransparency["opacity"] : '')) { return; } $this->currentFillTransparency["mode"] = $mode; $this->currentFillTransparency["opacity"] = $opacity; $options = [ "BM" => "/$mode", "ca" => (float)$opacity, ]; $this->setGraphicsState($options); } /** * draw a line from one set of coordinates to another * * @param $x1 * @param $y1 * @param $x2 * @param $y2 * @param bool $stroke */ function line($x1, $y1, $x2, $y2, $stroke = true) { $this->addContent(sprintf("\n%.3F %.3F m %.3F %.3F l", $x1, $y1, $x2, $y2)); if ($stroke) { $this->addContent(' S'); } } /** * draw a bezier curve based on 4 control points * * @param $x0 * @param $y0 * @param $x1 * @param $y1 * @param $x2 * @param $y2 * @param $x3 * @param $y3 */ function curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) { // in the current line style, draw a bezier curve from (x0,y0) to (x3,y3) using the other two points // as the control points for the curve. $this->addContent( sprintf("\n%.3F %.3F m %.3F %.3F %.3F %.3F %.3F %.3F c S", $x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) ); } /** * draw a part of an ellipse * * @param $x0 * @param $y0 * @param $astart * @param $afinish * @param $r1 * @param int $r2 * @param int $angle * @param int $nSeg */ function partEllipse($x0, $y0, $astart, $afinish, $r1, $r2 = 0, $angle = 0, $nSeg = 8) { $this->ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, false); } /** * draw a filled ellipse * * @param $x0 * @param $y0 * @param $r1 * @param int $r2 * @param int $angle * @param int $nSeg * @param int $astart * @param int $afinish */ function filledEllipse($x0, $y0, $r1, $r2 = 0, $angle = 0, $nSeg = 8, $astart = 0, $afinish = 360) { $this->ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, true, true); } /** * @param $x * @param $y */ function lineTo($x, $y) { $this->addContent(sprintf("\n%.3F %.3F l", $x, $y)); } /** * @param $x * @param $y */ function moveTo($x, $y) { $this->addContent(sprintf("\n%.3F %.3F m", $x, $y)); } /** * draw a bezier curve based on 4 control points * * @param $x1 * @param $y1 * @param $x2 * @param $y2 * @param $x3 * @param $y3 */ function curveTo($x1, $y1, $x2, $y2, $x3, $y3) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F %.3F %.3F c", $x1, $y1, $x2, $y2, $x3, $y3)); } /** * draw a bezier curve based on 4 control points */ function quadTo($cpx, $cpy, $x, $y) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F v", $cpx, $cpy, $x, $y)); } function closePath() { $this->addContent(' h'); } function endPath() { $this->addContent(' n'); } /** * draw an ellipse * note that the part and filled ellipse are just special cases of this function * * draws an ellipse in the current line style * centered at $x0,$y0, radii $r1,$r2 * if $r2 is not set, then a circle is drawn * from $astart to $afinish, measured in degrees, running anti-clockwise from the right hand side of the ellipse. * nSeg is not allowed to be less than 2, as this will simply draw a line (and will even draw a * pretty crappy shape at 2, as we are approximating with bezier curves. * * @param $x0 * @param $y0 * @param $r1 * @param int $r2 * @param int $angle * @param int $nSeg * @param int $astart * @param int $afinish * @param bool $close * @param bool $fill * @param bool $stroke * @param bool $incomplete */ function ellipse( $x0, $y0, $r1, $r2 = 0, $angle = 0, $nSeg = 8, $astart = 0, $afinish = 360, $close = true, $fill = false, $stroke = true, $incomplete = false ) { if ($r1 == 0) { return; } if ($r2 == 0) { $r2 = $r1; } if ($nSeg < 2) { $nSeg = 2; } $astart = deg2rad((float)$astart); $afinish = deg2rad((float)$afinish); $totalAngle = $afinish - $astart; $dt = $totalAngle / $nSeg; $dtm = $dt / 3; if ($angle != 0) { $a = -1 * deg2rad((float)$angle); $this->addContent( sprintf("\n q %.3F %.3F %.3F %.3F %.3F %.3F cm", cos($a), -sin($a), sin($a), cos($a), $x0, $y0) ); $x0 = 0; $y0 = 0; } $t1 = $astart; $a0 = $x0 + $r1 * cos($t1); $b0 = $y0 + $r2 * sin($t1); $c0 = -$r1 * sin($t1); $d0 = $r2 * cos($t1); if (!$incomplete) { $this->addContent(sprintf("\n%.3F %.3F m ", $a0, $b0)); } for ($i = 1; $i <= $nSeg; $i++) { // draw this bit of the total curve $t1 = $i * $dt + $astart; $a1 = $x0 + $r1 * cos($t1); $b1 = $y0 + $r2 * sin($t1); $c1 = -$r1 * sin($t1); $d1 = $r2 * cos($t1); $this->addContent( sprintf( "\n%.3F %.3F %.3F %.3F %.3F %.3F c", ($a0 + $c0 * $dtm), ($b0 + $d0 * $dtm), ($a1 - $c1 * $dtm), ($b1 - $d1 * $dtm), $a1, $b1 ) ); $a0 = $a1; $b0 = $b1; $c0 = $c1; $d0 = $d1; } if (!$incomplete) { if ($fill) { $this->addContent(' f'); } if ($stroke) { if ($close) { $this->addContent(' s'); // small 's' signifies closing the path as well } else { $this->addContent(' S'); } } } if ($angle != 0) { $this->addContent(' Q'); } } /** * this sets the line drawing style. * width, is the thickness of the line in user units * cap is the type of cap to put on the line, values can be 'butt','round','square' * where the diffference between 'square' and 'butt' is that 'square' projects a flat end past the * end of the line. * join can be 'miter', 'round', 'bevel' * dash is an array which sets the dash pattern, is a series of length values, which are the lengths of the * on and off dashes. * (2) represents 2 on, 2 off, 2 on , 2 off ... * (2,1) is 2 on, 1 off, 2 on, 1 off.. etc * phase is a modifier on the dash pattern which is used to shift the point at which the pattern starts. * * @param int $width * @param string $cap * @param string $join * @param string $dash * @param int $phase */ function setLineStyle($width = 1, $cap = '', $join = '', $dash = '', $phase = 0) { // this is quite inefficient in that it sets all the parameters whenever 1 is changed, but will fix another day $string = ''; if ($width > 0) { $string .= "$width w"; } $ca = ['butt' => 0, 'round' => 1, 'square' => 2]; if (isset($ca[$cap])) { $string .= " $ca[$cap] J"; } $ja = ['miter' => 0, 'round' => 1, 'bevel' => 2]; if (isset($ja[$join])) { $string .= " $ja[$join] j"; } if (is_array($dash)) { $string .= ' [ ' . implode(' ', $dash) . " ] $phase d"; } $this->currentLineStyle = $string; $this->addContent("\n$string"); } /** * draw a polygon, the syntax for this is similar to the GD polygon command * * @param $p * @param $np * @param bool $f */ function polygon($p, $np, $f = false) { $this->addContent(sprintf("\n%.3F %.3F m ", $p[0], $p[1])); for ($i = 2; $i < $np * 2; $i = $i + 2) { $this->addContent(sprintf("%.3F %.3F l ", $p[$i], $p[$i + 1])); } if ($f) { $this->addContent(' f'); } else { $this->addContent(' S'); } } /** * a filled rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not * the coordinates of the upper-right corner * * @param $x1 * @param $y1 * @param $width * @param $height */ function filledRectangle($x1, $y1, $width, $height) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re f", $x1, $y1, $width, $height)); } /** * draw a rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not * the coordinates of the upper-right corner * * @param $x1 * @param $y1 * @param $width * @param $height */ function rectangle($x1, $y1, $width, $height) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re S", $x1, $y1, $width, $height)); } /** * draw a rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not * the coordinates of the upper-right corner * * @param $x1 * @param $y1 * @param $width * @param $height */ function rect($x1, $y1, $width, $height) { $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re", $x1, $y1, $width, $height)); } function stroke() { $this->addContent("\nS"); } function fill() { $this->addContent("\nf" . ($this->fillRule === "evenodd" ? "*" : "")); } function fillStroke() { $this->addContent("\nb" . ($this->fillRule === "evenodd" ? "*" : "")); } /** * @param string $subtype * @param integer $x * @param integer $y * @param integer $w * @param integer $h * @return int */ function addXObject($subtype, $x, $y, $w, $h) { $id = ++$this->numObj; $this->o_xobject($id, 'new', ['Subtype' => $subtype, 'bbox' => [$x, $y, $w, $h]]); return $id; } /** * @param integer $numXObject * @param string $type * @param array $options */ function setXObjectResource($numXObject, $type, $options) { if (in_array($type, ['procset', 'font', 'xObject'])) { $this->o_xobject($numXObject, $type, $options); } } /** * add signature * * $fieldSigId = $cpdf->addFormField(Cpdf::ACROFORM_FIELD_SIG, 'Signature1', 0, 0, 0, 0, 0); * * $signatureId = $cpdf->addSignature([ * 'signcert' => file_get_contents('dompdf.crt'), * 'privkey' => file_get_contents('dompdf.key'), * 'password' => 'password', * 'name' => 'DomPDF DEMO', * 'location' => 'Home', * 'reason' => 'First Form', * 'contactinfo' => 'info' * ]); * $cpdf->setFormFieldValue($fieldSigId, "$signatureId 0 R"); * * @param string $signcert * @param string $privkey * @param string $password * @param string|null $name * @param string|null $location * @param string|null $reason * @param string|null $contactinfo * @return int */ function addSignature($signcert, $privkey, $password = '', $name = null, $location = null, $reason = null, $contactinfo = null) { $sigId = ++$this->numObj; $this->o_sig($sigId, 'new', [ 'SignCert' => $signcert, 'PrivKey' => $privkey, 'Password' => $password, 'Name' => $name, 'Location' => $location, 'Reason' => $reason, 'ContactInfo' => $contactinfo ]); return $sigId; } /** * add field to form * * @param string $type ACROFORM_FIELD_* * @param string $name * @param $x0 * @param $y0 * @param $x1 * @param $y1 * @param integer $ff Field Flag ACROFORM_FIELD_*_* * @param float $size * @param array $color * @return int */ public function addFormField($type, $name, $x0, $y0, $x1, $y1, $ff = 0, $size = 10.0, $color = [0, 0, 0]) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $color = implode(' ', $color) . ' rg'; $currentFontNum = $this->currentFontNum; $font = array_filter($this->objects[$this->currentNode]['info']['fonts'], function($item) use ($currentFontNum) { return $item['fontNum'] == $currentFontNum; }); $this->o_acroform($this->acroFormId, 'font', ['objNum' => $font[0]['objNum'], 'fontNum' => $font[0]['fontNum']]); $fieldId = ++$this->numObj; $this->o_field($fieldId, 'new', [ 'rect' => [$x0, $y0, $x1, $y1], 'F' => 4, 'FT' => "/$type", 'T' => $name, 'Ff' => $ff, 'pageid' => $this->currentPage, 'da' => "$color /F$this->currentFontNum " . sprintf('%.1F Tf ', $size) ]); return $fieldId; } /** * set Field value * * @param integer $numFieldObj * @param string $value */ public function setFormFieldValue($numFieldObj, $value) { $this->o_field($numFieldObj, 'set', ['value' => $value]); } /** * set Field value (reference) * * @param integer $numFieldObj * @param integer $numObj Object number */ public function setFormFieldRefValue($numFieldObj, $numObj) { $this->o_field($numFieldObj, 'set', ['refvalue' => $numObj]); } /** * set Field Appearanc (reference) * * @param integer $numFieldObj * @param integer $normalNumObj * @param integer|null $rolloverNumObj * @param integer|null $downNumObj */ public function setFormFieldAppearance($numFieldObj, $normalNumObj, $rolloverNumObj = null, $downNumObj = null) { $appearance['N'] = $normalNumObj; if ($rolloverNumObj !== null) { $appearance['R'] = $rolloverNumObj; } if ($downNumObj !== null) { $appearance['D'] = $downNumObj; } $this->o_field($numFieldObj, 'set', ['appearance' => $appearance]); } /** * set Choice Field option values * * @param integer $numFieldObj * @param array $value */ public function setFormFieldOpt($numFieldObj, $value) { $this->o_field($numFieldObj, 'set', ['options' => $value]); } /** * add form to document * * @param integer $sigFlags * @param boolean $needAppearances */ public function addForm($sigFlags = 0, $needAppearances = false) { $this->acroFormId = ++$this->numObj; $this->o_acroform($this->acroFormId, 'new', [ 'NeedAppearances' => $needAppearances ? 'true' : 'false', 'SigFlags' => $sigFlags ]); } /** * save the current graphic state */ function save() { // we must reset the color cache or it will keep bad colors after clipping $this->currentColor = null; $this->currentStrokeColor = null; $this->addContent("\nq"); } /** * restore the last graphic state */ function restore() { // we must reset the color cache or it will keep bad colors after clipping $this->currentColor = null; $this->currentStrokeColor = null; $this->addContent("\nQ"); } /** * draw a clipping rectangle, all the elements added after this will be clipped * * @param $x1 * @param $y1 * @param $width * @param $height */ function clippingRectangle($x1, $y1, $width, $height) { $this->save(); $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re W n", $x1, $y1, $width, $height)); } /** * draw a clipping rounded rectangle, all the elements added after this will be clipped * * @param $x1 * @param $y1 * @param $w * @param $h * @param $rTL * @param $rTR * @param $rBR * @param $rBL */ function clippingRectangleRounded($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) { $this->save(); // start: top edge, left end $this->addContent(sprintf("\n%.3F %.3F m ", $x1, $y1 - $rTL + $h)); // line: bottom edge, left end $this->addContent(sprintf("\n%.3F %.3F l ", $x1, $y1 + $rBL)); // curve: bottom-left corner $this->ellipse($x1 + $rBL, $y1 + $rBL, $rBL, 0, 0, 8, 180, 270, false, false, false, true); // line: right edge, bottom end $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $w - $rBR, $y1)); // curve: bottom-right corner $this->ellipse($x1 + $w - $rBR, $y1 + $rBR, $rBR, 0, 0, 8, 270, 360, false, false, false, true); // line: right edge, top end $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $w, $y1 + $h - $rTR)); // curve: bottom-right corner $this->ellipse($x1 + $w - $rTR, $y1 + $h - $rTR, $rTR, 0, 0, 8, 0, 90, false, false, false, true); // line: bottom edge, right end $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $rTL, $y1 + $h)); // curve: top-right corner $this->ellipse($x1 + $rTL, $y1 + $h - $rTL, $rTL, 0, 0, 8, 90, 180, false, false, false, true); // line: top edge, left end $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $rBL, $y1)); // Close & clip $this->addContent(" W n"); } /** * ends the last clipping shape */ function clippingEnd() { $this->restore(); } /** * scale * * @param float $s_x scaling factor for width as percent * @param float $s_y scaling factor for height as percent * @param float $x Origin abscissa * @param float $y Origin ordinate */ function scale($s_x, $s_y, $x, $y) { $y = $this->currentPageSize["height"] - $y; $tm = [ $s_x, 0, 0, $s_y, $x * (1 - $s_x), $y * (1 - $s_y) ]; $this->transform($tm); } /** * translate * * @param float $t_x movement to the right * @param float $t_y movement to the bottom */ function translate($t_x, $t_y) { $tm = [ 1, 0, 0, 1, $t_x, -$t_y ]; $this->transform($tm); } /** * rotate * * @param float $angle angle in degrees for counter-clockwise rotation * @param float $x Origin abscissa * @param float $y Origin ordinate */ function rotate($angle, $x, $y) { $y = $this->currentPageSize["height"] - $y; $a = deg2rad($angle); $cos_a = cos($a); $sin_a = sin($a); $tm = [ $cos_a, -$sin_a, $sin_a, $cos_a, $x - $sin_a * $y - $cos_a * $x, $y - $cos_a * $y + $sin_a * $x, ]; $this->transform($tm); } /** * skew * * @param float $angle_x * @param float $angle_y * @param float $x Origin abscissa * @param float $y Origin ordinate */ function skew($angle_x, $angle_y, $x, $y) { $y = $this->currentPageSize["height"] - $y; $tan_x = tan(deg2rad($angle_x)); $tan_y = tan(deg2rad($angle_y)); $tm = [ 1, -$tan_y, -$tan_x, 1, $tan_x * $y, $tan_y * $x, ]; $this->transform($tm); } /** * apply graphic transformations * * @param array $tm transformation matrix */ function transform($tm) { $this->addContent(vsprintf("\n %.3F %.3F %.3F %.3F %.3F %.3F cm", $tm)); } /** * add a new page to the document * this also makes the new page the current active object * * @param int $insert * @param int $id * @param string $pos * @return int */ function newPage($insert = 0, $id = 0, $pos = 'after') { // if there is a state saved, then go up the stack closing them // then on the new page, re-open them with the right setings if ($this->nStateStack) { for ($i = $this->nStateStack; $i >= 1; $i--) { $this->restoreState($i); } } $this->numObj++; if ($insert) { // the id from the ezPdf class is the id of the contents of the page, not the page object itself // query that object to find the parent $rid = $this->objects[$id]['onPage']; $opt = ['rid' => $rid, 'pos' => $pos]; $this->o_page($this->numObj, 'new', $opt); } else { $this->o_page($this->numObj, 'new'); } // if there is a stack saved, then put that onto the page if ($this->nStateStack) { for ($i = 1; $i <= $this->nStateStack; $i++) { $this->saveState($i); } } // and if there has been a stroke or fill color set, then transfer them if (isset($this->currentColor)) { $this->setColor($this->currentColor, true); } if (isset($this->currentStrokeColor)) { $this->setStrokeColor($this->currentStrokeColor, true); } // if there is a line style set, then put this in too if (mb_strlen($this->currentLineStyle, '8bit')) { $this->addContent("\n$this->currentLineStyle"); } // the call to the o_page object set currentContents to the present page, so this can be returned as the page id return $this->currentContents; } /** * Streams the PDF to the client. * * @param string $filename The filename to present to the client. * @param array $options Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1). */ function stream($filename = "document.pdf", $options = []) { if (headers_sent()) { die("Unable to stream pdf: headers already sent"); } if (!isset($options["compress"])) $options["compress"] = true; if (!isset($options["Attachment"])) $options["Attachment"] = true; $debug = !$options['compress']; $tmp = ltrim($this->output($debug)); header("Cache-Control: private"); header("Content-Type: application/pdf"); header("Content-Length: " . mb_strlen($tmp, "8bit")); $filename = str_replace(["\n", "'"], "", basename($filename, ".pdf")) . ".pdf"; $attachment = $options["Attachment"] ? "attachment" : "inline"; $encoding = mb_detect_encoding($filename); $fallbackfilename = mb_convert_encoding($filename, "ISO-8859-1", $encoding); $fallbackfilename = str_replace("\"", "", $fallbackfilename); $encodedfilename = rawurlencode($filename); $contentDisposition = "Content-Disposition: $attachment; filename=\"$fallbackfilename\""; if ($fallbackfilename !== $filename) { $contentDisposition .= "; filename*=UTF-8''$encodedfilename"; } header($contentDisposition); echo $tmp; flush(); } /** * return the height in units of the current font in the given size * * @param $size * @return float|int */ function getFontHeight($size) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $font = $this->fonts[$this->currentFont]; // for the current font, and the given size, what is the height of the font in user units if (isset($font['Ascender']) && isset($font['Descender'])) { $h = $font['Ascender'] - $font['Descender']; } else { $h = $font['FontBBox'][3] - $font['FontBBox'][1]; } // have to adjust by a font offset for Windows fonts. unfortunately it looks like // the bounding box calculations are wrong and I don't know why. if (isset($font['FontHeightOffset'])) { // For CourierNew from Windows this needs to be -646 to match the // Adobe native Courier font. // // For FreeMono from GNU this needs to be -337 to match the // Courier font. // // Both have been added manually to the .afm and .ufm files. $h += (int)$font['FontHeightOffset']; } return $size * $h / 1000; } /** * @param $size * @return float|int */ function getFontXHeight($size) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $font = $this->fonts[$this->currentFont]; // for the current font, and the given size, what is the height of the font in user units if (isset($font['XHeight'])) { $xh = $font['Ascender'] - $font['Descender']; } else { $xh = $this->getFontHeight($size) / 2; } return $size * $xh / 1000; } /** * return the font descender, this will normally return a negative number * if you add this number to the baseline, you get the level of the bottom of the font * it is in the pdf user units * * @param $size * @return float|int */ function getFontDescender($size) { // note that this will most likely return a negative value if (!$this->numFonts) { $this->selectFont($this->defaultFont); } //$h = $this->fonts[$this->currentFont]['FontBBox'][1]; $h = $this->fonts[$this->currentFont]['Descender']; return $size * $h / 1000; } /** * filter the text, this is applied to all text just before being inserted into the pdf document * it escapes the various things that need to be escaped, and so on * * @access private * * @param $text * @param bool $bom * @param bool $convert_encoding * @return string */ function filterText($text, $bom = true, $convert_encoding = true) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } if ($convert_encoding) { $cf = $this->currentFont; if (isset($this->fonts[$cf]) && $this->fonts[$cf]['isUnicode']) { $text = $this->utf8toUtf16BE($text, $bom); } else { //$text = html_entity_decode($text, ENT_QUOTES); $text = mb_convert_encoding($text, self::$targetEncoding, 'UTF-8'); } } else if ($bom) { $text = $this->utf8toUtf16BE($text, $bom); } // the chr(13) substitution fixes a bug seen in TCPDF (bug #1421290) return strtr($text, [')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r']); } /** * return array containing codepoints (UTF-8 character values) for the * string passed in. * * based on the excellent TCPDF code by Nicola Asuni and the * RFC for UTF-8 at http://www.faqs.org/rfcs/rfc3629.html * * @access private * @author Orion Richardson * @since January 5, 2008 * * @param string $text UTF-8 string to process * * @return array UTF-8 codepoints array for the string */ function utf8toCodePointsArray(&$text) { $length = mb_strlen($text, '8bit'); // http://www.php.net/manual/en/function.mb-strlen.php#77040 $unicode = []; // array containing unicode values $bytes = []; // array containing single character byte sequences $numbytes = 1; // number of octets needed to represent the UTF-8 character for ($i = 0; $i < $length; $i++) { $c = ord($text[$i]); // get one string character at time if (count($bytes) === 0) { // get starting octect if ($c <= 0x7F) { $unicode[] = $c; // use the character "as is" because is ASCII $numbytes = 1; } elseif (($c >> 0x05) === 0x06) { // 2 bytes character (0x06 = 110 BIN) $bytes[] = ($c - 0xC0) << 0x06; $numbytes = 2; } elseif (($c >> 0x04) === 0x0E) { // 3 bytes character (0x0E = 1110 BIN) $bytes[] = ($c - 0xE0) << 0x0C; $numbytes = 3; } elseif (($c >> 0x03) === 0x1E) { // 4 bytes character (0x1E = 11110 BIN) $bytes[] = ($c - 0xF0) << 0x12; $numbytes = 4; } else { // use replacement character for other invalid sequences $unicode[] = 0xFFFD; $bytes = []; $numbytes = 1; } } elseif (($c >> 0x06) === 0x02) { // bytes 2, 3 and 4 must start with 0x02 = 10 BIN $bytes[] = $c - 0x80; if (count($bytes) === $numbytes) { // compose UTF-8 bytes to a single unicode value $c = $bytes[0]; for ($j = 1; $j < $numbytes; $j++) { $c += ($bytes[$j] << (($numbytes - $j - 1) * 0x06)); } if ((($c >= 0xD800) and ($c <= 0xDFFF)) or ($c >= 0x10FFFF)) { // The definition of UTF-8 prohibits encoding character numbers between // U+D800 and U+DFFF, which are reserved for use with the UTF-16 // encoding form (as surrogate pairs) and do not directly represent // characters. $unicode[] = 0xFFFD; // use replacement character } else { $unicode[] = $c; // add char to array } // reset data for next char $bytes = []; $numbytes = 1; } } else { // use replacement character for other invalid sequences $unicode[] = 0xFFFD; $bytes = []; $numbytes = 1; } } return $unicode; } /** * convert UTF-8 to UTF-16 with an additional byte order marker * at the front if required. * * based on the excellent TCPDF code by Nicola Asuni and the * RFC for UTF-8 at http://www.faqs.org/rfcs/rfc3629.html * * @access private * @author Orion Richardson * @since January 5, 2008 * * @param string $text UTF-8 string to process * @param boolean $bom whether to add the byte order marker * * @return string UTF-16 result string */ function utf8toUtf16BE(&$text, $bom = true) { $out = $bom ? "\xFE\xFF" : ''; $unicode = $this->utf8toCodePointsArray($text); foreach ($unicode as $c) { if ($c === 0xFFFD) { $out .= "\xFF\xFD"; // replacement character } elseif ($c < 0x10000) { $out .= chr($c >> 0x08) . chr($c & 0xFF); } else { $c -= 0x10000; $w1 = 0xD800 | ($c >> 0x10); $w2 = 0xDC00 | ($c & 0x3FF); $out .= chr($w1 >> 0x08) . chr($w1 & 0xFF) . chr($w2 >> 0x08) . chr($w2 & 0xFF); } } return $out; } /** * given a start position and information about how text is to be laid out, calculate where * on the page the text will end * * @param $x * @param $y * @param $angle * @param $size * @param $wa * @param $text * @return array */ private function getTextPosition($x, $y, $angle, $size, $wa, $text) { // given this information return an array containing x and y for the end position as elements 0 and 1 $w = $this->getTextWidth($size, $text); // need to adjust for the number of spaces in this text $words = explode(' ', $text); $nspaces = count($words) - 1; $w += $wa * $nspaces; $a = deg2rad((float)$angle); return [cos($a) * $w + $x, -sin($a) * $w + $y]; } /** * Callback method used by smallCaps * * @param array $matches * * @return string */ function toUpper($matches) { return mb_strtoupper($matches[0]); } function concatMatches($matches) { $str = ""; foreach ($matches as $match) { $str .= $match[0]; } return $str; } /** * register text for font subsetting * * @param $font * @param $text */ function registerText($font, $text) { if (!$this->isUnicode || in_array(mb_strtolower(basename($font)), self::$coreFonts)) { return; } if (!isset($this->stringSubsets[$font])) { $this->stringSubsets[$font] = []; } $this->stringSubsets[$font] = array_unique( array_merge($this->stringSubsets[$font], $this->utf8toCodePointsArray($text)) ); } /** * add text to the document, at a specified location, size and angle on the page * * @param $x * @param $y * @param $size * @param $text * @param int $angle * @param int $wordSpaceAdjust * @param int $charSpaceAdjust * @param bool $smallCaps */ function addText($x, $y, $size, $text, $angle = 0, $wordSpaceAdjust = 0, $charSpaceAdjust = 0, $smallCaps = false) { if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $text = str_replace(["\r", "\n"], "", $text); // if ($smallCaps) { // preg_match_all("/(\P{Ll}+)/u", $text, $matches, PREG_SET_ORDER); // $lower = $this->concatMatches($matches); // d($lower); // preg_match_all("/(\p{Ll}+)/u", $text, $matches, PREG_SET_ORDER); // $other = $this->concatMatches($matches); // d($other); // $text = preg_replace_callback("/\p{Ll}/u", array($this, "toUpper"), $text); // } // if there are any open callbacks, then they should be called, to show the start of the line if ($this->nCallback > 0) { for ($i = $this->nCallback; $i > 0; $i--) { // call each function $info = [ 'x' => $x, 'y' => $y, 'angle' => $angle, 'status' => 'sol', 'p' => $this->callback[$i]['p'], 'nCallback' => $this->callback[$i]['nCallback'], 'height' => $this->callback[$i]['height'], 'descender' => $this->callback[$i]['descender'] ]; $func = $this->callback[$i]['f']; $this->$func($info); } } if ($angle == 0) { $this->addContent(sprintf("\nBT %.3F %.3F Td", $x, $y)); } else { $a = deg2rad((float)$angle); $this->addContent( sprintf("\nBT %.3F %.3F %.3F %.3F %.3F %.3F Tm", cos($a), -sin($a), sin($a), cos($a), $x, $y) ); } if ($wordSpaceAdjust != 0) { $this->addContent(sprintf(" %.3F Tw", $wordSpaceAdjust)); } if ($charSpaceAdjust != 0) { $this->addContent(sprintf(" %.3F Tc", $charSpaceAdjust)); } $len = mb_strlen($text); $start = 0; if ($start < $len) { $part = $text; // OAR - Don't need this anymore, given that $start always equals zero. substr($text, $start); $place_text = $this->filterText($part, false); // modify unicode text so that extra word spacing is manually implemented (bug #) if ($this->fonts[$this->currentFont]['isUnicode'] && $wordSpaceAdjust != 0) { $space_scale = 1000 / $size; $place_text = str_replace("\x00\x20", "\x00\x20)\x00\x20" . (-round($space_scale * $wordSpaceAdjust)) . "\x00\x20(", $place_text); } $this->addContent(" /F$this->currentFontNum " . sprintf('%.1F Tf ', $size)); $this->addContent(" [($place_text)] TJ"); } if ($wordSpaceAdjust != 0) { $this->addContent(sprintf(" %.3F Tw", 0)); } if ($charSpaceAdjust != 0) { $this->addContent(sprintf(" %.3F Tc", 0)); } $this->addContent(' ET'); // if there are any open callbacks, then they should be called, to show the end of the line if ($this->nCallback > 0) { for ($i = $this->nCallback; $i > 0; $i--) { // call each function $tmp = $this->getTextPosition($x, $y, $angle, $size, $wordSpaceAdjust, $text); $info = [ 'x' => $tmp[0], 'y' => $tmp[1], 'angle' => $angle, 'status' => 'eol', 'p' => $this->callback[$i]['p'], 'nCallback' => $this->callback[$i]['nCallback'], 'height' => $this->callback[$i]['height'], 'descender' => $this->callback[$i]['descender'] ]; $func = $this->callback[$i]['f']; $this->$func($info); } } if ($this->fonts[$this->currentFont]['isSubsetting']) { $this->registerText($this->currentFont, $text); } } /** * calculate how wide a given text string will be on a page, at a given size. * this can be called externally, but is also used by the other class functions * * @param float $size * @param string $text * @param float $word_spacing * @param float $char_spacing * @return float */ function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0) { static $ord_cache = []; // this function should not change any of the settings, though it will need to // track any directives which change during calculation, so copy them at the start // and put them back at the end. $store_currentTextState = $this->currentTextState; if (!$this->numFonts) { $this->selectFont($this->defaultFont); } $text = str_replace(["\r", "\n"], "", $text); // converts a number or a float to a string so it can get the width $text = "$text"; // hmm, this is where it all starts to get tricky - use the font information to // calculate the width of each character, add them up and convert to user units $w = 0; $cf = $this->currentFont; $current_font = $this->fonts[$cf]; $space_scale = 1000 / ($size > 0 ? $size : 1); if ($current_font['isUnicode']) { // for Unicode, use the code points array to calculate width rather // than just the string itself $unicode = $this->utf8toCodePointsArray($text); foreach ($unicode as $char) { // check if we have to replace character if (isset($current_font['differences'][$char])) { $char = $current_font['differences'][$char]; } if (isset($current_font['C'][$char])) { $char_width = $current_font['C'][$char]; // add the character width $w += $char_width; // add additional padding for space if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space $w += $word_spacing * $space_scale; } } } // add additional char spacing if ($char_spacing != 0) { $w += $char_spacing * $space_scale * count($unicode); } } else { // If CPDF is in Unicode mode but the current font does not support Unicode we need to convert the character set to Windows-1252 if ($this->isUnicode) { $text = mb_convert_encoding($text, 'Windows-1252', 'UTF-8'); } $len = mb_strlen($text, 'Windows-1252'); for ($i = 0; $i < $len; $i++) { $c = $text[$i]; $char = isset($ord_cache[$c]) ? $ord_cache[$c] : ($ord_cache[$c] = ord($c)); // check if we have to replace character if (isset($current_font['differences'][$char])) { $char = $current_font['differences'][$char]; } if (isset($current_font['C'][$char])) { $char_width = $current_font['C'][$char]; // add the character width $w += $char_width; // add additional padding for space if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space $w += $word_spacing * $space_scale; } } } // add additional char spacing if ($char_spacing != 0) { $w += $char_spacing * $space_scale * $len; } } $this->currentTextState = $store_currentTextState; $this->setCurrentFont(); return $w * $size / 1000; } /** * this will be called at a new page to return the state to what it was on the * end of the previous page, before the stack was closed down * This is to get around not being able to have open 'q' across pages * * @param int $pageEnd */ function saveState($pageEnd = 0) { if ($pageEnd) { // this will be called at a new page to return the state to what it was on the // end of the previous page, before the stack was closed down // This is to get around not being able to have open 'q' across pages $opt = $this->stateStack[$pageEnd]; // ok to use this as stack starts numbering at 1 $this->setColor($opt['col'], true); $this->setStrokeColor($opt['str'], true); $this->addContent("\n" . $opt['lin']); // $this->currentLineStyle = $opt['lin']; } else { $this->nStateStack++; $this->stateStack[$this->nStateStack] = [ 'col' => $this->currentColor, 'str' => $this->currentStrokeColor, 'lin' => $this->currentLineStyle ]; } $this->save(); } /** * restore a previously saved state * * @param int $pageEnd */ function restoreState($pageEnd = 0) { if (!$pageEnd) { $n = $this->nStateStack; $this->currentColor = $this->stateStack[$n]['col']; $this->currentStrokeColor = $this->stateStack[$n]['str']; $this->addContent("\n" . $this->stateStack[$n]['lin']); $this->currentLineStyle = $this->stateStack[$n]['lin']; $this->stateStack[$n] = null; unset($this->stateStack[$n]); $this->nStateStack--; } $this->restore(); } /** * make a loose object, the output will go into this object, until it is closed, then will revert to * the current one. * this object will not appear until it is included within a page. * the function will return the object number * * @return int */ function openObject() { $this->nStack++; $this->stack[$this->nStack] = ['c' => $this->currentContents, 'p' => $this->currentPage]; // add a new object of the content type, to hold the data flow $this->numObj++; $this->o_contents($this->numObj, 'new'); $this->currentContents = $this->numObj; $this->looseObjects[$this->numObj] = 1; return $this->numObj; } /** * open an existing object for editing * * @param $id */ function reopenObject($id) { $this->nStack++; $this->stack[$this->nStack] = ['c' => $this->currentContents, 'p' => $this->currentPage]; $this->currentContents = $id; // also if this object is the primary contents for a page, then set the current page to its parent if (isset($this->objects[$id]['onPage'])) { $this->currentPage = $this->objects[$id]['onPage']; } } /** * close an object */ function closeObject() { // close the object, as long as there was one open in the first place, which will be indicated by // an objectId on the stack. if ($this->nStack > 0) { $this->currentContents = $this->stack[$this->nStack]['c']; $this->currentPage = $this->stack[$this->nStack]['p']; $this->nStack--; // easier to probably not worry about removing the old entries, they will be overwritten // if there are new ones. } } /** * stop an object from appearing on pages from this point on * * @param $id */ function stopObject($id) { // if an object has been appearing on pages up to now, then stop it, this page will // be the last one that could contain it. if (isset($this->addLooseObjects[$id])) { $this->addLooseObjects[$id] = ''; } } /** * after an object has been created, it wil only show if it has been added, using this function. * * @param $id * @param string $options */ function addObject($id, $options = 'add') { // add the specified object to the page if (isset($this->looseObjects[$id]) && $this->currentContents != $id) { // then it is a valid object, and it is not being added to itself switch ($options) { case 'all': // then this object is to be added to this page (done in the next block) and // all future new pages. $this->addLooseObjects[$id] = 'all'; case 'add': if (isset($this->objects[$this->currentContents]['onPage'])) { // then the destination contents is the primary for the page // (though this object is actually added to that page) $this->o_page($this->objects[$this->currentContents]['onPage'], 'content', $id); } break; case 'even': $this->addLooseObjects[$id] = 'even'; $pageObjectId = $this->objects[$this->currentContents]['onPage']; if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 0) { $this->addObject($id); // hacky huh :) } break; case 'odd': $this->addLooseObjects[$id] = 'odd'; $pageObjectId = $this->objects[$this->currentContents]['onPage']; if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 1) { $this->addObject($id); // hacky huh :) } break; case 'next': $this->addLooseObjects[$id] = 'all'; break; case 'nexteven': $this->addLooseObjects[$id] = 'even'; break; case 'nextodd': $this->addLooseObjects[$id] = 'odd'; break; } } } /** * return a storable representation of a specific object * * @param $id * @return string|null */ function serializeObject($id) { if (array_key_exists($id, $this->objects)) { return serialize($this->objects[$id]); } return null; } /** * restore an object from its stored representation. Returns its new object id. * * @param $obj * @return int */ function restoreSerializedObject($obj) { $obj_id = $this->openObject(); $this->objects[$obj_id] = unserialize($obj); $this->closeObject(); return $obj_id; } /** * Embeds a file inside the PDF * * @param string $filepath path to the file to store inside the PDF * @param string $embeddedFilename the filename displayed in the list of embedded files * @param string $description a description in the list of embedded files */ public function addEmbeddedFile(string $filepath, string $embeddedFilename, string $description): void { $this->numObj++; $this->o_embedded_file_dictionary( $this->numObj, 'new', [ 'filepath' => $filepath, 'filename' => $embeddedFilename, 'description' => $description ] ); } /** * add content to the documents info object * * @param $label * @param int $value */ function addInfo($label, $value = 0) { // this will only work if the label is one of the valid ones. // modify this so that arrays can be passed as well. // if $label is an array then assume that it is key => value pairs // else assume that they are both scalar, anything else will probably error if (is_array($label)) { foreach ($label as $l => $v) { $this->o_info($this->infoObject, $l, $v); } } else { $this->o_info($this->infoObject, $label, $value); } } /** * set the viewer preferences of the document, it is up to the browser to obey these. * * @param $label * @param int $value */ function setPreferences($label, $value = 0) { // this will only work if the label is one of the valid ones. if (is_array($label)) { foreach ($label as $l => $v) { $this->o_catalog($this->catalogId, 'viewerPreferences', [$l => $v]); } } else { $this->o_catalog($this->catalogId, 'viewerPreferences', [$label => $value]); } } /** * extract an integer from a position in a byte stream * * @param $data * @param $pos * @param $num * @return int */ private function getBytes(&$data, $pos, $num) { // return the integer represented by $num bytes from $pos within $data $ret = 0; for ($i = 0; $i < $num; $i++) { $ret *= 256; $ret += ord($data[$pos + $i]); } return $ret; } /** * Check if image already added to pdf image directory. * If yes, need not to create again (pass empty data) * * @param string $imgname * @return bool */ function image_iscached($imgname) { return isset($this->imagelist[$imgname]); } /** * add a PNG image into the document, from a GD object * this should work with remote files * * @param \GdImage|resource $img A GD resource * @param string $file The PNG file * @param float $x X position * @param float $y Y position * @param float $w Width * @param float $h Height * @param bool $is_mask true if the image is a mask * @param bool $mask true if the image is masked * @throws Exception */ function addImagePng(&$img, $file, $x, $y, $w = 0.0, $h = 0.0, $is_mask = false, $mask = null) { if (!function_exists("imagepng")) { throw new \Exception("The PHP GD extension is required, but is not installed."); } //if already cached, need not to read again if (isset($this->imagelist[$file])) { $data = null; } else { // Example for transparency handling on new image. Retain for current image // $tIndex = imagecolortransparent($img); // if ($tIndex > 0) { // $tColor = imagecolorsforindex($img, $tIndex); // $new_tIndex = imagecolorallocate($new_img, $tColor['red'], $tColor['green'], $tColor['blue']); // imagefill($new_img, 0, 0, $new_tIndex); // imagecolortransparent($new_img, $new_tIndex); // } // blending mode (literal/blending) on drawing into current image. not relevant when not saved or not drawn //imagealphablending($img, true); //default, but explicitely set to ensure pdf compatibility imagesavealpha($img, false/*!$is_mask && !$mask*/); $error = 0; //DEBUG_IMG_TEMP //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addImagePng ' . $file . ']'; } ob_start(); @imagepng($img); $data = ob_get_clean(); if ($data == '') { $error = 1; $errormsg = 'trouble writing file from GD'; //DEBUG_IMG_TEMP //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print 'trouble writing file from GD'; } } if ($error) { $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); return; } } //End isset($this->imagelist[$file]) (png Duplicate removal) $this->addPngFromBuf($data, $file, $x, $y, $w, $h, $is_mask, $mask); } /** * @param $file * @param $x * @param $y * @param $w * @param $h * @param $byte */ protected function addImagePngAlpha($file, $x, $y, $w, $h, $byte) { // generate images $img = @imagecreatefrompng($file); if ($img === false) { return; } // FIXME The pixel transformation doesn't work well with 8bit PNGs $eight_bit = ($byte & 4) !== 4; $wpx = imagesx($img); $hpx = imagesy($img); imagesavealpha($img, false); // create temp alpha file $tempfile_alpha = @tempnam($this->tmp, "cpdf_img_"); @unlink($tempfile_alpha); $tempfile_alpha = "$tempfile_alpha.png"; // create temp plain file $tempfile_plain = @tempnam($this->tmp, "cpdf_img_"); @unlink($tempfile_plain); $tempfile_plain = "$tempfile_plain.png"; $imgalpha = imagecreate($wpx, $hpx); imagesavealpha($imgalpha, false); // generate gray scale palette (0 -> 255) for ($c = 0; $c < 256; ++$c) { imagecolorallocate($imgalpha, $c, $c, $c); } // Use PECL gmagick + Graphics Magic to process transparent PNG images if (extension_loaded("gmagick")) { $gmagick = new \Gmagick($file); $gmagick->setimageformat('png'); // Get opacity channel (negative of alpha channel) $alpha_channel_neg = clone $gmagick; $alpha_channel_neg->separateimagechannel(\Gmagick::CHANNEL_OPACITY); // Negate opacity channel $alpha_channel = new \Gmagick(); $alpha_channel->newimage($wpx, $hpx, "#FFFFFF", "png"); $alpha_channel->compositeimage($alpha_channel_neg, \Gmagick::COMPOSITE_DIFFERENCE, 0, 0); $alpha_channel->separateimagechannel(\Gmagick::CHANNEL_RED); $alpha_channel->writeimage($tempfile_alpha); // Cast to 8bit+palette $imgalpha_ = @imagecreatefrompng($tempfile_alpha); imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); imagedestroy($imgalpha_); imagepng($imgalpha, $tempfile_alpha); // Make opaque image $color_channels = new \Gmagick(); $color_channels->newimage($wpx, $hpx, "#FFFFFF", "png"); $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYRED, 0, 0); $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYGREEN, 0, 0); $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYBLUE, 0, 0); $color_channels->writeimage($tempfile_plain); $imgplain = @imagecreatefrompng($tempfile_plain); } // Use PECL imagick + ImageMagic to process transparent PNG images elseif (extension_loaded("imagick")) { // Native cloning was added to pecl-imagick in svn commit 263814 // the first version containing it was 3.0.1RC1 static $imagickClonable = null; if ($imagickClonable === null) { $imagickClonable = true; if (defined('Imagick::IMAGICK_EXTVER')) { $imagickVersion = \Imagick::IMAGICK_EXTVER; } else { $imagickVersion = '0'; } if (version_compare($imagickVersion, '0.0.1', '>=')) { $imagickClonable = version_compare($imagickVersion, '3.0.1rc1', '>='); } } $imagick = new \Imagick($file); $imagick->setFormat('png'); // Get opacity channel (negative of alpha channel) if ($imagick->getImageAlphaChannel()) { $alpha_channel = $imagickClonable ? clone $imagick : $imagick->clone(); $alpha_channel->separateImageChannel(\Imagick::CHANNEL_ALPHA); // Since ImageMagick7 negate invert transparency as default if (\Imagick::getVersion()['versionNumber'] < 1800) { $alpha_channel->negateImage(true); } $alpha_channel->writeImage($tempfile_alpha); // Cast to 8bit+palette $imgalpha_ = @imagecreatefrompng($tempfile_alpha); imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); imagedestroy($imgalpha_); imagepng($imgalpha, $tempfile_alpha); } else { $tempfile_alpha = null; } // Make opaque image $color_channels = new \Imagick(); $color_channels->newImage($wpx, $hpx, "#FFFFFF", "png"); $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYRED, 0, 0); $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYGREEN, 0, 0); $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYBLUE, 0, 0); $color_channels->writeImage($tempfile_plain); $imgplain = @imagecreatefrompng($tempfile_plain); } else { // allocated colors cache $allocated_colors = []; // extract alpha channel for ($xpx = 0; $xpx < $wpx; ++$xpx) { for ($ypx = 0; $ypx < $hpx; ++$ypx) { $color = imagecolorat($img, $xpx, $ypx); $col = imagecolorsforindex($img, $color); $alpha = $col['alpha']; if ($eight_bit) { // with gamma correction $gammacorr = 2.2; $pixel = round(pow((((127 - $alpha) * 255 / 127) / 255), $gammacorr) * 255); } else { // without gamma correction $pixel = (127 - $alpha) * 2; $key = $col['red'] . $col['green'] . $col['blue']; if (!isset($allocated_colors[$key])) { $pixel_img = imagecolorallocate($img, $col['red'], $col['green'], $col['blue']); $allocated_colors[$key] = $pixel_img; } else { $pixel_img = $allocated_colors[$key]; } imagesetpixel($img, $xpx, $ypx, $pixel_img); } imagesetpixel($imgalpha, $xpx, $ypx, $pixel); } } // extract image without alpha channel $imgplain = imagecreatetruecolor($wpx, $hpx); imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx); imagedestroy($img); imagepng($imgalpha, $tempfile_alpha); imagepng($imgplain, $tempfile_plain); } $this->imageAlphaList[$file] = [$tempfile_alpha, $tempfile_plain]; // embed mask image if ($tempfile_alpha) { $this->addImagePng($imgalpha, $tempfile_alpha, $x, $y, $w, $h, true); imagedestroy($imgalpha); $this->imageCache[] = $tempfile_alpha; } // embed image, masked with previously embedded mask $this->addImagePng($imgplain, $tempfile_plain, $x, $y, $w, $h, false, ($tempfile_alpha !== null)); imagedestroy($imgplain); $this->imageCache[] = $tempfile_plain; } /** * add a PNG image into the document, from a file * this should work with remote files * * @param $file * @param $x * @param $y * @param int $w * @param int $h * @throws Exception */ function addPngFromFile($file, $x, $y, $w = 0, $h = 0) { if (!function_exists("imagecreatefrompng")) { throw new \Exception("The PHP GD extension is required, but is not installed."); } if (isset($this->imageAlphaList[$file])) { [$alphaFile, $plainFile] = $this->imageAlphaList[$file]; if ($alphaFile) { $img = null; $this->addImagePng($img, $alphaFile, $x, $y, $w, $h, true); } $img = null; $this->addImagePng($img, $plainFile, $x, $y, $w, $h, false, ($plainFile !== null)); return; } //if already cached, need not to read again if (isset($this->imagelist[$file])) { $img = null; } else { $info = file_get_contents($file, false, null, 24, 5); $meta = unpack("CbitDepth/CcolorType/CcompressionMethod/CfilterMethod/CinterlaceMethod", $info); $bit_depth = $meta["bitDepth"]; $color_type = $meta["colorType"]; // http://www.w3.org/TR/PNG/#11IHDR // 3 => indexed // 4 => greyscale with alpha // 6 => fullcolor with alpha $is_alpha = in_array($color_type, [4, 6]) || ($color_type == 3 && $bit_depth != 4); if ($is_alpha) { // exclude grayscale alpha $this->addImagePngAlpha($file, $x, $y, $w, $h, $color_type); return; } //png files typically contain an alpha channel. //pdf file format or class.pdf does not support alpha blending. //on alpha blended images, more transparent areas have a color near black. //This appears in the result on not storing the alpha channel. //Correct would be the box background image or its parent when transparent. //But this would make the image dependent on the background. //Therefore create an image with white background and copy in //A more natural background than black is white. //Therefore create an empty image with white background and merge the //image in with alpha blending. $imgtmp = @imagecreatefrompng($file); if (!$imgtmp) { return; } $sx = imagesx($imgtmp); $sy = imagesy($imgtmp); $img = imagecreatetruecolor($sx, $sy); imagealphablending($img, true); // @todo is it still needed ?? $ti = imagecolortransparent($imgtmp); if ($ti >= 0) { $tc = imagecolorsforindex($imgtmp, $ti); $ti = imagecolorallocate($img, $tc['red'], $tc['green'], $tc['blue']); imagefill($img, 0, 0, $ti); imagecolortransparent($img, $ti); } else { imagefill($img, 1, 1, imagecolorallocate($img, 255, 255, 255)); } imagecopy($img, $imgtmp, 0, 0, 0, 0, $sx, $sy); imagedestroy($imgtmp); } $this->addImagePng($img, $file, $x, $y, $w, $h); if ($img) { imagedestroy($img); } } /** * add a PNG image into the document, from a file * this should work with remote files * * @param $file * @param $x * @param $y * @param int $w * @param int $h */ function addSvgFromFile($file, $x, $y, $w = 0, $h = 0) { $doc = new \Svg\Document(); $doc->loadFile($file); $dimensions = $doc->getDimensions(); $this->save(); $this->transform([$w / $dimensions["width"], 0, 0, $h / $dimensions["height"], $x, $y]); $surface = new \Svg\Surface\SurfaceCpdf($doc, $this); $doc->render($surface); $this->restore(); } /** * add a PNG image into the document, from a memory buffer of the file * * @param $data * @param $file * @param $x * @param $y * @param float $w * @param float $h * @param bool $is_mask * @param null $mask */ function addPngFromBuf(&$data, $file, $x, $y, $w = 0.0, $h = 0.0, $is_mask = false, $mask = null) { if (isset($this->imagelist[$file])) { $data = null; $info['width'] = $this->imagelist[$file]['w']; $info['height'] = $this->imagelist[$file]['h']; $label = $this->imagelist[$file]['label']; } else { if ($data == null) { $this->addMessage('addPngFromBuf error - data not present!'); return; } $error = 0; if (!$error) { $header = chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10); if (mb_substr($data, 0, 8, '8bit') != $header) { $error = 1; if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile this file does not have a valid header ' . $file . ']'; } $errormsg = 'this file does not have a valid header'; } } if (!$error) { // set pointer $p = 8; $len = mb_strlen($data, '8bit'); // cycle through the file, identifying chunks $haveHeader = 0; $info = []; $idata = ''; $pdata = ''; while ($p < $len) { $chunkLen = $this->getBytes($data, $p, 4); $chunkType = mb_substr($data, $p + 4, 4, '8bit'); switch ($chunkType) { case 'IHDR': // this is where all the file information comes from $info['width'] = $this->getBytes($data, $p + 8, 4); $info['height'] = $this->getBytes($data, $p + 12, 4); $info['bitDepth'] = ord($data[$p + 16]); $info['colorType'] = ord($data[$p + 17]); $info['compressionMethod'] = ord($data[$p + 18]); $info['filterMethod'] = ord($data[$p + 19]); $info['interlaceMethod'] = ord($data[$p + 20]); //print_r($info); $haveHeader = 1; if ($info['compressionMethod'] != 0) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile unsupported compression method ' . $file . ']'; } $errormsg = 'unsupported compression method'; } if ($info['filterMethod'] != 0) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile unsupported filter method ' . $file . ']'; } $errormsg = 'unsupported filter method'; } break; case 'PLTE': $pdata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); break; case 'IDAT': $idata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); break; case 'tRNS': //this chunk can only occur once and it must occur after the PLTE chunk and before IDAT chunk //print "tRNS found, color type = ".$info['colorType']."\n"; $transparency = []; switch ($info['colorType']) { // indexed color, rbg case 3: /* corresponding to entries in the plte chunk Alpha for palette index 0: 1 byte Alpha for palette index 1: 1 byte ...etc... */ // there will be one entry for each palette entry. up until the last non-opaque entry. // set up an array, stretching over all palette entries which will be o (opaque) or 1 (transparent) $transparency['type'] = 'indexed'; $trans = 0; for ($i = $chunkLen; $i >= 0; $i--) { if (ord($data[$p + 8 + $i]) == 0) { $trans = $i; } } $transparency['data'] = $trans; break; // grayscale case 0: /* corresponding to entries in the plte chunk Gray: 2 bytes, range 0 .. (2^bitdepth)-1 */ // $transparency['grayscale'] = $this->PRVT_getBytes($data,$p+8,2); // g = grayscale $transparency['type'] = 'indexed'; $transparency['data'] = ord($data[$p + 8 + 1]); break; // truecolor case 2: /* corresponding to entries in the plte chunk Red: 2 bytes, range 0 .. (2^bitdepth)-1 Green: 2 bytes, range 0 .. (2^bitdepth)-1 Blue: 2 bytes, range 0 .. (2^bitdepth)-1 */ $transparency['r'] = $this->getBytes($data, $p + 8, 2); // r from truecolor $transparency['g'] = $this->getBytes($data, $p + 10, 2); // g from truecolor $transparency['b'] = $this->getBytes($data, $p + 12, 2); // b from truecolor $transparency['type'] = 'color-key'; break; //unsupported transparency type default: if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile unsupported transparency type ' . $file . ']'; } break; } // KS End new code break; default: break; } $p += $chunkLen + 12; } if (!$haveHeader) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile information header is missing ' . $file . ']'; } $errormsg = 'information header is missing'; } if (isset($info['interlaceMethod']) && $info['interlaceMethod']) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile no support for interlaced images in pdf ' . $file . ']'; } $errormsg = 'There appears to be no support for interlaced images in pdf.'; } } if (!$error && $info['bitDepth'] > 8) { $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile bit depth of 8 or less is supported ' . $file . ']'; } $errormsg = 'only bit depth of 8 or less is supported'; } if (!$error) { switch ($info['colorType']) { case 3: $color = 'DeviceRGB'; $ncolor = 1; break; case 2: $color = 'DeviceRGB'; $ncolor = 3; break; case 0: $color = 'DeviceGray'; $ncolor = 1; break; default: $error = 1; //debugpng if (defined("DEBUGPNG") && DEBUGPNG) { print '[addPngFromFile alpha channel not supported: ' . $info['colorType'] . ' ' . $file . ']'; } $errormsg = 'transparency alpha channel not supported, transparency only supported for palette images.'; } } if ($error) { $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); return; } //print_r($info); // so this image is ok... add it in. $this->numImages++; $im = $this->numImages; $label = "I$im"; $this->numObj++; // $this->o_image($this->numObj,'new',array('label' => $label,'data' => $idata,'iw' => $w,'ih' => $h,'type' => 'png','ic' => $info['width'])); $options = [ 'label' => $label, 'data' => $idata, 'bitsPerComponent' => $info['bitDepth'], 'pdata' => $pdata, 'iw' => $info['width'], 'ih' => $info['height'], 'type' => 'png', 'color' => $color, 'ncolor' => $ncolor, 'masked' => $mask, 'isMask' => $is_mask ]; if (isset($transparency)) { $options['transparency'] = $transparency; } $this->o_image($this->numObj, 'new', $options); $this->imagelist[$file] = ['label' => $label, 'w' => $info['width'], 'h' => $info['height']]; } if ($is_mask) { return; } if ($w <= 0 && $h <= 0) { $w = $info['width']; $h = $info['height']; } if ($w <= 0) { $w = $h / $info['height'] * $info['width']; } if ($h <= 0) { $h = $w * $info['height'] / $info['width']; } $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ", $w, $h, $x, $y, $label)); } /** * add a JPEG image into the document, from a file * * @param $img * @param $x * @param $y * @param int $w * @param int $h */ function addJpegFromFile($img, $x, $y, $w = 0, $h = 0) { // attempt to add a jpeg image straight from a file, using no GD commands // note that this function is unable to operate on a remote file. if (!file_exists($img)) { return; } if ($this->image_iscached($img)) { $data = null; $imageWidth = $this->imagelist[$img]['w']; $imageHeight = $this->imagelist[$img]['h']; $channels = $this->imagelist[$img]['c']; } else { $tmp = getimagesize($img); $imageWidth = $tmp[0]; $imageHeight = $tmp[1]; if (isset($tmp['channels'])) { $channels = $tmp['channels']; } else { $channels = 3; } $data = file_get_contents($img); } if ($w <= 0 && $h <= 0) { $w = $imageWidth; } if ($w == 0) { $w = $h / $imageHeight * $imageWidth; } if ($h == 0) { $h = $w * $imageHeight / $imageWidth; } $this->addJpegImage_common($data, $img, $imageWidth, $imageHeight, $x, $y, $w, $h, $channels); } /** * common code used by the two JPEG adding functions * @param $data * @param $imgname * @param $imageWidth * @param $imageHeight * @param $x * @param $y * @param int $w * @param int $h * @param int $channels */ private function addJpegImage_common( &$data, $imgname, $imageWidth, $imageHeight, $x, $y, $w = 0, $h = 0, $channels = 3 ) { if ($this->image_iscached($imgname)) { $label = $this->imagelist[$imgname]['label']; //debugpng //if (DEBUGPNG) print '[addJpegImage_common Duplicate '.$imgname.']'; } else { if ($data == null) { $this->addMessage('addJpegImage_common error - (' . $imgname . ') data not present!'); return; } // note that this function is not to be called externally // it is just the common code between the GD and the file options $this->numImages++; $im = $this->numImages; $label = "I$im"; $this->numObj++; $this->o_image( $this->numObj, 'new', [ 'label' => $label, 'data' => &$data, 'iw' => $imageWidth, 'ih' => $imageHeight, 'channels' => $channels ] ); $this->imagelist[$imgname] = [ 'label' => $label, 'w' => $imageWidth, 'h' => $imageHeight, 'c' => $channels ]; } $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ ", $w, $h, $x, $y, $label)); } /** * specify where the document should open when it first starts * * @param $style * @param int $a * @param int $b * @param int $c */ function openHere($style, $a = 0, $b = 0, $c = 0) { // this function will open the document at a specified page, in a specified style // the values for style, and the required parameters are: // 'XYZ' left, top, zoom // 'Fit' // 'FitH' top // 'FitV' left // 'FitR' left,bottom,right // 'FitB' // 'FitBH' top // 'FitBV' left $this->numObj++; $this->o_destination( $this->numObj, 'new', ['page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c] ); $id = $this->catalogId; $this->o_catalog($id, 'openHere', $this->numObj); } /** * Add JavaScript code to the PDF document * * @param string $code */ function addJavascript($code) { $this->javascript .= $code; } /** * create a labelled destination within the document * * @param $label * @param $style * @param int $a * @param int $b * @param int $c */ function addDestination($label, $style, $a = 0, $b = 0, $c = 0) { // associates the given label with the destination, it is done this way so that a destination can be specified after // it has been linked to // styles are the same as the 'openHere' function $this->numObj++; $this->o_destination( $this->numObj, 'new', ['page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c] ); $id = $this->numObj; // store the label->idf relationship, note that this means that labels can be used only once $this->destinations["$label"] = $id; } /** * define font families, this is used to initialize the font families for the default fonts * and for the user to add new ones for their fonts. The default bahavious can be overridden should * that be desired. * * @param $family * @param string $options */ function setFontFamily($family, $options = '') { if (!is_array($options)) { if ($family === 'init') { // set the known family groups // these font families will be used to enable bold and italic markers to be included // within text streams. html forms will be used... $this->fontFamilies['Helvetica.afm'] = [ 'b' => 'Helvetica-Bold.afm', 'i' => 'Helvetica-Oblique.afm', 'bi' => 'Helvetica-BoldOblique.afm', 'ib' => 'Helvetica-BoldOblique.afm' ]; $this->fontFamilies['Courier.afm'] = [ 'b' => 'Courier-Bold.afm', 'i' => 'Courier-Oblique.afm', 'bi' => 'Courier-BoldOblique.afm', 'ib' => 'Courier-BoldOblique.afm' ]; $this->fontFamilies['Times-Roman.afm'] = [ 'b' => 'Times-Bold.afm', 'i' => 'Times-Italic.afm', 'bi' => 'Times-BoldItalic.afm', 'ib' => 'Times-BoldItalic.afm' ]; } } else { // the user is trying to set a font family // note that this can also be used to set the base ones to something else if (mb_strlen($family)) { $this->fontFamilies[$family] = $options; } } } /** * used to add messages for use in debugging * * @param $message */ function addMessage($message) { $this->messages .= $message . "\n"; } /** * a few functions which should allow the document to be treated transactionally. * * @param $action */ function transaction($action) { switch ($action) { case 'start': // store all the data away into the checkpoint variable $data = get_object_vars($this); $this->checkpoint = $data; unset($data); break; case 'commit': if (is_array($this->checkpoint) && isset($this->checkpoint['checkpoint'])) { $tmp = $this->checkpoint['checkpoint']; $this->checkpoint = $tmp; unset($tmp); } else { $this->checkpoint = ''; } break; case 'rewind': // do not destroy the current checkpoint, but move us back to the state then, so that we can try again if (is_array($this->checkpoint)) { // can only abort if were inside a checkpoint $tmp = $this->checkpoint; foreach ($tmp as $k => $v) { if ($k !== 'checkpoint') { $this->$k = $v; } } unset($tmp); } break; case 'abort': if (is_array($this->checkpoint)) { // can only abort if were inside a checkpoint $tmp = $this->checkpoint; foreach ($tmp as $k => $v) { $this->$k = $v; } unset($tmp); } break; } } } PK!l-convertformstools/pdf/dompdf/lib/res/html.cssnu[/** * dompdf default stylesheet. * * @package dompdf * @link http://dompdf.github.com/ * @author Benj Carson * @author Blake Ross * @author Fabien Ménager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License * * Portions from Mozilla * @link https://dxr.mozilla.org/mozilla-central/source/layout/style/res/html.css * @license http://mozilla.org/MPL/2.0/ Mozilla Public License, v. 2.0 * * Portions from W3C * @link https://drafts.csswg.org/css-ui-3/#default-style-sheet * */ @page { margin: 1.2cm; } html { display: -dompdf-page !important; counter-reset: page; } /* blocks */ article, aside, details, div, dt, figcaption, footer, form, header, hgroup, main, nav, noscript, section, summary { display: block; } body { page-break-before: avoid; display: block !important; counter-increment: page; } p, dl, multicol { display: block; margin: 1em 0; } dd { display: block; margin-left: 40px; } blockquote, figure { display: block; margin: 1em 40px; } address { display: block; font-style: italic; } center { display: block; text-align: center; } blockquote[type=cite] { display: block; margin: 1em 0; padding-left: 1em; border-left: solid; border-color: blue; border-width: thin; } h1, h2, h3, h4, h5, h6 { display: block; font-weight: bold; } h1 { font-size: 2em; margin: .67em 0; } h2 { font-size: 1.5em; margin: .83em 0; } h3 { font-size: 1.17em; margin: 1em 0; } h4 { margin: 1.33em 0; } h5 { font-size: 0.83em; margin: 1.67em 0; } h6 { font-size: 0.67em; margin: 2.33em 0; } listing { display: block; font-family: fixed; font-size: medium; white-space: pre; margin: 1em 0; } plaintext, pre, xmp { display: block; font-family: fixed; white-space: pre; margin: 1em 0; } /* tables */ table { display: table; border-spacing: 2px; border-collapse: separate; margin-top: 0; margin-bottom: 0; text-indent: 0; text-align: left; /* quirk */ } table[border] { border: outset gray; } table[border] td, table[border] th { border: 1px inset gray; } table[border="0"] td, table[border="0"] th { border-width: 0; } /* make sure backgrounds are inherited in tables -- see bug 4510 */ td, th, tr { background: inherit; } /* caption inherits from table not table-outer */ caption { display: table-caption; text-align: center; } tr { display: table-row; vertical-align: inherit; } col { display: table-column; } colgroup { display: table-column-group; } tbody { display: table-row-group; vertical-align: middle; } thead { display: table-header-group; vertical-align: middle; } tfoot { display: table-footer-group; vertical-align: middle; } /* To simulate tbody auto-insertion */ table > tr { vertical-align: middle; } td { display: table-cell; vertical-align: inherit; text-align: inherit; padding: 1px; } th { display: table-cell; vertical-align: inherit; text-align: center; font-weight: bold; padding: 1px; } /* inlines */ q:before { content: open-quote; } q:after { content: close-quote; } :link { color: #00c; text-decoration: underline; } b, strong { font-weight: bolder; } i, cite, em, var, dfn { font-style: italic; } tt, code, kbd, samp { font-family: fixed; } u, ins { text-decoration: underline; } s, strike, del { text-decoration: line-through; } big { font-size: larger; } small { font-size: smaller; } sub { vertical-align: sub; font-size: smaller; line-height: normal; } sup { vertical-align: super; font-size: smaller; line-height: normal; } nobr { white-space: nowrap; } mark { background: yellow; color: black; } /* titles */ abbr[title], acronym[title] { text-decoration: dotted underline; } /* lists */ ul, menu, dir { display: block; list-style-type: disc; margin: 1em 0; padding-left: 40px; } ol { display: block; list-style-type: decimal; margin: 1em 0; padding-left: 40px; } li { display: list-item; } /*li:before { display: -dompdf-list-bullet !important; content: counter(-dompdf-default-counter) ". "; padding-right: 0.5em; }*/ /* nested lists have no top/bottom margins */ :matches(ul, ol, dir, menu, dl) ul, :matches(ul, ol, dir, menu, dl) ol, :matches(ul, ol, dir, menu, dl) dir, :matches(ul, ol, dir, menu, dl) menu, :matches(ul, ol, dir, menu, dl) dl { margin-top: 0; margin-bottom: 0; } /* 2 deep unordered lists use a circle */ :matches(ul, ol, dir, menu) ul, :matches(ul, ol, dir, menu) ul, :matches(ul, ol, dir, menu) ul, :matches(ul, ol, dir, menu) ul { list-style-type: circle; } /* 3 deep (or more) unordered lists use a square */ :matches(ul, ol, dir, menu) :matches(ul, ol, dir, menu) ul, :matches(ul, ol, dir, menu) :matches(ul, ol, dir, menu) menu, :matches(ul, ol, dir, menu) :matches(ul, ol, dir, menu) dir { list-style-type: square; } /* forms */ /* From https://drafts.csswg.org/css-ui-3/#default-style-sheet */ form { display: block; } input, button, select { display: inline-block; font-family: sans-serif; } input[type=text], input[type=password], select { width: 12em; } input[type=text], input[type=password], input[type=button], input[type=submit], input[type=reset], input[type=file], button, textarea, select { background: #FFF; border: 1px solid #999; padding: 2px; margin: 2px; } input[type=button], input[type=submit], input[type=reset], input[type=file], button { background: #CCC; text-align: center; } input[type=file] { width: 8em; } input[type=text]:before, input[type=button]:before, input[type=submit]:before, input[type=reset]:before { content: attr(value); } input[type=file]:before { content: "Choose a file"; } input[type=password][value]:before { font-family: "DejaVu Sans" !important; content: "\2022\2022\2022\2022\2022\2022\2022\2022"; line-height: 1em; } input[type=checkbox], input[type=radio], select:after { font-family: "DejaVu Sans" !important; font-size: 18px; line-height: 1; } input[type=checkbox]:before { content: "\2610"; } input[type=checkbox][checked]:before { content: "\2611"; } input[type=radio]:before { content: "\25CB"; } input[type=radio][checked]:before { content: "\25C9"; } textarea { display: block; height: 3em; overflow: hidden; font-family: monospace; white-space: pre-wrap; word-wrap: break-word; } select { position: relative!important; overflow: hidden!important; } select:after { position: absolute; right: 0; top: 0; height: 5em; width: 1.4em; text-align: center; background: #CCC; content: "\25BE"; } select option { display: none; } select option[selected] { display: inline; } fieldset { display: block; margin: 0.6em 2px 2px; padding: 0.75em; border: 1pt groove #666; position: relative; } fieldset > legend { position: absolute; top: -0.6em; left: 0.75em; padding: 0 0.3em; background: white; } legend { display: inline-block; } /* leafs */ hr { display: block; height: 0; border: 1px inset; margin: 0.5em auto 0.5em auto; } hr[size="1"] { border-style: solid none none none; } iframe { border: 2px inset; } noframes { display: block; } br { display: -dompdf-br; } img, img_generated { display: -dompdf-image !important; } dompdf_generated { display: inline; } /* hidden elements */ area, base, basefont, head, meta, script, style, title, noembed, param { display: none; -dompdf-keep: yes; } PK!CEE5convertformstools/pdf/dompdf/lib/res/broken_image.svgnu[ PK!Ɛjj5convertformstools/pdf/dompdf/lib/res/broken_image.pngnu[PNG  IHDR@@XGlsBITOPLTEतスި pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time04/12/11#IDATHj0 `*q> {@ `ذwΎIЋIVսuug}_ ,:͠ l ]ͽp#`ݔPr{n&vD D `$4<tX\P za》mV-<|##!pWG˗>Ӳȣ@݋X4oޚfY> @E(/r߿HI..p.@8P&Ɓ6U(;ȓH% O"OȺ[ߥIENDB`PK!0! ((,convertformstools/pdf/dompdf/src/LineBox.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf; use Dompdf\FrameDecorator\AbstractFrameDecorator; use Dompdf\FrameDecorator\Block; use Dompdf\FrameDecorator\ListBullet; use Dompdf\FrameDecorator\Page; use Dompdf\FrameReflower\Text as TextFrameReflower; use Dompdf\Positioner\Inline as InlinePositioner; /** * The line box class * * This class represents a line box * http://www.w3.org/TR/CSS2/visuren.html#line-box * * @package dompdf */ class LineBox { /** * @var Block */ protected $_block_frame; /** * @var AbstractFrameDecorator[] */ protected $_frames = []; /** * @var ListBullet[] */ protected $list_markers = []; /** * @var int */ public $wc = 0; /** * @var float */ public $y = null; /** * @var float */ public $w = 0.0; /** * @var float */ public $h = 0.0; /** * @var float */ public $left = 0.0; /** * @var float */ public $right = 0.0; /** * @var AbstractFrameDecorator */ public $tallest_frame = null; /** * @var bool[] */ public $floating_blocks = []; /** * @var bool */ public $br = false; /** * Whether the line box contains any inline-positioned frames. * * @var bool */ public $inline = false; /** * Class constructor * * @param Block $frame the Block containing this line * @param int $y */ public function __construct(Block $frame, $y = 0) { $this->_block_frame = $frame; $this->_frames = []; $this->y = $y; $this->get_float_offsets(); } /** * Returns the floating elements inside the first floating parent * * @param Page $root * * @return Frame[] */ public function get_floats_inside(Page $root) { $floating_frames = $root->get_floating_frames(); if (count($floating_frames) == 0) { return $floating_frames; } // Find nearest floating element $p = $this->_block_frame; while ($p->get_style()->float === "none") { $parent = $p->get_parent(); if (!$parent) { break; } $p = $parent; } if ($p == $root) { return $floating_frames; } $parent = $p; $childs = []; foreach ($floating_frames as $_floating) { $p = $_floating->get_parent(); while (($p = $p->get_parent()) && $p !== $parent); if ($p) { $childs[] = $p; } } return $childs; } public function get_float_offsets() { static $anti_infinite_loop = 10000; // FIXME smelly hack $reflower = $this->_block_frame->get_reflower(); if (!$reflower) { return; } $cb_w = null; $block = $this->_block_frame; $root = $block->get_root(); if (!$root) { return; } $style = $this->_block_frame->get_style(); $floating_frames = $this->get_floats_inside($root); $inside_left_floating_width = 0; $inside_right_floating_width = 0; $outside_left_floating_width = 0; $outside_right_floating_width = 0; foreach ($floating_frames as $child_key => $floating_frame) { $floating_frame_parent = $floating_frame->get_parent(); $id = $floating_frame->get_id(); if (isset($this->floating_blocks[$id])) { continue; } $float = $floating_frame->get_style()->float; $floating_width = $floating_frame->get_margin_width(); if (!$cb_w) { $cb_w = $floating_frame->get_containing_block("w"); } $line_w = $this->get_width(); if (!$floating_frame->_float_next_line && ($cb_w <= $line_w + $floating_width) && ($cb_w > $line_w)) { $floating_frame->_float_next_line = true; continue; } // If the child is still shifted by the floating element if ($anti_infinite_loop-- > 0 && $floating_frame->get_position("y") + $floating_frame->get_margin_height() >= $this->y && $block->get_position("x") + $block->get_margin_width() >= $floating_frame->get_position("x") ) { if ($float === "left") { if ($floating_frame_parent === $this->_block_frame) { $inside_left_floating_width += $floating_width; } else { $outside_left_floating_width += $floating_width; } } elseif ($float === "right") { if ($floating_frame_parent === $this->_block_frame) { $inside_right_floating_width += $floating_width; } else { $outside_right_floating_width += $floating_width; } } $this->floating_blocks[$id] = true; } // else, the floating element won't shift anymore else { $root->remove_floating_frame($child_key); } } $this->left += $inside_left_floating_width; if ($outside_left_floating_width > 0 && $outside_left_floating_width > ((float)$style->length_in_pt($style->margin_left) + (float)$style->length_in_pt($style->padding_left))) { $this->left += $outside_left_floating_width - (float)$style->length_in_pt($style->margin_left) - (float)$style->length_in_pt($style->padding_left); } $this->right += $inside_right_floating_width; if ($outside_right_floating_width > 0 && $outside_right_floating_width > ((float)$style->length_in_pt($style->margin_left) + (float)$style->length_in_pt($style->padding_right))) { $this->right += $outside_right_floating_width - (float)$style->length_in_pt($style->margin_right) - (float)$style->length_in_pt($style->padding_right); } } /** * @return float */ public function get_width() { return $this->left + $this->w + $this->right; } /** * @return Block */ public function get_block_frame() { return $this->_block_frame; } /** * @return AbstractFrameDecorator[] */ function &get_frames() { return $this->_frames; } /** * @param AbstractFrameDecorator $frame */ public function add_frame(Frame $frame) { $this->_frames[] = $frame; if ($frame->get_positioner() instanceof InlinePositioner) { $this->inline = true; } } /** * Remove the frame at the given index and all following frames from the * line. * * @param int $index */ public function remove_frames(int $index): void { $lastIndex = count($this->_frames) - 1; if ($index < 0 || $index > $lastIndex) { return; } for ($i = $lastIndex; $i >= $index; $i--) { $f = $this->_frames[$i]; unset($this->_frames[$i]); $this->w -= $f->get_margin_width(); } // Reset array indices $this->_frames = array_values($this->_frames); // Recalculate the height of the line $h = 0.0; $this->inline = false; foreach ($this->_frames as $f) { $h = max($h, $f->get_margin_height()); if ($f->get_positioner() instanceof InlinePositioner) { $this->inline = true; } } $this->h = $h; } /** * Get the `outside` positioned list markers to be vertically aligned with * the line box. * * @return ListBullet[] */ public function get_list_markers(): array { return $this->list_markers; } /** * Add a list marker to the line box. * * The list marker is only added for the purpose of vertical alignment, it * is not actually added to the list of frames of the line box. */ public function add_list_marker(ListBullet $marker): void { $this->list_markers[] = $marker; } /** * An iterator of all list markers and inline positioned frames of the line * box. * * @return \Iterator */ public function frames_to_align(): \Iterator { yield from $this->list_markers; foreach ($this->_frames as $frame) { if ($frame->get_positioner() instanceof InlinePositioner) { yield $frame; } } } /** * Trim trailing whitespace from the line. */ public function trim_trailing_ws(): void { $lastIndex = count($this->_frames) - 1; if ($lastIndex < 0) { return; } $lastFrame = $this->_frames[$lastIndex]; $reflower = $lastFrame->get_reflower(); if ($reflower instanceof TextFrameReflower && !$lastFrame->is_pre()) { $reflower->trim_trailing_ws(); $this->recalculate_width(); } } /** * Recalculate LineBox width based on the contained frames total width. * * @return float */ public function recalculate_width() { $width = 0.0; foreach ($this->_frames as $frame) { $width += $frame->get_margin_width(); } return $this->w = $width; } /** * @return string */ public function __toString() { $props = ["wc", "y", "w", "h", "left", "right", "br"]; $s = ""; foreach ($props as $prop) { $s .= "$prop: " . $this->$prop . "\n"; } $s .= count($this->_frames) . " frames\n"; return $s; } } /* class LineBoxList implements Iterator { private $_p = 0; private $_lines = array(); } */ PK!P9nCnC0convertformstools/pdf/dompdf/src/FontMetrics.phpnu[ * @author Helmut Tischer * @author Fabien Ménager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf; use FontLib\Font; /** * The font metrics class * * This class provides information about fonts and text. It can resolve * font names into actual installed font files, as well as determine the * size of text in a particular font and size. * * @static * @package dompdf */ class FontMetrics { /** * Name of the font cache file * * This file must be writable by the webserver process only to update it * with save_font_families() after adding the .afm file references of a new font family * with FontMetrics::saveFontFamilies(). * This is typically done only from command line with load_font.php on converting * ttf fonts to ufm with php-font-lib. */ const CACHE_FILE = "dompdf_font_family_cache.php"; /** * @var Canvas * @deprecated */ protected $pdf; /** * Underlying {@link Canvas} object to perform text size calculations * * @var Canvas */ protected $canvas; /** * Array of font family names to font files * * Usually cached by the {@link load_font.php} script * * @var array */ protected $fontLookup = []; /** * @var Options */ private $options; /** * Class initialization */ public function __construct(Canvas $canvas, Options $options) { $this->setCanvas($canvas); $this->setOptions($options); $this->loadFontFamilies(); } /** * @deprecated */ public function save_font_families() { $this->saveFontFamilies(); } /** * Saves the stored font family cache * * The name and location of the cache file are determined by {@link * FontMetrics::CACHE_FILE}. This file should be writable by the * webserver process. * * @see FontMetrics::loadFontFamilies() */ public function saveFontFamilies() { // replace the path to the DOMPDF font directories with the corresponding constants (allows for more portability) $cacheData = sprintf("fontLookup as $family => $variants) { $cacheData .= sprintf(" '%s' => array(%s", addslashes($family), PHP_EOL); foreach ($variants as $variant => $path) { $path = sprintf("'%s'", $path); $path = str_replace('\'' . $this->options->getFontDir(), '$fontDir . \'', $path); $path = str_replace('\'' . $this->options->getRootDir(), '$rootDir . \'', $path); $cacheData .= sprintf(" '%s' => %s,%s", $variant, $path, PHP_EOL); } $cacheData .= sprintf(" ),%s", PHP_EOL); } $cacheData .= ");" . PHP_EOL; $cacheData .= "}; ?>"; file_put_contents($this->getCacheFile(), $cacheData); } /** * @deprecated */ public function load_font_families() { $this->loadFontFamilies(); } /** * Loads the stored font family cache * * @see FontMetrics::saveFontFamilies() */ public function loadFontFamilies() { $fontDir = $this->options->getFontDir(); $rootDir = $this->options->getRootDir(); // FIXME: temporarily define constants for cache files <= v0.6.2 if (!defined("DOMPDF_DIR")) { define("DOMPDF_DIR", $rootDir); } if (!defined("DOMPDF_FONT_DIR")) { define("DOMPDF_FONT_DIR", $fontDir); } $file = $rootDir . "/lib/fonts/dompdf_font_family_cache.dist.php"; $distFontsClosure = require $file; $distFonts = is_array($distFontsClosure) ? $distFontsClosure : $distFontsClosure($rootDir); if (!is_readable($this->getCacheFile())) { $this->fontLookup = $distFonts; return; } $cacheDataClosure = require $this->getCacheFile(); $cacheData = is_array($cacheDataClosure) ? $cacheDataClosure : $cacheDataClosure($fontDir, $rootDir); $this->fontLookup = []; if (is_array($this->fontLookup)) { foreach ($cacheData as $key => $value) { $this->fontLookup[stripslashes($key)] = $value; } } // Merge provided fonts $this->fontLookup += $distFonts; } /** * @param array $style * @param string $remote_file * @param resource $context * @return bool * @deprecated */ public function register_font($style, $remote_file, $context = null) { return $this->registerFont($style, $remote_file); } /** * @param array $style * @param string $remoteFile * @param resource $context * @return bool */ public function registerFont($style, $remoteFile, $context = null) { $fontname = mb_strtolower($style["family"]); $families = $this->getFontFamilies(); $entry = []; if (isset($families[$fontname])) { $entry = $families[$fontname]; } $styleString = $this->getType("{$style['weight']} {$style['style']}"); $fontDir = $this->options->getFontDir(); $remoteHash = md5($remoteFile); $prefix = $fontname . "_" . $styleString; $prefix = trim($prefix, "-"); if (function_exists('iconv')) { $prefix = @iconv('utf-8', 'us-ascii//TRANSLIT', $prefix); } $prefix_encoding = mb_detect_encoding($prefix, mb_detect_order(), true); $substchar = mb_substitute_character(); mb_substitute_character(0x005F); $prefix = mb_convert_encoding($prefix, "ISO-8859-1", $prefix_encoding); mb_substitute_character($substchar); $prefix = preg_replace("[\W]", "_", $prefix); $prefix = preg_replace("/[^-_\w]+/", "", $prefix); $localFile = $fontDir . "/" . $prefix . "_" . $remoteHash; if (isset($entry[$styleString]) && $localFile == $entry[$styleString]) { return true; } $cacheEntry = $localFile; $localFile .= ".".strtolower(pathinfo(parse_url($remoteFile, PHP_URL_PATH), PATHINFO_EXTENSION)); $entry[$styleString] = $cacheEntry; // Download the remote file [$protocol] = Helpers::explode_url($remoteFile); if (!$this->options->isRemoteEnabled() && ($protocol !== "" && $protocol !== "file://")) { Helpers::record_warnings(E_USER_WARNING, "Remote font resource $remoteFile referenced, but remote file download is disabled.", __FILE__, __LINE__); return false; } if ($protocol === "" || $protocol === "file://") { $realfile = realpath($remoteFile); $rootDir = realpath($this->options->getRootDir()); if (strpos($realfile, $rootDir) !== 0) { $chroot = $this->options->getChroot(); $chrootValid = false; foreach ($chroot as $chrootPath) { $chrootPath = realpath($chrootPath); if ($chrootPath !== false && strpos($realfile, $chrootPath) === 0) { $chrootValid = true; break; } } if ($chrootValid !== true) { Helpers::record_warnings(E_USER_WARNING, "Permission denied on $remoteFile. The file could not be found under the paths specified by Options::chroot.", __FILE__, __LINE__); return false; } } if (!$realfile) { Helpers::record_warnings(E_USER_WARNING, "File '$realfile' not found.", __FILE__, __LINE__); return false; } $remoteFile = $realfile; } list($remoteFileContent, $http_response_header) = @Helpers::getFileContent($remoteFile, $context); if ($remoteFileContent === null) { return false; } $localTempFile = @tempnam($this->options->get("tempDir"), "dompdf-font-"); file_put_contents($localTempFile, $remoteFileContent); $font = Font::load($localTempFile); if (!$font) { unlink($localTempFile); return false; } $font->parse(); $font->saveAdobeFontMetrics("$cacheEntry.ufm"); $font->close(); unlink($localTempFile); if ( !file_exists("$cacheEntry.ufm") ) { return false; } // Save the changes file_put_contents($localFile, $remoteFileContent); if ( !file_exists($localFile) ) { unlink("$cacheEntry.ufm"); return false; } $this->setFontFamily($fontname, $entry); $this->saveFontFamilies(); return true; } /** * @param $text * @param $font * @param $size * @param float $word_spacing * @param float $char_spacing * @return float * @deprecated */ public function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0) { //return self::$_pdf->get_text_width($text, $font, $size, $word_spacing, $char_spacing); return $this->getTextWidth($text, $font, $size, $word_spacing, $char_spacing); } /** * Calculates text size, in points * * @param string $text the text to be sized * @param string $font the desired font * @param float $size the desired font size * @param float $wordSpacing * @param float $charSpacing * * @internal param float $spacing word spacing, if any * @return float */ public function getTextWidth($text, $font, $size, $wordSpacing = 0.0, $charSpacing = 0.0) { // @todo Make sure this cache is efficient before enabling it static $cache = []; if ($text === "") { return 0; } // Don't cache long strings $useCache = !isset($text[50]); // Faster than strlen // Text-size calculations depend on the canvas used. Make sure to not // return wrong values when switching canvas backends $canvasClass = get_class($this->canvas); $key = "$canvasClass/$font/$size/$wordSpacing/$charSpacing"; if ($useCache && isset($cache[$key][$text])) { return $cache[$key][$text]; } $width = $this->canvas->get_text_width($text, $font, $size, $wordSpacing, $charSpacing); if ($useCache) { $cache[$key][$text] = $width; } return $width; } /** * @param $font * @param $size * @return float * @deprecated */ public function get_font_height($font, $size) { return $this->getFontHeight($font, $size); } /** * Calculates font height, in points * * @param string $font * @param float $size * * @return float */ public function getFontHeight($font, $size) { return $this->canvas->get_font_height($font, $size); } /** * Calculates font baseline, in points * * @param string $font * @param float $size * * @return float */ public function getFontBaseline($font, $size) { return $this->canvas->get_font_baseline($font, $size); } /** * @param $family_raw * @param string $subtype_raw * @return string * @deprecated */ public function get_font($family_raw, $subtype_raw = "normal") { return $this->getFont($family_raw, $subtype_raw); } /** * Resolves a font family & subtype into an actual font file * Subtype can be one of 'normal', 'bold', 'italic' or 'bold_italic'. If * the particular font family has no suitable font file, the default font * ({@link Options::defaultFont}) is used. The font file returned * is the absolute pathname to the font file on the system. * * @param string $familyRaw * @param string $subtypeRaw * * @return string */ public function getFont($familyRaw, $subtypeRaw = "normal") { static $cache = []; if (isset($cache[$familyRaw][$subtypeRaw])) { return $cache[$familyRaw][$subtypeRaw]; } /* Allow calling for various fonts in search path. Therefore not immediately * return replacement on non match. * Only when called with NULL try replacement. * When this is also missing there is really trouble. * If only the subtype fails, nevertheless return failure. * Only on checking the fallback font, check various subtypes on same font. */ $subtype = strtolower($subtypeRaw); if ($familyRaw) { $family = str_replace(["'", '"'], "", strtolower($familyRaw)); if (isset($this->fontLookup[$family][$subtype])) { return $cache[$familyRaw][$subtypeRaw] = $this->fontLookup[$family][$subtype]; } return null; } $family = "serif"; if (isset($this->fontLookup[$family][$subtype])) { return $cache[$familyRaw][$subtypeRaw] = $this->fontLookup[$family][$subtype]; } if (!isset($this->fontLookup[$family])) { return null; } $family = $this->fontLookup[$family]; foreach ($family as $sub => $font) { if (strpos($subtype, $sub) !== false) { return $cache[$familyRaw][$subtypeRaw] = $font; } } if ($subtype !== "normal") { foreach ($family as $sub => $font) { if ($sub !== "normal") { return $cache[$familyRaw][$subtypeRaw] = $font; } } } $subtype = "normal"; if (isset($family[$subtype])) { return $cache[$familyRaw][$subtypeRaw] = $family[$subtype]; } return null; } /** * @param $family * @return null|string * @deprecated */ public function get_family($family) { return $this->getFamily($family); } /** * @param string $family * @return null|string */ public function getFamily($family) { $family = str_replace(["'", '"'], "", mb_strtolower($family)); if (isset($this->fontLookup[$family])) { return $this->fontLookup[$family]; } return null; } /** * @param $type * @return string * @deprecated */ public function get_type($type) { return $this->getType($type); } /** * @param string $type * @return string */ public function getType($type) { if (preg_match('/bold/i', $type)) { $weight = 700; } elseif (preg_match('/([1-9]00)/', $type, $match)) { $weight = (int)$match[0]; } else { $weight = 400; } $weight = $weight === 400 ? 'normal' : $weight; $weight = $weight === 700 ? 'bold' : $weight; $style = preg_match('/italic|oblique/i', $type) ? 'italic' : null; if ($weight === 'normal' && $style !== null) { return $style; } return $style === null ? $weight : $weight.'_'.$style; } /** * @return array * @deprecated */ public function get_font_families() { return $this->getFontFamilies(); } /** * Returns the current font lookup table * * @return array */ public function getFontFamilies() { return $this->fontLookup; } /** * @param string $fontname * @param mixed $entry * @deprecated */ public function set_font_family($fontname, $entry) { $this->setFontFamily($fontname, $entry); } /** * @param string $fontname * @param mixed $entry */ public function setFontFamily($fontname, $entry) { $this->fontLookup[mb_strtolower($fontname)] = $entry; } /** * @return string */ public function getCacheFile() { return $this->options->getFontDir() . '/' . self::CACHE_FILE; } /** * @param Options $options * @return $this */ public function setOptions(Options $options) { $this->options = $options; return $this; } /** * @return Options */ public function getOptions() { return $this->options; } /** * @param Canvas $canvas * @return $this */ public function setCanvas(Canvas $canvas) { $this->canvas = $canvas; // Still write deprecated pdf for now. It might be used by a parent class. $this->pdf = $canvas; return $this; } /** * @return Canvas */ public function getCanvas() { return $this->canvas; } } PK!0W<convertformstools/pdf/dompdf/src/Frame/FrameTreeIterator.phpnu[_stack[] = $this->_root = $root; $this->_num = 0; } public function rewind(): void { $this->_stack = [$this->_root]; $this->_num = 0; } /** * @return bool */ public function valid(): bool { return count($this->_stack) > 0; } /** * @return int */ public function key(): int { return $this->_num; } /** * @return Frame */ public function current(): Frame { return end($this->_stack); } public function next(): void { $b = end($this->_stack); // Pop last element unset($this->_stack[key($this->_stack)]); $this->_num++; // Push all children onto the stack in reverse order if ($c = $b->get_last_child()) { $this->_stack[] = $c; while ($c = $c->get_prev_sibling()) { $this->_stack[] = $c; } } } } PK!_frame = $frame; } /** * @return FrameListIterator */ function getIterator(): FrameListIterator { return new FrameListIterator($this->_frame); } } PK!i!!4convertformstools/pdf/dompdf/src/Frame/FrameTree.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ /** * Represents an entire document as a tree of frames * * The FrameTree consists of {@link Frame} objects each tied to specific * DOMNode objects in a specific DomDocument. The FrameTree has the same * structure as the DomDocument, but adds additional capabilities for * styling and layout. * * @package dompdf */ class FrameTree { /** * Tags to ignore while parsing the tree * * @var array */ protected static $HIDDEN_TAGS = [ "area", "base", "basefont", "head", "style", "meta", "title", "colgroup", "noembed", "param", "#comment" ]; /** * The main DomDocument * * @see http://ca2.php.net/manual/en/ref.dom.php * @var DOMDocument */ protected $_dom; /** * The root node of the FrameTree. * * @var Frame */ protected $_root; /** * Subtrees of absolutely positioned elements * * @var array of Frames */ protected $_absolute_frames; /** * A mapping of {@link Frame} objects to DOMNode objects * * @var array */ protected $_registry; /** * Class constructor * * @param DOMDocument $dom the main DomDocument object representing the current html document */ public function __construct(DomDocument $dom) { $this->_dom = $dom; $this->_root = null; $this->_registry = []; } /** * Returns the DOMDocument object representing the current html document * * @return DOMDocument */ public function get_dom() { return $this->_dom; } /** * Returns the root frame of the tree * * @return Frame */ public function get_root() { return $this->_root; } /** * Returns a specific frame given its id * * @param string $id * * @return Frame|null */ public function get_frame($id) { return isset($this->_registry[$id]) ? $this->_registry[$id] : null; } /** * Returns a post-order iterator for all frames in the tree * * @return FrameTreeList|Frame[] */ public function get_frames() { return new FrameTreeList($this->_root); } /** * Builds the tree */ public function build_tree() { $html = $this->_dom->getElementsByTagName("html")->item(0); if (is_null($html)) { $html = $this->_dom->firstChild; } if (is_null($html)) { throw new Exception("Requested HTML document contains no data."); } $this->fix_tables(); $this->_root = $this->_build_tree_r($html); } /** * Adds missing TBODYs around TR */ protected function fix_tables() { $xp = new DOMXPath($this->_dom); // Move table caption before the table // FIXME find a better way to deal with it... $captions = $xp->query('//table/caption'); foreach ($captions as $caption) { $table = $caption->parentNode; $table->parentNode->insertBefore($caption, $table); } $firstRows = $xp->query('//table/tr[1]'); /** @var DOMElement $tableChild */ foreach ($firstRows as $tableChild) { $tbody = $this->_dom->createElement('tbody'); $tableNode = $tableChild->parentNode; do { if ($tableChild->nodeName === 'tr') { $tmpNode = $tableChild; $tableChild = $tableChild->nextSibling; $tableNode->removeChild($tmpNode); $tbody->appendChild($tmpNode); } else { if ($tbody->hasChildNodes() === true) { $tableNode->insertBefore($tbody, $tableChild); $tbody = $this->_dom->createElement('tbody'); } $tableChild = $tableChild->nextSibling; } } while ($tableChild); if ($tbody->hasChildNodes() === true) { $tableNode->appendChild($tbody); } } } // FIXME: temporary hack, preferably we will improve rendering of sequential #text nodes /** * Remove a child from a node * * Remove a child from a node. If the removed node results in two * adjacent #text nodes then combine them. * * @param DOMNode $node the current DOMNode being considered * @param array $children an array of nodes that are the children of $node * @param int $index index from the $children array of the node to remove */ protected function _remove_node(DOMNode $node, array &$children, $index) { $child = $children[$index]; $previousChild = $child->previousSibling; $nextChild = $child->nextSibling; $node->removeChild($child); if (isset($previousChild, $nextChild)) { if ($previousChild->nodeName === "#text" && $nextChild->nodeName === "#text") { $previousChild->nodeValue .= $nextChild->nodeValue; $this->_remove_node($node, $children, $index+1); } } array_splice($children, $index, 1); } /** * Recursively adds {@link Frame} objects to the tree * * Recursively build a tree of Frame objects based on a dom tree. * No layout information is calculated at this time, although the * tree may be adjusted (i.e. nodes and frames for generated content * and images may be created). * * @param DOMNode $node the current DOMNode being considered * * @return Frame */ protected function _build_tree_r(DOMNode $node) { $frame = new Frame($node); $id = $frame->get_id(); $this->_registry[$id] = $frame; if (!$node->hasChildNodes()) { return $frame; } // Store the children in an array so that the tree can be modified $children = []; $length = $node->childNodes->length; for ($i = 0; $i < $length; $i++) { $children[] = $node->childNodes->item($i); } $index = 0; // INFO: We don't advance $index if a node is removed to avoid skipping nodes while ($index < count($children)) { $child = $children[$index]; $nodeName = strtolower($child->nodeName); // Skip non-displaying nodes if (in_array($nodeName, self::$HIDDEN_TAGS)) { if ($nodeName !== "head" && $nodeName !== "style") { $this->_remove_node($node, $children, $index); } else { $index++; } continue; } // Skip empty text nodes if ($nodeName === "#text" && $child->nodeValue === "") { $this->_remove_node($node, $children, $index); continue; } // Skip empty image nodes if ($nodeName === "img" && $child->getAttribute("src") === "") { $this->_remove_node($node, $children, $index); continue; } if (is_object($child)) { $frame->append_child($this->_build_tree_r($child), false); } $index++; } return $frame; } /** * @param DOMElement $node * @param DOMElement $new_node * @param string $pos * * @return mixed */ public function insert_node(DOMElement $node, DOMElement $new_node, $pos) { if ($pos === "after" || !$node->firstChild) { $node->appendChild($new_node); } else { $node->insertBefore($new_node, $node->firstChild); } $this->_build_tree_r($new_node); $frame_id = $new_node->getAttribute("frame_id"); $frame = $this->get_frame($frame_id); $parent_id = $node->getAttribute("frame_id"); $parent = $this->get_frame($parent_id); if ($parent) { if ($pos === "before") { $parent->prepend_child($frame, false); } else { $parent->append_child($frame, false); } } return $frame_id; } } PK!m2convertformstools/pdf/dompdf/src/Frame/Factory.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Frame; use Dompdf\Dompdf; use Dompdf\Exception; use Dompdf\Frame; use Dompdf\FrameDecorator\AbstractFrameDecorator; use DOMXPath; use Dompdf\FrameDecorator\Page as PageFrameDecorator; use Dompdf\FrameReflower\Page as PageFrameReflower; use Dompdf\Positioner\AbstractPositioner; /** * Contains frame decorating logic * * This class is responsible for assigning the correct {@link AbstractFrameDecorator}, * {@link AbstractPositioner}, and {@link AbstractFrameReflower} objects to {@link Frame} * objects. This is determined primarily by the Frame's display type, but * also by the Frame's node's type (e.g. DomElement vs. #text) * * @access private * @package dompdf */ class Factory { /** * Array of positioners for specific frame types * * @var AbstractPositioner[] */ protected static $_positioners; /** * Decorate the root Frame * * @param $root Frame The frame to decorate * @param $dompdf Dompdf The dompdf instance * * @return PageFrameDecorator */ static function decorate_root(Frame $root, Dompdf $dompdf) { $frame = new PageFrameDecorator($root, $dompdf); $frame->set_reflower(new PageFrameReflower($frame)); $root->set_decorator($frame); return $frame; } /** * Decorate a Frame * * @param Frame $frame The frame to decorate * @param Dompdf $dompdf The dompdf instance * @param Frame $root The root of the frame * * @throws Exception * @return AbstractFrameDecorator * FIXME: this is admittedly a little smelly... */ static function decorate_frame(Frame $frame, Dompdf $dompdf, Frame $root = null) { $style = $frame->get_style(); $display = $style->display; switch ($display) { case "block": $positioner = "Block"; $decorator = "Block"; $reflower = "Block"; break; case "inline-block": $positioner = "Inline"; $decorator = "Block"; $reflower = "Block"; break; case "inline": $positioner = "Inline"; if ($frame->is_text_node()) { $decorator = "Text"; $reflower = "Text"; } else { $decorator = "Inline"; $reflower = "Inline"; } break; case "table": $positioner = "Block"; $decorator = "Table"; $reflower = "Table"; break; case "inline-table": $positioner = "Inline"; $decorator = "Table"; $reflower = "Table"; break; case "table-row-group": case "table-header-group": case "table-footer-group": $positioner = "NullPositioner"; $decorator = "TableRowGroup"; $reflower = "TableRowGroup"; break; case "table-row": $positioner = "NullPositioner"; $decorator = "TableRow"; $reflower = "TableRow"; break; case "table-cell": $positioner = "TableCell"; $decorator = "TableCell"; $reflower = "TableCell"; break; case "list-item": $positioner = "Block"; $decorator = "Block"; $reflower = "Block"; break; case "-dompdf-list-bullet": if ($style->list_style_position === "inside") { $positioner = "Inline"; } else { $positioner = "ListBullet"; } if ($style->list_style_image !== "none") { $decorator = "ListBulletImage"; } else { $decorator = "ListBullet"; } $reflower = "ListBullet"; break; case "-dompdf-image": $positioner = "Inline"; $decorator = "Image"; $reflower = "Image"; break; case "-dompdf-br": $positioner = "Inline"; $decorator = "Inline"; $reflower = "Inline"; break; default: case "none": if ($style->_dompdf_keep !== "yes") { // Remove the node and the frame $frame->get_parent()->remove_child($frame); return; } $positioner = "NullPositioner"; $decorator = "NullFrameDecorator"; $reflower = "NullFrameReflower"; break; } // Handle CSS position $position = $style->position; if ($position === "absolute") { $positioner = "Absolute"; } else { if ($position === "fixed") { $positioner = "Fixed"; } } $node = $frame->get_node(); // Handle nodeName if ($node->nodeName === "img") { $style->display = "-dompdf-image"; $decorator = "Image"; $reflower = "Image"; } $decorator = "Dompdf\\FrameDecorator\\$decorator"; $reflower = "Dompdf\\FrameReflower\\$reflower"; /** @var AbstractFrameDecorator $deco */ $deco = new $decorator($frame, $dompdf); $deco->set_positioner(self::getPositionerInstance($positioner)); $deco->set_reflower(new $reflower($deco, $dompdf->getFontMetrics())); if ($root) { $deco->set_root($root); } if ($display === "list-item") { // Insert a list-bullet frame $xml = $dompdf->getDom(); $bullet_node = $xml->createElement("bullet"); // arbitrary choice $b_f = new Frame($bullet_node); $node = $frame->get_node(); $parent_node = $node->parentNode; if ($parent_node) { if (!$parent_node->hasAttribute("dompdf-children-count")) { $xpath = new DOMXPath($xml); $count = $xpath->query("li", $parent_node)->length; $parent_node->setAttribute("dompdf-children-count", $count); } if (is_numeric($node->getAttribute("value"))) { $index = intval($node->getAttribute("value")); } else { if (!$parent_node->hasAttribute("dompdf-counter")) { $index = ($parent_node->hasAttribute("start") ? $parent_node->getAttribute("start") : 1); } else { $index = (int)$parent_node->getAttribute("dompdf-counter") + 1; } } $parent_node->setAttribute("dompdf-counter", $index); $bullet_node->setAttribute("dompdf-counter", $index); } $new_style = $dompdf->getCss()->create_style(); $new_style->display = "-dompdf-list-bullet"; $new_style->inherit($style); $b_f->set_style($new_style); $deco->prepend_child(Factory::decorate_frame($b_f, $dompdf, $root)); } return $deco; } /** * Creates Positioners * * @param string $type type of positioner to use * @return AbstractPositioner */ protected static function getPositionerInstance($type) { if (!isset(self::$_positioners[$type])) { $class = '\\Dompdf\\Positioner\\'.$type; self::$_positioners[$type] = new $class(); } return self::$_positioners[$type]; } } PK!4//8convertformstools/pdf/dompdf/src/Frame/FrameTreeList.phpnu[_root = $root; } /** * @return FrameTreeIterator */ public function getIterator(): FrameTreeIterator { return new FrameTreeIterator($this->_root); } } PK!tR  <convertformstools/pdf/dompdf/src/Frame/FrameListIterator.phpnu[parent = $frame; $this->rewind(); } public function rewind(): void { $this->cur = $this->parent->get_first_child(); $this->prev = null; $this->num = 0; } /** * @return bool */ public function valid(): bool { return $this->cur !== null; } /** * @return int */ public function key(): int { return $this->num; } /** * @return Frame|null */ public function current(): ?Frame { return $this->cur; } public function next(): void { if ($this->cur === null) { return; } if ($this->cur->get_parent() === $this->parent) { $this->prev = $this->cur; $this->cur = $this->cur->get_next_sibling(); $this->num++; } else { // Continue from the previous child if the current frame has been // moved to another parent $this->cur = $this->prev !== null ? $this->prev->get_next_sibling() : $this->parent->get_first_child(); } } } PK!Hkk=convertformstools/pdf/dompdf/src/Exception/ImageException.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Exception; use Dompdf\Exception; /** * Image exception thrown by DOMPDF * * @package dompdf */ class ImageException extends Exception { /** * Class constructor * * @param string $message Error message * @param int $code Error code */ function __construct($message = null, $code = 0) { parent::__construct($message, $code); } } PK!b[UUJconvertformstools/pdf/dompdf/src/FrameDecorator/AbstractFrameDecorator.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ /** * Base AbstractFrameDecorator class * * @package dompdf */ abstract class AbstractFrameDecorator extends Frame { const DEFAULT_COUNTER = "-dompdf-default-counter"; /** * array([id] => counter_value) (for generated content) * * @var array */ public $_counters = []; /** * The root node of the DOM tree * * @var Frame */ protected $_root; /** * The decorated frame * * @var Frame */ protected $_frame; /** * AbstractPositioner object used to position this frame (Strategy pattern) * * @var AbstractPositioner */ protected $_positioner; /** * Reflower object used to calculate frame dimensions (Strategy pattern) * * @var AbstractFrameReflower */ protected $_reflower; /** * Reference to the current dompdf instance * * @var Dompdf */ protected $_dompdf; /** * First block parent * * @var Block */ private $_block_parent; /** * First positioned parent (position: relative | absolute | fixed) * * @var AbstractFrameDecorator */ private $_positionned_parent; /** * Cache for the get_parent while loop results * * @var Frame */ private $_cached_parent; /** * Whether generated content and counters have been set. * * @var bool */ public $content_set = false; /** * Whether the frame has been split * * @var bool */ public $is_split = false; /** * Class constructor * * @param Frame $frame The decoration target * @param Dompdf $dompdf The Dompdf object */ function __construct(Frame $frame, Dompdf $dompdf) { $this->_frame = $frame; $this->_root = null; $this->_dompdf = $dompdf; $frame->set_decorator($this); } /** * "Destructor": forcibly free all references held by this object * * @param bool $recursive if true, call dispose on all children */ function dispose($recursive = false) { if ($recursive) { while ($child = $this->get_first_child()) { $child->dispose(true); } } $this->_root = null; unset($this->_root); $this->_frame->dispose(true); $this->_frame = null; unset($this->_frame); $this->_positioner = null; unset($this->_positioner); $this->_reflower = null; unset($this->_reflower); } /** * Return a copy of this frame with $node as its node * * @param DOMNode $node * * @return AbstractFrameDecorator */ function copy(DOMNode $node) { $frame = new Frame($node); $frame->set_style(clone $this->_frame->get_original_style()); if ($node instanceof DOMElement && $node->hasAttribute("id")) { $node->setAttribute("data-dompdf-original-id", $node->getAttribute("id")); $node->removeAttribute("id"); } return Factory::decorate_frame($frame, $this->_dompdf, $this->_root); } /** * Create a deep copy: copy this node and all children * * @return AbstractFrameDecorator */ function deep_copy() { $node = $this->_frame->get_node()->cloneNode(); $frame = new Frame($node); $frame->set_style(clone $this->_frame->get_original_style()); if ($node instanceof DOMElement && $node->hasAttribute("id")) { $node->setAttribute("data-dompdf-original-id", $node->getAttribute("id")); $node->removeAttribute("id"); } $deco = Factory::decorate_frame($frame, $this->_dompdf, $this->_root); foreach ($this->get_children() as $child) { $deco->append_child($child->deep_copy()); } return $deco; } /** * Create an anonymous child frame, inheriting styles from this frame. * * @param string $node_name * @param string $display * * @return AbstractFrameDecorator */ public function create_anonymous_child(string $node_name, string $display): AbstractFrameDecorator { $style = $this->get_style(); $child_style = $style->get_stylesheet()->create_style(); $child_style->inherit($style); $child_style->display = $display; $node = $this->get_node()->ownerDocument->createElement($node_name); $frame = new Frame($node); $frame->set_style($child_style); return Factory::decorate_frame($frame, $this->_dompdf, $this->_root); } function reset() { $this->_frame->reset(); $this->_reflower->reset(); $this->reset_generated_content(); $this->revert_counter_increment(); $this->content_set = false; $this->_counters = []; // clear parent lookup caches $this->_cached_parent = null; $this->_block_parent = null; $this->_positionned_parent = null; // Reset all children foreach ($this->get_children() as $child) { $child->reset(); } } /** * If this represents a generated node then child nodes represent generated * content. Remove the children since the content will be generated next * time this frame is reflowed. */ protected function reset_generated_content(): void { if ($this->content_set && $this->get_node()->nodeName === "dompdf_generated" ) { foreach ($this->get_children() as $child) { $this->remove_child($child); } } } /** * Decrement any counters that were incremented on the current node, unless * that node is the body. */ protected function revert_counter_increment(): void { if ($this->content_set && $this->get_node()->nodeName !== "body" && ($decrement = $this->get_style()->counter_increment) !== "none" ) { $this->decrement_counters($decrement); } } // Getters ----------- function get_id() { return $this->_frame->get_id(); } /** * @return Frame */ function get_frame() { return $this->_frame; } function get_node() { return $this->_frame->get_node(); } function get_style() { return $this->_frame->get_style(); } function get_original_style() { return $this->_frame->get_original_style(); } function get_containing_block($i = null) { return $this->_frame->get_containing_block($i); } function get_position($i = null) { return $this->_frame->get_position($i); } /** * @return Dompdf */ function get_dompdf() { return $this->_dompdf; } public function get_margin_width(): float { return $this->_frame->get_margin_width(); } public function get_margin_height(): float { return $this->_frame->get_margin_height(); } public function get_content_box(): array { return $this->_frame->get_content_box(); } public function get_padding_box(): array { return $this->_frame->get_padding_box(); } public function get_border_box(): array { return $this->_frame->get_border_box(); } function set_id($id) { $this->_frame->set_id($id); } function set_style(Style $style) { $this->_frame->set_style($style); } function set_containing_block($x = null, $y = null, $w = null, $h = null) { $this->_frame->set_containing_block($x, $y, $w, $h); } function set_position($x = null, $y = null) { $this->_frame->set_position($x, $y); } function is_auto_height() { return $this->_frame->is_auto_height(); } function is_auto_width() { return $this->_frame->is_auto_width(); } function __toString() { return $this->_frame->__toString(); } function prepend_child(Frame $child, $update_node = true) { while ($child instanceof AbstractFrameDecorator) { $child = $child->_frame; } $this->_frame->prepend_child($child, $update_node); } function append_child(Frame $child, $update_node = true) { while ($child instanceof AbstractFrameDecorator) { $child = $child->_frame; } $this->_frame->append_child($child, $update_node); } function insert_child_before(Frame $new_child, Frame $ref, $update_node = true) { while ($new_child instanceof AbstractFrameDecorator) { $new_child = $new_child->_frame; } if ($ref instanceof AbstractFrameDecorator) { $ref = $ref->_frame; } $this->_frame->insert_child_before($new_child, $ref, $update_node); } function insert_child_after(Frame $new_child, Frame $ref, $update_node = true) { $insert_frame = $new_child; while ($insert_frame instanceof AbstractFrameDecorator) { $insert_frame = $insert_frame->_frame; } $reference_frame = $ref; while ($reference_frame instanceof AbstractFrameDecorator) { $reference_frame = $reference_frame->_frame; } $this->_frame->insert_child_after($insert_frame, $reference_frame, $update_node); } function remove_child(Frame $child, $update_node = true) { while ($child instanceof AbstractFrameDecorator) { $child = $child->_frame; } return $this->_frame->remove_child($child, $update_node); } /** * @param bool $use_cache * @return AbstractFrameDecorator */ function get_parent($use_cache = true) { if ($use_cache && $this->_cached_parent) { return $this->_cached_parent; } $p = $this->_frame->get_parent(); if ($p && $deco = $p->get_decorator()) { while ($tmp = $deco->get_decorator()) { $deco = $tmp; } return $this->_cached_parent = $deco; } else { return $this->_cached_parent = $p; } } /** * @return AbstractFrameDecorator */ function get_first_child() { $c = $this->_frame->get_first_child(); if ($c && $deco = $c->get_decorator()) { while ($tmp = $deco->get_decorator()) { $deco = $tmp; } return $deco; } else { if ($c) { return $c; } } return null; } /** * @return AbstractFrameDecorator */ function get_last_child() { $c = $this->_frame->get_last_child(); if ($c && $deco = $c->get_decorator()) { while ($tmp = $deco->get_decorator()) { $deco = $tmp; } return $deco; } else { if ($c) { return $c; } } return null; } /** * @return AbstractFrameDecorator */ function get_prev_sibling() { $s = $this->_frame->get_prev_sibling(); if ($s && $deco = $s->get_decorator()) { while ($tmp = $deco->get_decorator()) { $deco = $tmp; } return $deco; } else { if ($s) { return $s; } } return null; } /** * @return AbstractFrameDecorator */ function get_next_sibling() { $s = $this->_frame->get_next_sibling(); if ($s && $deco = $s->get_decorator()) { while ($tmp = $deco->get_decorator()) { $deco = $tmp; } return $deco; } else { if ($s) { return $s; } } return null; } /** * @return FrameTreeList */ function get_subtree() { return new FrameTreeList($this); } function set_positioner(AbstractPositioner $posn) { $this->_positioner = $posn; if ($this->_frame instanceof AbstractFrameDecorator) { $this->_frame->set_positioner($posn); } } function set_reflower(AbstractFrameReflower $reflower) { $this->_reflower = $reflower; if ($this->_frame instanceof AbstractFrameDecorator) { $this->_frame->set_reflower($reflower); } } /** * @return AbstractPositioner */ function get_positioner() { return $this->_positioner; } /** * @return AbstractFrameReflower */ function get_reflower() { return $this->_reflower; } /** * @param Frame $root */ function set_root(Frame $root) { $this->_root = $root; if ($this->_frame instanceof AbstractFrameDecorator) { $this->_frame->set_root($root); } } /** * @return Page */ function get_root() { return $this->_root; } /** * @return Block */ function find_block_parent() { // Find our nearest block level parent if (isset($this->_block_parent)) { return $this->_block_parent; } $p = $this->get_parent(); while ($p) { if ($p->is_block()) { break; } $p = $p->get_parent(); } return $this->_block_parent = $p; } /** * @return AbstractFrameDecorator */ function find_positionned_parent() { // Find our nearest relative positioned parent if (isset($this->_positionned_parent)) { return $this->_positionned_parent; } $p = $this->get_parent(); while ($p) { if ($p->is_positionned()) { break; } $p = $p->get_parent(); } if (!$p) { $p = $this->_root; } return $this->_positionned_parent = $p; } /** * Split this frame at $child. * The current frame is cloned and $child and all children following * $child are added to the clone. The clone is then passed to the * current frame's parent->split() method. * * @param Frame|null $child * @param bool $page_break * @param bool $forced Whether the page break is forced. * * @throws Exception */ public function split(?Frame $child = null, bool $page_break = false, bool $forced = false): void { if (is_null($child)) { $this->get_parent()->split($this, $page_break, $forced); return; } if ($child->get_parent() !== $this) { throw new Exception("Unable to split: frame is not a child of this one."); } $this->revert_counter_increment(); $node = $this->_frame->get_node(); $split = $this->copy($node->cloneNode()); $style = $this->_frame->get_style(); $split_style = $split->get_original_style(); // Truncate the box decoration at the split, except for the body if ($node->nodeName !== "body") { // Style reset on the first and second parts $style->margin_bottom = 0; $style->padding_bottom = 0; $style->border_bottom = 0; $style->border_bottom_left_radius = 0; $style->border_bottom_right_radius = 0; // second $split_style->margin_top = 0; $split_style->padding_top = 0; $split_style->border_top = 0; $split_style->border_top_left_radius = 0; $split_style->border_top_right_radius = 0; $split_style->page_break_before = "auto"; } $split_style->text_indent = 0; $split_style->counter_reset = "none"; $split->set_style(clone $split_style); $this->is_split = true; $split->_splitted = true; $split->_already_pushed = true; $this->get_parent()->insert_child_after($split, $this); if ($this instanceof Block) { // Remove the frames that will be moved to the new split node from // the line boxes $this->remove_frames_from_line($child); // recalculate the float offsets after paging foreach ($this->get_line_boxes() as $line_box) { $line_box->get_float_offsets(); } } if (!$forced) { // Reset top margin in case of an unforced page break // https://www.w3.org/TR/CSS21/page.html#allowed-page-breaks $child->get_original_style()->margin_top = 0; } // Add $child and all following siblings to the new split node $iter = $child; while ($iter) { $frame = $iter; $iter = $iter->get_next_sibling(); $frame->reset(); $split->append_child($frame); } $this->get_parent()->split($split, $page_break, $forced); // Preserve the current counter values. This must be done after the // parent split, as counters get reset on frame reset $split->_counters = $this->_counters; } /** * @param array $counters */ public function reset_counters(array $counters): void { foreach ($counters as $id => $value) { $this->reset_counter($id, $value); } } /** * @param string $id * @param int $value */ public function reset_counter(string $id = self::DEFAULT_COUNTER, int $value = 0): void { $this->get_parent()->_counters[$id] = $value; } /** * @param array $counters */ public function decrement_counters(array $counters): void { foreach ($counters as $id => $increment) { $this->increment_counter($id, $increment * -1); } } /** * @param array $counters */ public function increment_counters(array $counters): void { foreach ($counters as $id => $increment) { $this->increment_counter($id, $increment); } } /** * @param string $id * @param int $increment */ public function increment_counter(string $id = self::DEFAULT_COUNTER, int $increment = 1): void { $counter_frame = $this->lookup_counter_frame($id); if ($counter_frame) { if (!isset($counter_frame->_counters[$id])) { $counter_frame->_counters[$id] = 0; } $counter_frame->_counters[$id] += $increment; } } /** * @param string $id * @return AbstractFrameDecorator|null */ function lookup_counter_frame($id = self::DEFAULT_COUNTER) { $f = $this->get_parent(); while ($f) { if (isset($f->_counters[$id])) { return $f; } $fp = $f->get_parent(); if (!$fp) { return $f; } $f = $fp; } return null; } /** * @param string $id * @param string $type * @return bool|string * * TODO: What version is the best : this one or the one in ListBullet ? */ function counter_value(string $id = self::DEFAULT_COUNTER, string $type = "decimal") { $type = mb_strtolower($type); if (!isset($this->_counters[$id])) { $this->_counters[$id] = 0; } $value = $this->_counters[$id]; switch ($type) { default: case "decimal": return $value; case "decimal-leading-zero": return str_pad($value, 2, "0", STR_PAD_LEFT); case "lower-roman": return Helpers::dec2roman($value); case "upper-roman": return mb_strtoupper(Helpers::dec2roman($value)); case "lower-latin": case "lower-alpha": return chr((($value - 1) % 26) + ord('a')); case "upper-latin": case "upper-alpha": return chr((($value - 1) % 26) + ord('A')); case "lower-greek": return Helpers::unichr($value + 944); case "upper-greek": return Helpers::unichr($value + 912); } } final function position() { $this->_positioner->position($this); } /** * @param float $offset_x * @param float $offset_y * @param bool $ignore_self */ final function move($offset_x, $offset_y, $ignore_self = false) { $this->_positioner->move($this, $offset_x, $offset_y, $ignore_self); } /** * @param Block|null $block */ final function reflow(Block $block = null) { // Uncomment this to see the frames before they're laid out, instead of // during rendering. //echo $this->_frame; flush(); $this->_reflower->reflow($block); } /** * @return array */ final public function get_min_max_width(): array { return $this->_reflower->get_min_max_width(); } } PK!}܃Fconvertformstools/pdf/dompdf/src/FrameDecorator/NullFrameDecorator.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; /** * Dummy decorator * * @package dompdf */ class NullFrameDecorator extends AbstractFrameDecorator { /** * NullFrameDecorator constructor. * @param Frame $frame * @param Dompdf $dompdf */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); $style = $this->_frame->get_style(); $style->width = 0; $style->height = 0; $style->margin = 0; $style->padding = 0; } } PK!mJ[Aconvertformstools/pdf/dompdf/src/FrameDecorator/TableRowGroup.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; /** * Table row group decorator * * Overrides split() method for tbody, thead & tfoot elements * * @package dompdf */ class TableRowGroup extends AbstractFrameDecorator { /** * Class constructor * * @param Frame $frame Frame to decorate * @param Dompdf $dompdf Current dompdf instance */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); } /** * Split the row group at the given child and remove all subsequent child * rows and all subsequent row groups from the cellmap. */ public function split(?Frame $child = null, bool $page_break = false, bool $forced = false): void { if (is_null($child)) { parent::split($child, $page_break, $forced); return; } // Remove child & all subsequent rows from the cellmap $cellmap = $this->get_parent()->get_cellmap(); $iter = $child; while ($iter) { $cellmap->remove_row($iter); $iter = $iter->get_next_sibling(); } // Remove all subsequent row groups from the cellmap $iter = $this->get_next_sibling(); while ($iter) { $cellmap->remove_row_group($iter); $iter = $iter->get_next_sibling(); } // If we are splitting at the first child remove the // table-row-group from the cellmap as well if ($child === $this->get_first_child()) { $cellmap->remove_row_group($this); parent::split(null, $page_break, $forced); return; } $cellmap->update_row_group($this, $child->get_prev_sibling()); parent::split($child, $page_break, $forced); } } PK!aa8convertformstools/pdf/dompdf/src/FrameDecorator/Page.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Helpers; use Dompdf\Frame; use Dompdf\Renderer; /** * Decorates frames for page layout * * @access private * @package dompdf */ class Page extends AbstractFrameDecorator { /** * The y value of the bottom edge of the page area. * * https://www.w3.org/TR/CSS21/page.html#page-margins * * @var float */ protected $bottom_page_edge; /** * Flag indicating page is full. * * @var bool */ protected $_page_full; /** * Number of tables currently being reflowed * * @var int */ protected $_in_table; /** * The pdf renderer * * @var Renderer */ protected $_renderer; /** * This page's floating frames * * @var array */ protected $_floating_frames = []; //........................................................................ /** * Class constructor * * @param Frame $frame the frame to decorate * @param Dompdf $dompdf */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); $this->_page_full = false; $this->_in_table = 0; $this->bottom_page_edge = null; } /** * Set the renderer used for this pdf * * @param Renderer $renderer the renderer to use */ function set_renderer($renderer) { $this->_renderer = $renderer; } /** * Return the renderer used for this pdf * * @return Renderer */ function get_renderer() { return $this->_renderer; } /** * Calculate the bottom edge of the page area after margins have been * applied for the current page. */ public function calculate_bottom_page_edge(): void { [, , , $cbh] = $this->get_containing_block(); $style = $this->get_style(); $margin_bottom = (float) $style->length_in_pt($style->margin_bottom, $cbh); $this->bottom_page_edge = $cbh - $margin_bottom; } /** * Returns true if the page is full and is no longer accepting frames. * * @return bool */ function is_full() { return $this->_page_full; } /** * Start a new page by resetting the full flag. */ function next_page() { $this->_floating_frames = []; $this->_renderer->new_page(); $this->_page_full = false; } /** * Indicate to the page that a table is currently being reflowed. */ function table_reflow_start() { $this->_in_table++; } /** * Indicate to the page that table reflow is finished. */ function table_reflow_end() { $this->_in_table--; } /** * Return whether we are currently in a nested table or not * * @return bool */ function in_nested_table() { return $this->_in_table > 1; } /** * Check if a forced page break is required before $frame. This uses the * frame's page_break_before property as well as the preceding frame's * page_break_after property. * * @link http://www.w3.org/TR/CSS21/page.html#forced * * @param AbstractFrameDecorator $frame the frame to check * * @return bool true if a page break occurred */ function check_forced_page_break(Frame $frame) { // Skip check if page is already split and for the body if ($this->_page_full || $frame->get_node()->nodeName === "body") { return false; } $page_breaks = ["always", "left", "right"]; $style = $frame->get_style(); if (($frame->is_block_level() || $style->display === "table-row") && in_array($style->page_break_before, $page_breaks, true) ) { // Prevent cascading splits $frame->split(null, true, true); // We have to grab the style again here because split() resets // $frame->style to the frame's original style. $frame->get_style()->page_break_before = "auto"; $this->_page_full = true; $frame->_already_pushed = true; return true; } // Find the preceding block-level sibling (or table row). Inline // elements are treated as if wrapped in an anonymous block container // here. See https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level $prev = $frame->get_prev_sibling(); while ($prev && (($prev->is_text_node() && $prev->get_node()->nodeValue === "") || $prev->get_node()->nodeName === "bullet") ) { $prev = $prev->get_prev_sibling(); } if ($prev && ($prev->is_block_level() || $prev->get_style()->display === "table-row")) { if (in_array($prev->get_style()->page_break_after, $page_breaks, true)) { // Prevent cascading splits $frame->split(null, true, true); $prev->get_style()->page_break_after = "auto"; $this->_page_full = true; $frame->_already_pushed = true; return true; } $prev_last_child = $prev->get_last_child(); while ($prev_last_child && (($prev_last_child->is_text_node() && $prev_last_child->get_node()->nodeValue === "") || $prev_last_child->get_node()->nodeName === "bullet") ) { $prev_last_child = $prev_last_child->get_prev_sibling(); } if ($prev_last_child && $prev_last_child->is_block_level() && in_array($prev_last_child->get_style()->page_break_after, $page_breaks, true) ) { $frame->split(null, true, true); $prev_last_child->get_style()->page_break_after = "auto"; $this->_page_full = true; $frame->_already_pushed = true; return true; } } return false; } /** * Check for a gap between the top content edge of a frame and its child * content. * * Additionally, the top margin, border, and padding of the frame must fit * on the current page. * * @param float $childPos The top margin or line-box edge of the child content. * @param Frame $frame The parent frame to check. * @return bool */ protected function hasGap(float $childPos, Frame $frame): bool { $style = $frame->get_style(); $cbw = $frame->get_containing_block("w"); $contentEdge = $frame->get_position("y") + (float) $style->length_in_pt([ $style->margin_top, $style->border_top_width, $style->padding_top ], $cbw); return Helpers::lengthGreater($childPos, $contentEdge) && Helpers::lengthLessOrEqual($contentEdge, $this->bottom_page_edge); } /** * Determine if a page break is allowed before $frame * http://www.w3.org/TR/CSS21/page.html#allowed-page-breaks * * In the normal flow, page breaks can occur at the following places: * * 1. In the vertical margin between block boxes. When an * unforced page break occurs here, the used values of the * relevant 'margin-top' and 'margin-bottom' properties are set * to '0'. When a forced page break occurs here, the used value * of the relevant 'margin-bottom' property is set to '0'; the * relevant 'margin-top' used value may either be set to '0' or * retained. * 2. Between line boxes inside a block container box. * 3. Between the content edge of a block container box and the * outer edges of its child content (margin edges of block-level * children or line box edges for inline-level children) if there * is a (non-zero) gap between them. * * These breaks are subject to the following rules: * * * Rule A: Breaking at (1) is allowed only if the * 'page-break-after' and 'page-break-before' properties of all * the elements generating boxes that meet at this margin allow * it, which is when at least one of them has the value * 'always', 'left', or 'right', or when all of them are 'auto'. * * * Rule B: However, if all of them are 'auto' and a common * ancestor of all the elements has a 'page-break-inside' value * of 'avoid', then breaking here is not allowed. * * * Rule C: Breaking at (2) is allowed only if the number of line * boxes between the break and the start of the enclosing block * box is the value of 'orphans' or more, and the number of line * boxes between the break and the end of the box is the value * of 'widows' or more. * * * Rule D: In addition, breaking at (2) or (3) is allowed only * if the 'page-break-inside' property of the element and all * its ancestors is 'auto'. * * If the above does not provide enough break points to keep content * from overflowing the page boxes, then rules A, B and D are * dropped in order to find additional breakpoints. * * If that still does not lead to sufficient break points, rule C is * dropped as well, to find still more break points. * * We also allow breaks between table rows. * * @param AbstractFrameDecorator $frame the frame to check * * @return bool true if a break is allowed, false otherwise */ protected function _page_break_allowed(Frame $frame) { Helpers::dompdf_debug("page-break", "_page_break_allowed(" . $frame->get_node()->nodeName . ")"); $display = $frame->get_style()->display; // Block Frames (1): if ($frame->is_block_level() || $display === "-dompdf-image") { // Avoid breaks within table-cells if ($this->_in_table > ($display === "table" ? 1 : 0)) { Helpers::dompdf_debug("page-break", "In table: " . $this->_in_table); return false; } // Rule A if ($frame->get_style()->page_break_before === "avoid") { Helpers::dompdf_debug("page-break", "before: avoid"); return false; } // Find the preceding block-level sibling. Inline elements are // treated as if wrapped in an anonymous block container here. See // https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level $prev = $frame->get_prev_sibling(); while ($prev && (($prev->is_text_node() && $prev->get_node()->nodeValue === "") || $prev->get_node()->nodeName === "bullet") ) { $prev = $prev->get_prev_sibling(); } // Does the previous element allow a page break after? if ($prev && ($prev->is_block_level() || $prev->get_style()->display === "-dompdf-image") && $prev->get_style()->page_break_after === "avoid" ) { Helpers::dompdf_debug("page-break", "after: avoid"); return false; } // Rules B & D $parent = $frame->get_parent(); $p = $parent; while ($p) { if ($p->get_style()->page_break_inside === "avoid") { Helpers::dompdf_debug("page-break", "parent->inside: avoid"); return false; } $p = $p->find_block_parent(); } // To prevent cascading page breaks when a top-level element has // page-break-inside: avoid, ensure that at least one frame is // on the page before splitting. if ($parent->get_node()->nodeName === "body" && !$prev) { // We are the body's first child Helpers::dompdf_debug("page-break", "Body's first child."); return false; } // Check for a possible type (3) break if (!$prev && $parent && !$this->hasGap($frame->get_position("y"), $parent)) { Helpers::dompdf_debug("page-break", "First block-level frame, no gap"); return false; } Helpers::dompdf_debug("page-break", "block: break allowed"); return true; } // Inline frames (2): else { if ($frame->is_inline_level()) { // Avoid breaks within table-cells if ($this->_in_table) { Helpers::dompdf_debug("page-break", "In table: " . $this->_in_table); return false; } // Rule C $block_parent = $frame->find_block_parent(); $parent_style = $block_parent->get_style(); $line = $block_parent->get_current_line_box(); $line_count = count($block_parent->get_line_boxes()); $line_number = $frame->get_containing_line() && empty($line->get_frames()) ? $line_count - 1 : $line_count; // The line number of the frame can be less than the current // number of line boxes, in case we are backtracking. As long as // we are not checking for widows yet, just checking against the // number of line boxes is sufficient in most cases, though. if ($line_number <= $parent_style->orphans) { Helpers::dompdf_debug("page-break", "orphans"); return false; } // FIXME: Checking widows is tricky without having laid out the // remaining line boxes. Just ignore it for now... // Rule D $p = $block_parent; while ($p) { if ($p->get_style()->page_break_inside === "avoid") { Helpers::dompdf_debug("page-break", "parent->inside: avoid"); return false; } $p = $p->find_block_parent(); } // To prevent cascading page breaks when a top-level element has // page-break-inside: avoid, ensure that at least one frame with // some content is on the page before splitting. $prev = $frame->get_prev_sibling(); while ($prev && ($prev->is_text_node() && trim($prev->get_node()->nodeValue) == "")) { $prev = $prev->get_prev_sibling(); } if ($block_parent->get_node()->nodeName === "body" && !$prev) { // We are the body's first child Helpers::dompdf_debug("page-break", "Body's first child."); return false; } Helpers::dompdf_debug("page-break", "inline: break allowed"); return true; // Table-rows } else { if ($display === "table-row") { // If this is a nested table, prevent the page from breaking if ($this->_in_table > 1) { Helpers::dompdf_debug("page-break", "table: nested table"); return false; } // Rule A (table row) if ($frame->get_style()->page_break_before === "avoid") { Helpers::dompdf_debug("page-break", "before: avoid"); return false; } // Find the preceding row $prev = $frame->get_prev_sibling(); if (!$prev) { $prev_group = $frame->get_parent()->get_prev_sibling(); if ($prev_group && in_array($prev_group->get_style()->display, Table::$ROW_GROUPS, true) ) { $prev = $prev_group->get_last_child(); } } // Check if a page break is allowed after the preceding row if ($prev && $prev->get_style()->page_break_after === "avoid") { Helpers::dompdf_debug("page-break", "after: avoid"); return false; } // Avoid breaking before the first row of a table if (!$prev) { Helpers::dompdf_debug("page-break", "table: first-row"); return false; } // Rule B (table row) // Check if the page_break_inside property is not 'avoid' // for the parent table or any of its ancestors $table = Table::find_parent_table($frame); $p = $table; while ($p) { if ($p->get_style()->page_break_inside === "avoid") { Helpers::dompdf_debug("page-break", "parent->inside: avoid"); return false; } $p = $p->find_block_parent(); } Helpers::dompdf_debug("page-break", "table-row: break allowed"); return true; } else { if (in_array($display, Table::$ROW_GROUPS, true)) { // Disallow breaks at row-groups: only split at row boundaries return false; } else { Helpers::dompdf_debug("page-break", "? " . $display); return false; } } } } } /** * Check if $frame will fit on the page. If the frame does not fit, * the frame tree is modified so that a page break occurs in the * correct location. * * @param AbstractFrameDecorator $frame the frame to check * * @return bool */ function check_page_break(Frame $frame) { if ($this->_page_full || $frame->_already_pushed // Never check for breaks on empty text nodes || ($frame->is_text_node() && $frame->get_node()->nodeValue === "") ) { return false; } $p = $frame; do { $display = $p->get_style()->display; if ($display == "table-row") { if ($p->_already_pushed) { return false; } } } while ($p = $p->get_parent()); // If the frame is absolute or fixed it shouldn't break $p = $frame; do { if ($p->is_absolute()) { return false; } } while ($p = $p->get_parent()); $margin_height = $frame->get_margin_height(); // Determine the frame's maximum y value $max_y = (float)$frame->get_position("y") + $margin_height; // If a split is to occur here, then the bottom margins & paddings of all // parents of $frame must fit on the page as well: $p = $frame->get_parent(); while ($p && $p !== $this) { $cbw = $p->get_containing_block("w"); $max_y += (float) $p->get_style()->computed_bottom_spacing($cbw); $p = $p->get_parent(); } // Check if $frame flows off the page if (Helpers::lengthLessOrEqual($max_y, $this->bottom_page_edge)) { // no: do nothing return false; } Helpers::dompdf_debug("page-break", "check_page_break"); Helpers::dompdf_debug("page-break", "in_table: " . $this->_in_table); // yes: determine page break location $iter = $frame; $flg = false; $pushed_flg = false; $in_table = $this->_in_table; Helpers::dompdf_debug("page-break", "Starting search"); while ($iter) { // echo "\nbacktrack: " .$iter->get_node()->nodeName ." ".spl_object_hash($iter->get_node()). ""; if ($iter === $this) { Helpers::dompdf_debug("page-break", "reached root."); // We've reached the root in our search. Just split at $frame. break; } if ($iter->_already_pushed) { $pushed_flg = true; } elseif ($this->_page_break_allowed($iter)) { Helpers::dompdf_debug("page-break", "break allowed, splitting."); $iter->split(null, true); $this->_page_full = true; $this->_in_table = $in_table; $iter->_already_pushed = true; $frame->_already_pushed = true; return true; } if (!$flg && $next = $iter->get_last_child()) { Helpers::dompdf_debug("page-break", "following last child."); if ($next->is_table()) { $this->_in_table++; } $iter = $next; $pushed_flg = false; continue; } if ($pushed_flg) { // The frame was already pushed, avoid breaking on a previous page break; } $next = $iter->get_prev_sibling(); // Skip empty text nodes while ($next && $next->is_text_node() && $next->get_node()->nodeValue === "") { $next = $next->get_prev_sibling(); } if ($next) { Helpers::dompdf_debug("page-break", "following prev sibling."); if ($next->is_table() && !$iter->is_table()) { $this->_in_table++; } else if (!$next->is_table() && $iter->is_table()) { $this->_in_table--; } $iter = $next; $flg = false; continue; } if ($next = $iter->get_parent()) { Helpers::dompdf_debug("page-break", "following parent."); if ($iter->is_table()) { $this->_in_table--; } $iter = $next; $flg = true; continue; } break; } $this->_in_table = $in_table; // No valid page break found. Just break at $frame. Helpers::dompdf_debug("page-break", "no valid break found, just splitting."); // If we are in a table, backtrack to the nearest top-level table row if ($this->_in_table) { $iter = $frame; while ($iter && $iter->get_style()->display !== "table-row" && $iter->get_style()->display !== 'table-row-group' && $iter->_already_pushed === false) { $iter = $iter->get_parent(); } if ($iter) { $iter->split(null, true); $iter->_already_pushed = true; } else { return false; } } else { $frame->split(null, true); } $this->_page_full = true; $frame->_already_pushed = true; return true; } //........................................................................ public function split(?Frame $child = null, bool $page_break = false, bool $forced = false): void { // Do nothing } /** * Add a floating frame * * @param Frame $frame * * @return void */ function add_floating_frame(Frame $frame) { array_unshift($this->_floating_frames, $frame); } /** * @return Frame[] */ function get_floating_frames() { return $this->_floating_frames; } /** * @param $key */ public function remove_floating_frame($key) { unset($this->_floating_frames[$key]); } /** * @param Frame $child * @return int|mixed */ public function get_lowest_float_offset(Frame $child) { $style = $child->get_style(); $side = $style->clear; $float = $style->float; $y = 0; if ($float === "none") { foreach ($this->_floating_frames as $key => $frame) { if ($side === "both" || $frame->get_style()->float === $side) { $y = max($y, $frame->get_position("y") + $frame->get_margin_height()); } $this->remove_floating_frame($key); } } if ($y > 0) { $y++; // add 1px buffer from float } return $y; } } PK!"ɛ҉--9convertformstools/pdf/dompdf/src/FrameDecorator/Table.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Cellmap; use DOMNode; use Dompdf\Css\Style; use Dompdf\Dompdf; use Dompdf\Frame; /** * Decorates Frames for table layout * * @package dompdf */ class Table extends AbstractFrameDecorator { public static $VALID_CHILDREN = Style::TABLE_INTERNAL_TYPES; public static $ROW_GROUPS = [ "table-row-group", "table-header-group", "table-footer-group" ]; /** * The Cellmap object for this table. The cellmap maps table cells * to rows and columns, and aids in calculating column widths. * * @var Cellmap */ protected $_cellmap; /** * The minimum width of the table, in pt * * @var float */ protected $_min_width; /** * The maximum width of the table, in pt * * @var float */ protected $_max_width; /** * Table header rows. Each table header is duplicated when a table * spans pages. * * @var TableRowGroup[] */ protected $_headers; /** * Table footer rows. Each table footer is duplicated when a table * spans pages. * * @var TableRowGroup[] */ protected $_footers; /** * Class constructor * * @param Frame $frame the frame to decorate * @param Dompdf $dompdf */ public function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); $this->_cellmap = new Cellmap($this); if ($frame->get_style()->table_layout === "fixed") { $this->_cellmap->set_layout_fixed(true); } $this->_min_width = null; $this->_max_width = null; $this->_headers = []; $this->_footers = []; } public function reset() { parent::reset(); $this->_cellmap->reset(); $this->_min_width = null; $this->_max_width = null; $this->_headers = []; $this->_footers = []; $this->_reflower->reset(); } //........................................................................ /** * Split the table at $row. $row and all subsequent rows will be * added to the clone. This method is overridden in order to remove * frames from the cellmap properly. */ public function split(?Frame $child = null, bool $page_break = false, bool $forced = false): void { if (is_null($child)) { parent::split($child, $page_break, $forced); return; } // If $child is a header or if it is the first non-header row, do // not duplicate headers, simply move the table to the next page. if (count($this->_headers) && !in_array($child, $this->_headers, true) && !in_array($child->get_prev_sibling(), $this->_headers, true) ) { $first_header = null; // Insert copies of the table headers before $child foreach ($this->_headers as $header) { $new_header = $header->deep_copy(); if (is_null($first_header)) { $first_header = $new_header; } $this->insert_child_before($new_header, $child); } parent::split($first_header, $page_break, $forced); } elseif (in_array($child->get_style()->display, self::$ROW_GROUPS, true)) { // Individual rows should have already been handled parent::split($child, $page_break, $forced); } else { $iter = $child; while ($iter) { $this->_cellmap->remove_row($iter); $iter = $iter->get_next_sibling(); } parent::split($child, $page_break, $forced); } } public function copy(DOMNode $node) { $deco = parent::copy($node); // In order to keep columns' widths through pages $deco->_cellmap->set_columns($this->_cellmap->get_columns()); $deco->_cellmap->lock_columns(); return $deco; } /** * Static function to locate the parent table of a frame * * @param Frame $frame * * @return Table the table that is an ancestor of $frame */ public static function find_parent_table(Frame $frame) { while ($frame = $frame->get_parent()) { if ($frame->is_table()) { break; } } return $frame; } /** * Return this table's Cellmap * * @return Cellmap */ public function get_cellmap() { return $this->_cellmap; } /** * Return the minimum width of this table * * @return float */ public function get_min_width() { return $this->_min_width; } /** * Return the maximum width of this table * * @return float */ public function get_max_width() { return $this->_max_width; } /** * Set the minimum width of the table * * @param float $width the new minimum width */ public function set_min_width($width) { $this->_min_width = $width; } /** * Set the maximum width of the table * * @param float $width the new maximum width */ public function set_max_width($width) { $this->_max_width = $width; } //........................................................................ /** * Check for text nodes between valid table children that only contain white * space, except if white space is to be preserved. * * @param AbstractFrameDecorator $frame * * @return bool */ private function isEmptyTextNode(AbstractFrameDecorator $frame): bool { // This is based on the white-space pattern in `FrameReflower\Text`, // i.e. only match on collapsible white space $wsPattern = '/^[^\S\xA0\x{202F}\x{2007}]*$/u'; $validChildOrNull = function ($frame) { return $frame === null || in_array($frame->get_style()->display, self::$VALID_CHILDREN, true); }; return $frame->is_text_node() && !$frame->is_pre() && preg_match($wsPattern, $frame->get_text()) && $validChildOrNull($frame->get_prev_sibling()) && $validChildOrNull($frame->get_next_sibling()); } /** * Restructure tree so that the table has the correct structure. Misplaced * children are appropriately wrapped in anonymous row groups, rows, and * cells. * * https://www.w3.org/TR/CSS21/tables.html#anonymous-boxes */ public function normalize(): void { $column_caption = ["table-column-group", "table-column", "table-caption"]; $children = iterator_to_array($this->get_children()); $tbody = null; foreach ($children as $child) { $display = $child->get_style()->display; if (in_array($display, self::$ROW_GROUPS, true)) { // Reset anonymous tbody $tbody = null; // Add headers and footers if ($display === "table-header-group") { $this->_headers[] = $child; } elseif ($display === "table-footer-group") { $this->_footers[] = $child; } continue; } if (in_array($display, $column_caption, true)) { continue; } // Remove empty text nodes between valid children if ($this->isEmptyTextNode($child)) { $this->remove_child($child); continue; } // Catch consecutive misplaced frames within a single anonymous group if ($tbody === null) { $tbody = $this->create_anonymous_child("tbody", "table-row-group"); $this->insert_child_before($tbody, $child); } $tbody->append_child($child); } // Handle empty table: Make sure there is at least one row group if (!$this->get_first_child()) { $tbody = $this->create_anonymous_child("tbody", "table-row-group"); $this->append_child($tbody); } foreach ($this->get_children() as $child) { $display = $child->get_style()->display; if (in_array($display, self::$ROW_GROUPS, true)) { $this->normalizeRowGroup($child); } } } private function normalizeRowGroup(AbstractFrameDecorator $frame): void { $children = iterator_to_array($frame->get_children()); $tr = null; foreach ($children as $child) { $display = $child->get_style()->display; if ($display === "table-row") { // Reset anonymous tr $tr = null; continue; } // Remove empty text nodes between valid children if ($this->isEmptyTextNode($child)) { $frame->remove_child($child); continue; } // Catch consecutive misplaced frames within a single anonymous row if ($tr === null) { $tr = $frame->create_anonymous_child("tr", "table-row"); $frame->insert_child_before($tr, $child); } $tr->append_child($child); } // Handle empty row group: Make sure there is at least one row if (!$frame->get_first_child()) { $tr = $frame->create_anonymous_child("tr", "table-row"); $frame->append_child($tr); } foreach ($frame->get_children() as $child) { $this->normalizeRow($child); } } private function normalizeRow(AbstractFrameDecorator $frame): void { $children = iterator_to_array($frame->get_children()); $td = null; foreach ($children as $child) { $display = $child->get_style()->display; if ($display === "table-cell") { // Reset anonymous td $td = null; continue; } // Remove empty text nodes between valid children if ($this->isEmptyTextNode($child)) { $frame->remove_child($child); continue; } // Catch consecutive misplaced frames within a single anonymous cell if ($td === null) { $td = $frame->create_anonymous_child("td", "table-cell"); $frame->insert_child_before($td, $child); } $td->append_child($child); } // Handle empty row: Make sure there is at least one cell if (!$frame->get_first_child()) { $td = $frame->create_anonymous_child("td", "table-cell"); $frame->append_child($td); } } //........................................................................ /** * @deprecated */ public function normalise() { $this->normalize(); } /** * Moves the specified frame and it's corresponding node outside of * the table. * * @deprecated * @param Frame $frame the frame to move */ public function move_after(Frame $frame) { $this->get_parent()->insert_child_after($frame, $this); } } PK!IN N Cconvertformstools/pdf/dompdf/src/FrameDecorator/ListBulletImage.phpnu[ * @author Helmut Tischer * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; use Dompdf\Helpers; use Dompdf\Image\Cache; /** * Decorates frames for list bullets with custom images * * @package dompdf */ class ListBulletImage extends ListBullet { /** * The underlying image frame * * @var Image */ protected $_img; /** * The image's width in pixels * * @var float */ protected $_width; /** * The image's height in pixels * * @var float */ protected $_height; /** * ListBulletImage constructor. * @param Frame $frame * @param Dompdf $dompdf */ function __construct(Frame $frame, Dompdf $dompdf) { $style = $frame->get_style(); $url = $style->list_style_image; $frame->get_node()->setAttribute("src", $url); $this->_img = new Image($frame, $dompdf); parent::__construct($this->_img, $dompdf); $url = $this->_img->get_image_url(); if (Cache::is_broken($url)) { $this->_width = parent::get_width(); $this->_height = parent::get_height(); } else { // Resample the bullet image to be consistent with 'auto' sized images [$width, $height] = $this->_img->get_intrinsic_dimensions(); $this->_width = $this->_img->resample($width); $this->_height = $this->_img->resample($height); } } public function get_width(): float { return $this->_width; } public function get_height(): float { return $this->_height; } public function get_margin_width(): float { $style = $this->get_style(); return $this->_width + $style->font_size * self::MARKER_INDENT; } public function get_margin_height(): float { $fontMetrics = $this->_dompdf->getFontMetrics(); $style = $this->get_style(); $font = $style->font_family; $size = $style->font_size; $fontHeight = $fontMetrics->getFontHeight($font, $size); $baseline = $fontMetrics->getFontBaseline($font, $size); // This is the same factor as used in // `FrameDecorator\Text::get_margin_height()` $f = $style->line_height / ($size > 0 ? $size : 1); // FIXME: Tries to approximate replacing the space above the font // baseline with the image return $f * ($fontHeight - $baseline) + $this->_height; } /** * Return image url * * @return string */ function get_image_url() { return $this->_img->get_image_url(); } } PK!KKM{{:convertformstools/pdf/dompdf/src/FrameDecorator/Inline.phpnu[ * @author Helmut Tischer * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; use Dompdf\Exception; /** * Decorates frames for inline layout * * @access private * @package dompdf */ class Inline extends AbstractFrameDecorator { /** * Inline constructor. * @param Frame $frame * @param Dompdf $dompdf */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); } /** * Vertical padding, border, and margin do not apply when determining the * height for inline frames. * * http://www.w3.org/TR/CSS21/visudet.html#inline-non-replaced * * The vertical padding, border and margin of an inline, non-replaced box * start at the top and bottom of the content area, not the * 'line-height'. But only the 'line-height' is used to calculate the * height of the line box. * * @return float */ public function get_margin_height(): float { $style = $this->get_style(); $font = $style->font_family; $size = $style->font_size; $fontHeight = $this->_dompdf->getFontMetrics()->getFontHeight($font, $size); return ($style->line_height / ($size > 0 ? $size : 1)) * $fontHeight; } public function split(?Frame $child = null, bool $page_break = false, bool $forced = false): void { if (is_null($child)) { $this->get_parent()->split($this, $page_break, $forced); return; } if ($child->get_parent() !== $this) { throw new Exception("Unable to split: frame is not a child of this one."); } $this->revert_counter_increment(); $node = $this->_frame->get_node(); $split = $this->copy($node->cloneNode()); // if this is a generated node don't propagate the content style if ($split->get_node()->nodeName == "dompdf_generated") { $split->get_style()->content = "normal"; } $this->get_parent()->insert_child_after($split, $this); // Unset the current node's right style properties $style = $this->_frame->get_style(); $style->margin_right = 0; $style->padding_right = 0; $style->border_right_width = 0; // Unset the split node's left style properties since we don't want them // to propagate $style = $split->get_style(); $style->margin_left = 0; $style->padding_left = 0; $style->border_left_width = 0; //On continuation of inline element on next line, //don't repeat non-vertically repeatable background images //See e.g. in testcase image_variants, long descriptions if (($url = $style->background_image) && $url !== "none" && ($repeat = $style->background_repeat) && $repeat !== "repeat" && $repeat !== "repeat-y" ) { $style->background_image = "none"; } // Add $child and all following siblings to the new split node $iter = $child; while ($iter) { $frame = $iter; $iter = $iter->get_next_sibling(); $frame->reset(); $split->append_child($frame); } $parent = $this->get_parent(); if ($page_break) { $parent->split($split, $page_break, $forced); } elseif ($parent instanceof Inline) { $parent->split($split); } } } PK!5R R >convertformstools/pdf/dompdf/src/FrameDecorator/ListBullet.phpnu[ * @author Helmut Tischer * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; /** * Decorates frames for list bullet rendering * * @package dompdf */ class ListBullet extends AbstractFrameDecorator { /** * Bullet diameter as fraction of font size. */ public const BULLET_SIZE = 0.35; /** * Bullet offset from font baseline as fraction of font size. */ public const BULLET_OFFSET = 0.1; /** * Thickness of bullet outline as fraction of font size. * See also `DECO_THICKNESS`. Screen: 0.08, print: better less, e.g. 0.04. */ public const BULLET_THICKNESS = 0.04; /** * Indentation from the start of the line as fraction of font size. */ public const MARKER_INDENT = 0.52; /** * @deprecated */ const BULLET_PADDING = 1; /** * @deprecated */ const BULLET_DESCENT = 0.3; /** * @deprecated */ static $BULLET_TYPES = ["disc", "circle", "square"]; /** * ListBullet constructor. * @param Frame $frame * @param Dompdf $dompdf */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); } /** * Get the width of the bullet symbol. * * @return float */ public function get_width(): float { $style = $this->_frame->get_style(); if ($style->list_style_type === "none") { return 0.0; } return $style->font_size * self::BULLET_SIZE; } /** * Get the height of the bullet symbol. * * @return float */ public function get_height(): float { $style = $this->_frame->get_style(); if ($style->list_style_type === "none") { return 0.0; } return $style->font_size * self::BULLET_SIZE; } /** * Get the width of the bullet, including indentation. */ public function get_margin_width(): float { $style = $this->get_style(); if ($style->list_style_type === "none") { return 0.0; } return $style->font_size * (self::BULLET_SIZE + self::MARKER_INDENT); } /** * Get the line height for the bullet. * * This increases the height of the corresponding line box when necessary. */ public function get_margin_height(): float { $style = $this->get_style(); if ($style->list_style_type === "none") { return 0.0; } // TODO: This is a copy of `FrameDecorator\Text::get_margin_height()` // Would be nice to properly refactor that at some point $font = $style->font_family; $size = $style->font_size; $fontHeight = $this->_dompdf->getFontMetrics()->getFontHeight($font, $size); return ($style->line_height / ($size > 0 ? $size : 1)) * $fontHeight; } } PK!PLL8convertformstools/pdf/dompdf/src/FrameDecorator/Text.phpnu[ * @author Brian Sweeney * @author Fabien Ménager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; use Dompdf\Exception; /** * Decorates Frame objects for text layout * * @access private * @package dompdf */ class Text extends AbstractFrameDecorator { /** * @var float|null */ protected $_text_spacing; /** * Text constructor. * @param Frame $frame * @param Dompdf $dompdf * @throws Exception */ function __construct(Frame $frame, Dompdf $dompdf) { if (!$frame->is_text_node()) { throw new Exception("Text_Decorator can only be applied to #text nodes."); } parent::__construct($frame, $dompdf); $this->_text_spacing = null; } function reset() { parent::reset(); $this->_text_spacing = null; } // Accessor methods /** * @return float|null */ function get_text_spacing() { return $this->_text_spacing; } /** * @return string */ function get_text() { // FIXME: this should be in a child class (and is incorrect) // if ( $this->_frame->get_style()->content !== "normal" ) { // $this->_frame->get_node()->data = $this->_frame->get_style()->content; // $this->_frame->get_style()->content = "normal"; // } // Helpers::pre_r("---"); // $style = $this->_frame->get_style(); // var_dump($text = $this->_frame->get_node()->data); // var_dump($asc = utf8_decode($text)); // for ($i = 0; $i < strlen($asc); $i++) // Helpers::pre_r("$i: " . $asc[$i] . " - " . ord($asc[$i])); // Helpers::pre_r("width: " . $this->_dompdf->getFontMetrics()->getTextWidth($text, $style->font_family, $style->font_size)); return $this->_frame->get_node()->data; } //........................................................................ /** * Vertical padding, border, and margin do not apply when determining the * height for inline frames. * * http://www.w3.org/TR/CSS21/visudet.html#inline-non-replaced * * The vertical padding, border and margin of an inline, non-replaced box * start at the top and bottom of the content area, not the * 'line-height'. But only the 'line-height' is used to calculate the * height of the line box. * * @return float */ public function get_margin_height(): float { // This function is also called in add_frame_to_line() and is used to // determine the line height $style = $this->get_style(); $font = $style->font_family; $size = $style->font_size; $fontHeight = $this->_dompdf->getFontMetrics()->getFontHeight($font, $size); return ($style->line_height / ($size > 0 ? $size : 1)) * $fontHeight; } public function get_padding_box(): array { $style = $this->_frame->get_style(); $pb = $this->_frame->get_padding_box(); $pb[3] = $pb["h"] = (float) $style->length_in_pt($style->height); return $pb; } /** * @param float $spacing */ function set_text_spacing($spacing) { $style = $this->_frame->get_style(); $this->_text_spacing = $spacing; $char_spacing = (float)$style->length_in_pt($style->letter_spacing); // Re-adjust our width to account for the change in spacing $style->width = $this->_dompdf->getFontMetrics()->getTextWidth($this->get_text(), $style->font_family, $style->font_size, $spacing, $char_spacing); } /** * Recalculate the text width * * @return float */ function recalculate_width() { $style = $this->get_style(); $text = $this->get_text(); $size = $style->font_size; $font = $style->font_family; $word_spacing = (float)$style->length_in_pt($style->word_spacing); $char_spacing = (float)$style->length_in_pt($style->letter_spacing); return $style->width = $this->_dompdf->getFontMetrics()->getTextWidth($text, $font, $size, $word_spacing, $char_spacing); } // Text manipulation methods /** * Split the text in this frame at the offset specified. The remaining * text is added as a sibling frame following this one and is returned. * * @param int $offset * @return Frame|null */ function split_text($offset) { if ($offset == 0) { return null; } $split = $this->_frame->get_node()->splitText($offset); if ($split === false) { return null; } $deco = $this->copy($split); $p = $this->get_parent(); $p->insert_child_after($deco, $this, false); if ($p instanceof Inline) { $p->split($deco); } return $deco; } /** * @param int $offset * @param int $count */ function delete_text($offset, $count) { $this->_frame->get_node()->deleteData($offset, $count); } /** * @param string $text */ function set_text($text) { $this->_frame->get_node()->data = $text; } } PK!$̋<convertformstools/pdf/dompdf/src/FrameDecorator/TableRow.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; use Dompdf\FrameDecorator\Table as TableFrameDecorator; /** * Decorates Frames for table row layout * * @package dompdf */ class TableRow extends AbstractFrameDecorator { /** * TableRow constructor. * @param Frame $frame * @param Dompdf $dompdf */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); } //........................................................................ /** * Remove all non table-cell frames from this row and move them after * the table. * * @deprecated */ function normalise() { // Find our table parent $p = TableFrameDecorator::find_parent_table($this); $erroneous_frames = []; foreach ($this->get_children() as $child) { $display = $child->get_style()->display; if ($display !== "table-cell") { $erroneous_frames[] = $child; } } // dump the extra nodes after the table. foreach ($erroneous_frames as $frame) { $p->move_after($frame); } } } PK!k#9convertformstools/pdf/dompdf/src/FrameDecorator/Block.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; use Dompdf\LineBox; /** * Decorates frames for block layout * * @access private * @package dompdf */ class Block extends AbstractFrameDecorator { /** * Current line index * * @var int */ protected $_cl; /** * The block's line boxes * * @var LineBox[] */ protected $_line_boxes; /** * List of markers that have not found their line box to vertically align * with yet. Markers are collected by nested block containers until an * inline line box is found at the start of the block. * * @var ListBullet[] */ protected $dangling_markers; /** * Block constructor. * @param Frame $frame * @param Dompdf $dompdf */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); $this->_line_boxes = [new LineBox($this)]; $this->_cl = 0; $this->dangling_markers = []; } function reset() { parent::reset(); $this->_line_boxes = [new LineBox($this)]; $this->_cl = 0; $this->dangling_markers = []; } /** * @return LineBox */ function get_current_line_box() { return $this->_line_boxes[$this->_cl]; } /** * @return int */ function get_current_line_number() { return $this->_cl; } /** * @return LineBox[] */ function get_line_boxes() { return $this->_line_boxes; } /** * @param int $line_number * @return int */ function set_current_line_number($line_number) { $line_boxes_count = count($this->_line_boxes); $cl = max(min($line_number, $line_boxes_count), 0); return ($this->_cl = $cl); } /** * @param int $i */ function clear_line($i) { if (isset($this->_line_boxes[$i])) { unset($this->_line_boxes[$i]); } } /** * @param Frame $frame * @return LineBox|null */ public function add_frame_to_line(Frame $frame) { $current_line = $this->_line_boxes[$this->_cl]; $frame->set_containing_line($current_line); // Inline frames are currently treated as wrappers, and are not actually // added to the line if ($frame instanceof Inline) { return null; } $current_line->add_frame($frame); $this->increase_line_width($frame->get_margin_width()); $this->maximize_line_height($frame->get_margin_height(), $frame); // Add any dangling list markers to the first line box if it is inline if ($this->_cl === 0 && $current_line->inline && $this->dangling_markers !== [] ) { foreach ($this->dangling_markers as $marker) { $current_line->add_list_marker($marker); $this->maximize_line_height($marker->get_margin_height(), $marker); } $this->dangling_markers = []; } return $current_line; } /** * Remove the given frame and all following frames and lines from the block. * * @param Frame $frame */ public function remove_frames_from_line(Frame $frame): void { // Inline frames are not added to line boxes themselves, only their // text frame children $actualFrame = $frame; while ($actualFrame !== null && $actualFrame instanceof Inline) { $actualFrame = $actualFrame->get_first_child(); } if ($actualFrame === null) { return; } // Search backwards through the lines for $frame $frame = $actualFrame; $i = $this->_cl; $j = null; while ($i > 0) { $line = $this->_line_boxes[$i]; foreach ($line->get_frames() as $index => $f) { if ($frame === $f) { $j = $index; break 2; } } $i--; } if ($j === null) { return; } // Remove all lines that follow for ($k = $this->_cl; $k > $i; $k--) { unset($this->_line_boxes[$k]); } // Remove the line, if it is empty if ($j > 0) { $line->remove_frames($j); } else { unset($this->_line_boxes[$i]); } // Reset array indices $this->_line_boxes = array_values($this->_line_boxes); $this->_cl = count($this->_line_boxes) - 1; } /** * @param float $w */ function increase_line_width($w) { $this->_line_boxes[$this->_cl]->w += $w; } /** * @param float $val * @param Frame $frame */ function maximize_line_height($val, Frame $frame) { if ($val > $this->_line_boxes[$this->_cl]->h) { $this->_line_boxes[$this->_cl]->tallest_frame = $frame; $this->_line_boxes[$this->_cl]->h = $val; } } /** * @param bool $br */ function add_line(bool $br = false) { $line = $this->_line_boxes[$this->_cl]; $line->br = $br; $y = $line->y + $line->h; $new_line = new LineBox($this, $y); $this->_line_boxes[++$this->_cl] = $new_line; } /** * @param ListBullet $marker */ public function add_dangling_marker(ListBullet $marker): void { $this->dangling_markers[] = $marker; } /** * Inherit any dangling markers from the parent block. * * @param Block $block */ public function inherit_dangling_markers(self $block): void { if ($block->dangling_markers !== []) { $this->dangling_markers = $block->dangling_markers; $block->dangling_markers = []; } } } PK!aZ\ \ =convertformstools/pdf/dompdf/src/FrameDecorator/TableCell.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; use Dompdf\FrameDecorator\Block as BlockFrameDecorator; /** * Decorates table cells for layout * * @package dompdf */ class TableCell extends BlockFrameDecorator { protected $_resolved_borders; protected $_content_height; //........................................................................ /** * TableCell constructor. * @param Frame $frame * @param Dompdf $dompdf */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); $this->_resolved_borders = []; $this->_content_height = 0; } //........................................................................ function reset() { parent::reset(); $this->_resolved_borders = []; $this->_content_height = 0; $this->_frame->reset(); } /** * @return int */ function get_content_height() { return $this->_content_height; } /** * @param $height */ function set_content_height($height) { $this->_content_height = $height; } /** * @param $height */ function set_cell_height($height) { $style = $this->get_style(); $v_space = (float)$style->length_in_pt( [ $style->margin_top, $style->padding_top, $style->border_top_width, $style->border_bottom_width, $style->padding_bottom, $style->margin_bottom ], (float)$style->length_in_pt($style->height) ); $new_height = $height - $v_space; $style->height = $new_height; if ($new_height > $this->_content_height) { $y_offset = 0; // Adjust our vertical alignment switch ($style->vertical_align) { default: case "baseline": // FIXME: this isn't right case "top": // Don't need to do anything return; case "middle": $y_offset = ($new_height - $this->_content_height) / 2; break; case "bottom": $y_offset = $new_height - $this->_content_height; break; } if ($y_offset) { // Move our children foreach ($this->get_line_boxes() as $line) { foreach ($line->get_frames() as $frame) { $frame->move(0, $y_offset); } } } } } /** * @param $side * @param $border_spec */ function set_resolved_border($side, $border_spec) { $this->_resolved_borders[$side] = $border_spec; } /** * @param $side * @return mixed */ function get_resolved_border($side) { return $this->_resolved_borders[$side]; } /** * @return array */ function get_resolved_borders() { return $this->_resolved_borders; } } PK!Bdw 9convertformstools/pdf/dompdf/src/FrameDecorator/Image.phpnu[ * @author Fabien Ménager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\FrameDecorator; use Dompdf\Dompdf; use Dompdf\Frame; use Dompdf\Helpers; use Dompdf\Image\Cache; /** * Decorates frames for image layout and rendering * * @package dompdf */ class Image extends AbstractFrameDecorator { /** * The path to the image file (note that remote images are * downloaded locally to Options:tempDir). * * @var string */ protected $_image_url; /** * The image's file error message * * @var string */ protected $_image_msg; /** * Class constructor * * @param Frame $frame the frame to decorate * @param DOMPDF $dompdf the document's dompdf object (required to resolve relative & remote urls) */ function __construct(Frame $frame, Dompdf $dompdf) { parent::__construct($frame, $dompdf); $url = $frame->get_node()->getAttribute("src"); $debug_png = $dompdf->getOptions()->getDebugPng(); if ($debug_png) { print '[__construct ' . $url . ']'; } list($this->_image_url, /*$type*/, $this->_image_msg) = Cache::resolve_url( $url, $dompdf->getProtocol(), $dompdf->getBaseHost(), $dompdf->getBasePath(), $dompdf ); if (Cache::is_broken($this->_image_url) && $alt = $frame->get_node()->getAttribute("alt") ) { $style = $frame->get_style(); $style->width = (4 / 3) * $dompdf->getFontMetrics()->getTextWidth($alt, $style->font_family, $style->font_size, $style->word_spacing); $style->height = $dompdf->getFontMetrics()->getFontHeight($style->font_family, $style->font_size); } } /** * Get the intrinsic pixel dimensions of the image. * * @return array Width and height as `float|int`. */ public function get_intrinsic_dimensions(): array { [$width, $height] = Helpers::dompdf_getimagesize($this->_image_url, $this->_dompdf->getHttpContext()); return [$width, $height]; } /** * Resample the given pixel length according to dpi. * * @param float|int $length * @return float */ public function resample($length): float { $dpi = $this->_dompdf->getOptions()->getDpi(); return ($length * 72) / $dpi; } /** * Return the image's url * * @return string The url of this image */ function get_image_url() { return $this->_image_url; } /** * Return the image's error message * * @return string The image's error message */ function get_image_msg() { return $this->_image_msg; } } PK!E@dd,convertformstools/pdf/dompdf/src/Helpers.phpnu[ tags if the current sapi is not 'cli'. * Returns the output string instead of displaying it if $return is true. * * @param mixed $mixed variable or expression to display * @param bool $return * * @return string|null */ public static function pre_r($mixed, $return = false) { if ($return) { return "
    " . print_r($mixed, true) . "
    "; } if (php_sapi_name() !== "cli") { echo "
    ";
            }
    
            print_r($mixed);
    
            if (php_sapi_name() !== "cli") {
                echo "
    "; } else { echo "\n"; } flush(); return null; } /** * builds a full url given a protocol, hostname, base path and url * * @param string $protocol * @param string $host * @param string $base_path * @param string $url * @return string * * Initially the trailing slash of $base_path was optional, and conditionally appended. * However on dynamically created sites, where the page is given as url parameter, * the base path might not end with an url. * Therefore do not append a slash, and **require** the $base_url to ending in a slash * when needed. * Vice versa, on using the local file system path of a file, make sure that the slash * is appended (o.k. also for Windows) */ public static function build_url($protocol, $host, $base_path, $url) { $protocol = mb_strtolower($protocol); if ($url === "") { //return $protocol . $host . rtrim($base_path, "/\\") . "/"; return $protocol . $host . $base_path; } // Is the url already fully qualified, a Data URI, or a reference to a named anchor? // File-protocol URLs may require additional processing (e.g. for URLs with a relative path) if ((mb_strpos($url, "://") !== false && substr($url, 0, 7) !== "file://") || mb_substr($url, 0, 1) === "#" || mb_strpos($url, "data:") === 0 || mb_strpos($url, "mailto:") === 0 || mb_strpos($url, "tel:") === 0) { return $url; } if (strpos($url, "file://") === 0) { $url = substr($url, 7); $protocol = ""; } $ret = ""; if ($protocol !== "file://") { $ret = $protocol; } if (!in_array(mb_strtolower($protocol), ["http://", "https://", "ftp://", "ftps://"], true)) { //On Windows local file, an abs path can begin also with a '\' or a drive letter and colon //drive: followed by a relative path would be a drive specific default folder. //not known in php app code, treat as abs path //($url[1] !== ':' || ($url[2]!=='\\' && $url[2]!=='/')) if ($url[0] !== '/' && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' || (mb_strlen($url) > 1 && $url[0] !== '\\' && $url[1] !== ':'))) { // For rel path and local access we ignore the host, and run the path through realpath() $ret .= realpath($base_path) . '/'; } $ret .= $url; $ret = preg_replace('/\?(.*)$/', "", $ret); return $ret; } // Protocol relative urls (e.g. "//example.org/style.css") if (strpos($url, '//') === 0) { $ret .= substr($url, 2); //remote urls with backslash in html/css are not really correct, but lets be genereous } elseif ($url[0] === '/' || $url[0] === '\\') { // Absolute path $ret .= $host . $url; } else { // Relative path //$base_path = $base_path !== "" ? rtrim($base_path, "/\\") . "/" : ""; $ret .= $host . $base_path . $url; } // URL should now be complete, final cleanup $parsed_url = parse_url($ret); // reproduced from https://www.php.net/manual/en/function.parse-url.php#106731 $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; $user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; $pass = ($user || $pass) ? "$pass@" : ''; $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; // partially reproduced from https://stackoverflow.com/a/1243431/264628 /* replace '//' or '/./' or '/foo/../' with '/' */ $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'); for ($n=1; $n>0; $path=preg_replace($re, '/', $path, -1, $n)) {} $ret = "$scheme$user$pass$host$port$path$query$fragment"; return $ret; } /** * Builds a HTTP Content-Disposition header string using `$dispositionType` * and `$filename`. * * If the filename contains any characters not in the ISO-8859-1 character * set, a fallback filename will be included for clients not supporting the * `filename*` parameter. * * @param string $dispositionType * @param string $filename * @return string */ public static function buildContentDispositionHeader($dispositionType, $filename) { $encoding = mb_detect_encoding($filename); $fallbackfilename = mb_convert_encoding($filename, "ISO-8859-1", $encoding); $fallbackfilename = str_replace("\"", "", $fallbackfilename); $encodedfilename = rawurlencode($filename); $contentDisposition = "Content-Disposition: $dispositionType; filename=\"$fallbackfilename\""; if ($fallbackfilename !== $filename) { $contentDisposition .= "; filename*=UTF-8''$encodedfilename"; } return $contentDisposition; } /** * Converts decimal numbers to roman numerals. * * As numbers larger than 3999 (and smaller than 1) cannot be represented in * the standard form of roman numerals, those are left in decimal form. * * See https://en.wikipedia.org/wiki/Roman_numerals#Standard_form * * @param int|string $num * * @throws Exception * @return string */ public static function dec2roman($num): string { static $ones = ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"]; static $tens = ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"]; static $hund = ["", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"]; static $thou = ["", "m", "mm", "mmm"]; if (!is_numeric($num)) { throw new Exception("dec2roman() requires a numeric argument."); } if ($num >= 4000 || $num <= 0) { return (string) $num; } $num = strrev((string)$num); $ret = ""; switch (mb_strlen($num)) { /** @noinspection PhpMissingBreakStatementInspection */ case 4: $ret .= $thou[$num[3]]; /** @noinspection PhpMissingBreakStatementInspection */ case 3: $ret .= $hund[$num[2]]; /** @noinspection PhpMissingBreakStatementInspection */ case 2: $ret .= $tens[$num[1]]; /** @noinspection PhpMissingBreakStatementInspection */ case 1: $ret .= $ones[$num[0]]; default: break; } return $ret; } /** * Restrict a length to the given range. * * If min > max, the result is min. * * @param float $length * @param float $min * @param float $max * * @return float */ public static function clamp(float $length, float $min, float $max): float { return max($min, min($length, $max)); } /** * Determines whether $value is a percentage or not * * @param string|float|int $value * * @return bool */ public static function is_percent($value): bool { return is_string($value) && false !== mb_strpos($value, "%"); } /** * Parses a data URI scheme * http://en.wikipedia.org/wiki/Data_URI_scheme * * @param string $data_uri The data URI to parse * * @return array|bool The result with charset, mime type and decoded data */ public static function parse_data_uri($data_uri) { if (!preg_match('/^data:(?P[a-z0-9\/+-.]+)(;charset=(?P[a-z0-9-])+)?(?P;base64)?\,(?P.*)?/is', $data_uri, $match)) { return false; } $match['data'] = rawurldecode($match['data']); $result = [ 'charset' => $match['charset'] ? $match['charset'] : 'US-ASCII', 'mime' => $match['mime'] ? $match['mime'] : 'text/plain', 'data' => $match['base64'] ? base64_decode($match['data']) : $match['data'], ]; return $result; } /** * Encodes a Uniform Resource Identifier (URI) by replacing non-alphanumeric * characters with a percent (%) sign followed by two hex digits, excepting * characters in the URI reserved character set. * * Assumes that the URI is a complete URI, so does not encode reserved * characters that have special meaning in the URI. * * Simulates the encodeURI function available in JavaScript * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURI * * Source: http://stackoverflow.com/q/4929584/264628 * * @param string $uri The URI to encode * @return string The original URL with special characters encoded */ public static function encodeURI($uri) { $unescaped = [ '%2D'=>'-','%5F'=>'_','%2E'=>'.','%21'=>'!', '%7E'=>'~', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')' ]; $reserved = [ '%3B'=>';','%2C'=>',','%2F'=>'/','%3F'=>'?','%3A'=>':', '%40'=>'@','%26'=>'&','%3D'=>'=','%2B'=>'+','%24'=>'$' ]; $score = [ '%23'=>'#' ]; return strtr(rawurlencode(rawurldecode($uri)), array_merge($reserved, $unescaped, $score)); } /** * Decoder for RLE8 compression in windows bitmaps * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp * * @param string $str Data to decode * @param int $width Image width * * @return string */ public static function rle8_decode($str, $width) { $lineWidth = $width + (3 - ($width - 1) % 4); $out = ''; $cnt = strlen($str); for ($i = 0; $i < $cnt; $i++) { $o = ord($str[$i]); switch ($o) { case 0: # ESCAPE $i++; switch (ord($str[$i])) { case 0: # NEW LINE $padCnt = $lineWidth - strlen($out) % $lineWidth; if ($padCnt < $lineWidth) { $out .= str_repeat(chr(0), $padCnt); # pad line } break; case 1: # END OF FILE $padCnt = $lineWidth - strlen($out) % $lineWidth; if ($padCnt < $lineWidth) { $out .= str_repeat(chr(0), $padCnt); # pad line } break 3; case 2: # DELTA $i += 2; break; default: # ABSOLUTE MODE $num = ord($str[$i]); for ($j = 0; $j < $num; $j++) { $out .= $str[++$i]; } if ($num % 2) { $i++; } } break; default: $out .= str_repeat($str[++$i], $o); } } return $out; } /** * Decoder for RLE4 compression in windows bitmaps * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp * * @param string $str Data to decode * @param int $width Image width * * @return string */ public static function rle4_decode($str, $width) { $w = floor($width / 2) + ($width % 2); $lineWidth = $w + (3 - (($width - 1) / 2) % 4); $pixels = []; $cnt = strlen($str); $c = 0; for ($i = 0; $i < $cnt; $i++) { $o = ord($str[$i]); switch ($o) { case 0: # ESCAPE $i++; switch (ord($str[$i])) { case 0: # NEW LINE while (count($pixels) % $lineWidth != 0) { $pixels[] = 0; } break; case 1: # END OF FILE while (count($pixels) % $lineWidth != 0) { $pixels[] = 0; } break 3; case 2: # DELTA $i += 2; break; default: # ABSOLUTE MODE $num = ord($str[$i]); for ($j = 0; $j < $num; $j++) { if ($j % 2 == 0) { $c = ord($str[++$i]); $pixels[] = ($c & 240) >> 4; } else { $pixels[] = $c & 15; } } if ($num % 2 == 0) { $i++; } } break; default: $c = ord($str[++$i]); for ($j = 0; $j < $o; $j++) { $pixels[] = ($j % 2 == 0 ? ($c & 240) >> 4 : $c & 15); } } } $out = ''; if (count($pixels) % 2) { $pixels[] = 0; } $cnt = count($pixels) / 2; for ($i = 0; $i < $cnt; $i++) { $out .= chr(16 * $pixels[2 * $i] + $pixels[2 * $i + 1]); } return $out; } /** * parse a full url or pathname and return an array(protocol, host, path, * file + query + fragment) * * @param string $url * @return array */ public static function explode_url($url) { $protocol = ""; $host = ""; $path = ""; $file = ""; $arr = parse_url($url); if ( isset($arr["scheme"]) ) { $arr["scheme"] = mb_strtolower($arr["scheme"]); } // Exclude windows drive letters... if (isset($arr["scheme"]) && $arr["scheme"] !== "file" && strlen($arr["scheme"]) > 1) { $protocol = $arr["scheme"] . "://"; if (isset($arr["user"])) { $host .= $arr["user"]; if (isset($arr["pass"])) { $host .= ":" . $arr["pass"]; } $host .= "@"; } if (isset($arr["host"])) { $host .= $arr["host"]; } if (isset($arr["port"])) { $host .= ":" . $arr["port"]; } if (isset($arr["path"]) && $arr["path"] !== "") { // Do we have a trailing slash? if ($arr["path"][mb_strlen($arr["path"]) - 1] === "/") { $path = $arr["path"]; $file = ""; } else { $path = rtrim(dirname($arr["path"]), '/\\') . "/"; $file = basename($arr["path"]); } } if (isset($arr["query"])) { $file .= "?" . $arr["query"]; } if (isset($arr["fragment"])) { $file .= "#" . $arr["fragment"]; } } else { $i = mb_stripos($url, "file://"); if ($i !== false) { $url = mb_substr($url, $i + 7); } $protocol = ""; // "file://"; ? why doesn't this work... It's because of // network filenames like //COMPU/SHARENAME $host = ""; // localhost, really $file = basename($url); $path = dirname($url); // Check that the path exists if ($path !== false) { $path .= '/'; } else { // generate a url to access the file if no real path found. $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://'; $host = isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : php_uname("n"); if (substr($arr["path"], 0, 1) === '/') { $path = dirname($arr["path"]); } else { $path = '/' . rtrim(dirname($_SERVER["SCRIPT_NAME"]), '/') . '/' . $arr["path"]; } } } $ret = [$protocol, $host, $path, $file, "protocol" => $protocol, "host" => $host, "path" => $path, "file" => $file]; return $ret; } /** * Print debug messages * * @param string $type The type of debug messages to print * @param string $msg The message to show */ public static function dompdf_debug($type, $msg) { global $_DOMPDF_DEBUG_TYPES, $_dompdf_show_warnings, $_dompdf_debug; if (isset($_DOMPDF_DEBUG_TYPES[$type]) && ($_dompdf_show_warnings || $_dompdf_debug)) { $arr = debug_backtrace(); echo basename($arr[0]["file"]) . " (" . $arr[0]["line"] . "): " . $arr[1]["function"] . ": "; Helpers::pre_r($msg); } } /** * Stores warnings in an array for display later * This function allows warnings generated by the DomDocument parser * and CSS loader ({@link Stylesheet}) to be captured and displayed * later. Without this function, errors are displayed immediately and * PDF streaming is impossible. * @see http://www.php.net/manual/en/function.set-error_handler.php * * @param int $errno * @param string $errstr * @param string $errfile * @param string $errline * * @throws Exception */ public static function record_warnings($errno, $errstr, $errfile, $errline) { // Not a warning or notice if (!($errno & (E_WARNING | E_NOTICE | E_USER_NOTICE | E_USER_WARNING | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED))) { throw new Exception($errstr . " $errno"); } global $_dompdf_warnings; global $_dompdf_show_warnings; if ($_dompdf_show_warnings) { echo $errstr . "\n"; } $_dompdf_warnings[] = $errstr; } /** * @param $c * @return bool|string */ public static function unichr($c) { if ($c <= 0x7F) { return chr($c); } else if ($c <= 0x7FF) { return chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F); } else if ($c <= 0xFFFF) { return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F) . chr(0x80 | $c & 0x3F); } else if ($c <= 0x10FFFF) { return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F) . chr(0x80 | $c >> 6 & 0x3F) . chr(0x80 | $c & 0x3F); } return false; } /** * Converts a CMYK color to RGB * * @param float|float[] $c * @param float $m * @param float $y * @param float $k * * @return float[] */ public static function cmyk_to_rgb($c, $m = null, $y = null, $k = null) { if (is_array($c)) { [$c, $m, $y, $k] = $c; } $c *= 255; $m *= 255; $y *= 255; $k *= 255; $r = (1 - round(2.55 * ($c + $k))); $g = (1 - round(2.55 * ($m + $k))); $b = (1 - round(2.55 * ($y + $k))); if ($r < 0) { $r = 0; } if ($g < 0) { $g = 0; } if ($b < 0) { $b = 0; } return [ $r, $g, $b, "r" => $r, "g" => $g, "b" => $b ]; } /** * getimagesize doesn't give a good size for 32bit BMP image v5 * * @param string $filename * @param resource $context * @return array An array of three elements: width and height as * `float|int`, and image type as `string|null`. */ public static function dompdf_getimagesize($filename, $context = null) { static $cache = []; if (isset($cache[$filename])) { return $cache[$filename]; } [$width, $height, $type] = getimagesize($filename); // Custom types $types = [ IMAGETYPE_JPEG => "jpeg", IMAGETYPE_GIF => "gif", IMAGETYPE_BMP => "bmp", IMAGETYPE_PNG => "png", IMAGETYPE_WEBP => "webp", ]; $type = $types[$type] ?? null; if ($width == null || $height == null) { [$data] = Helpers::getFileContent($filename, $context); if ($data !== null) { if (substr($data, 0, 2) === "BM") { $meta = unpack("vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight", $data); $width = (int) $meta["width"]; $height = (int) $meta["height"]; $type = "bmp"; } elseif (strpos($data, "loadFile($filename); [$width, $height] = $doc->getDimensions(); $width = (float) $width; $height = (float) $height; $type = "svg"; } } } return $cache[$filename] = [$width ?? 0, $height ?? 0, $type]; } /** * Credit goes to mgutt * http://www.programmierer-forum.de/function-imagecreatefrombmp-welche-variante-laeuft-t143137.htm * Modified by Fabien Menager to support RGB555 BMP format */ public static function imagecreatefrombmp($filename, $context = null) { if (!function_exists("imagecreatetruecolor")) { trigger_error("The PHP GD extension is required, but is not installed.", E_ERROR); return false; } // version 1.00 if (!($fh = fopen($filename, 'rb'))) { trigger_error('imagecreatefrombmp: Can not open ' . $filename, E_USER_WARNING); return false; } $bytes_read = 0; // read file header $meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14)); // check for bitmap if ($meta['type'] != 19778) { trigger_error('imagecreatefrombmp: ' . $filename . ' is not a bitmap!', E_USER_WARNING); return false; } // read image header $meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40)); $bytes_read += 40; // read additional bitfield header if ($meta['compression'] == 3) { $meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12)); $bytes_read += 12; } // set bytes and padding $meta['bytes'] = $meta['bits'] / 8; $meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4) - floor($meta['width'] * $meta['bytes'] / 4))); if ($meta['decal'] == 4) { $meta['decal'] = 0; } // obtain imagesize if ($meta['imagesize'] < 1) { $meta['imagesize'] = $meta['filesize'] - $meta['offset']; // in rare cases filesize is equal to offset so we need to read physical size if ($meta['imagesize'] < 1) { $meta['imagesize'] = @filesize($filename) - $meta['offset']; if ($meta['imagesize'] < 1) { trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING); return false; } } } // calculate colors $meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors']; // read color palette $palette = []; if ($meta['bits'] < 16) { $palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4)); // in rare cases the color value is signed if ($palette[1] < 0) { foreach ($palette as $i => $color) { $palette[$i] = $color + 16777216; } } } // ignore extra bitmap headers if ($meta['headersize'] > $bytes_read) { fread($fh, $meta['headersize'] - $bytes_read); } // create gd image $im = imagecreatetruecolor($meta['width'], $meta['height']); $data = fread($fh, $meta['imagesize']); // uncompress data switch ($meta['compression']) { case 1: $data = Helpers::rle8_decode($data, $meta['width']); break; case 2: $data = Helpers::rle4_decode($data, $meta['width']); break; } $p = 0; $vide = chr(0); $y = $meta['height'] - 1; $error = 'imagecreatefrombmp: ' . $filename . ' has not enough data!'; // loop through the image data beginning with the lower left corner while ($y >= 0) { $x = 0; while ($x < $meta['width']) { switch ($meta['bits']) { case 32: case 24: if (!($part = substr($data, $p, 3 /*$meta['bytes']*/))) { trigger_error($error, E_USER_WARNING); return $im; } $color = unpack('V', $part . $vide); break; case 16: if (!($part = substr($data, $p, 2 /*$meta['bytes']*/))) { trigger_error($error, E_USER_WARNING); return $im; } $color = unpack('v', $part); if (empty($meta['rMask']) || $meta['rMask'] != 0xf800) { $color[1] = (($color[1] & 0x7c00) >> 7) * 65536 + (($color[1] & 0x03e0) >> 2) * 256 + (($color[1] & 0x001f) << 3); // 555 } else { $color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3); // 565 } break; case 8: $color = unpack('n', $vide . substr($data, $p, 1)); $color[1] = $palette[$color[1] + 1]; break; case 4: $color = unpack('n', $vide . substr($data, floor($p), 1)); $color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F; $color[1] = $palette[$color[1] + 1]; break; case 1: $color = unpack('n', $vide . substr($data, floor($p), 1)); switch (($p * 8) % 8) { case 0: $color[1] = $color[1] >> 7; break; case 1: $color[1] = ($color[1] & 0x40) >> 6; break; case 2: $color[1] = ($color[1] & 0x20) >> 5; break; case 3: $color[1] = ($color[1] & 0x10) >> 4; break; case 4: $color[1] = ($color[1] & 0x8) >> 3; break; case 5: $color[1] = ($color[1] & 0x4) >> 2; break; case 6: $color[1] = ($color[1] & 0x2) >> 1; break; case 7: $color[1] = ($color[1] & 0x1); break; } $color[1] = $palette[$color[1] + 1]; break; default: trigger_error('imagecreatefrombmp: ' . $filename . ' has ' . $meta['bits'] . ' bits and this is not supported!', E_USER_WARNING); return false; } imagesetpixel($im, $x, $y, $color[1]); $x++; $p += $meta['bytes']; } $y--; $p += $meta['decal']; } fclose($fh); return $im; } /** * Gets the content of the file at the specified path using one of * the following methods, in preferential order: * - file_get_contents: if allow_url_fopen is true or the file is local * - curl: if allow_url_fopen is false and curl is available * * @param string $uri * @param resource $context (ignored if curl is used) * @param int $offset * @param int $maxlen (ignored if curl is used) * @return string[] */ public static function getFileContent($uri, $context = null, $offset = 0, $maxlen = null) { $content = null; $headers = null; [$protocol] = Helpers::explode_url($uri); $is_local_path = ($protocol === "" || $protocol === "file://"); set_error_handler([self::class, 'record_warnings']); try { if ($is_local_path || ini_get('allow_url_fopen')) { if ($is_local_path === false) { $uri = Helpers::encodeURI($uri); } if (isset($maxlen)) { $result = file_get_contents($uri, false, $context, $offset, $maxlen); } else { $result = file_get_contents($uri, false, $context, $offset); } if ($result !== false) { $content = $result; } if (isset($http_response_header)) { $headers = $http_response_header; } } elseif (function_exists('curl_exec')) { $curl = curl_init($uri); //TODO: use $context to define additional curl options curl_setopt($curl, CURLOPT_TIMEOUT, 10); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, true); if ($offset > 0) { curl_setopt($curl, CURLOPT_RESUME_FROM, $offset); } $data = curl_exec($curl); if ($data !== false && !curl_errno($curl)) { switch ($http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE)) { case 200: $raw_headers = substr($data, 0, curl_getinfo($curl, CURLINFO_HEADER_SIZE)); $headers = preg_split("/[\n\r]+/", trim($raw_headers)); $content = substr($data, curl_getinfo($curl, CURLINFO_HEADER_SIZE)); break; } } curl_close($curl); } } finally { restore_error_handler(); } return [$content, $headers]; } /** * @param string $str * @return string */ public static function mb_ucwords(string $str): string { $max_len = mb_strlen($str); if ($max_len === 1) { return mb_strtoupper($str); } $str = mb_strtoupper(mb_substr($str, 0, 1)) . mb_substr($str, 1); foreach ([' ', '.', ',', '!', '?', '-', '+'] as $s) { $pos = 0; while (($pos = mb_strpos($str, $s, $pos)) !== false) { $pos++; // Nothing to do if the separator is the last char of the string if ($pos !== false && $pos < $max_len) { // If the char we want to upper is the last char there is nothing to append behind if ($pos + 1 < $max_len) { $str = mb_substr($str, 0, $pos) . mb_strtoupper(mb_substr($str, $pos, 1)) . mb_substr($str, $pos + 1); } else { $str = mb_substr($str, 0, $pos) . mb_strtoupper(mb_substr($str, $pos, 1)); } } } } return $str; } /** * Check whether two lengths should be considered equal, accounting for * inaccuracies in float computation. * * The implementation relies on the fact that we are neither dealing with * very large, nor with very small numbers in layout. Adapted from * https://floating-point-gui.de/errors/comparison/. * * @param float $a * @param float $b * * @return bool */ public static function lengthEqual(float $a, float $b): bool { // The epsilon results in a precision of at least: // * 7 decimal digits at around 1 // * 4 decimal digits at around 1000 (around the size of common paper formats) // * 2 decimal digits at around 100,000 (100,000pt ~ 35.28m) static $epsilon = 1e-8; static $almostZero = 1e-12; $diff = abs($a - $b); if ($a === $b || $diff < $almostZero) { return true; } return $diff < $epsilon * max(abs($a), abs($b)); } /** * Check `$a < $b`, accounting for inaccuracies in float computation. */ public static function lengthLess(float $a, float $b): bool { return $a < $b && !self::lengthEqual($a, $b); } /** * Check `$a <= $b`, accounting for inaccuracies in float computation. */ public static function lengthLessOrEqual(float $a, float $b): bool { return $a <= $b || self::lengthEqual($a, $b); } /** * Check `$a > $b`, accounting for inaccuracies in float computation. */ public static function lengthGreater(float $a, float $b): bool { return $a > $b && !self::lengthEqual($a, $b); } /** * Check `$a >= $b`, accounting for inaccuracies in float computation. */ public static function lengthGreaterOrEqual(float $a, float $b): bool { return $a >= $b || self::lengthEqual($a, $b); } } PK!s<+convertformstools/pdf/dompdf/src/Dompdf.phpnu[ * @author Fabien Ménager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf; use DOMDocument; use DOMNode; use Dompdf\Adapter\CPDF; use DOMXPath; use Dompdf\Frame\Factory; use Dompdf\Frame\FrameTree; use HTML5_Tokenizer; use HTML5_TreeBuilder; use Dompdf\Image\Cache; use Dompdf\Css\Stylesheet; use Dompdf\Helpers; /** * Dompdf - PHP5 HTML to PDF renderer * * Dompdf loads HTML and does its best to render it as a PDF. It gets its * name from the new DomDocument PHP5 extension. Source HTML is first * parsed by a DomDocument object. Dompdf takes the resulting DOM tree and * attaches a {@link Frame} object to each node. {@link Frame} objects store * positioning and layout information and each has a reference to a {@link * Style} object. * * Style information is loaded and parsed (see {@link Stylesheet}) and is * applied to the frames in the tree by using XPath. CSS selectors are * converted into XPath queries, and the computed {@link Style} objects are * applied to the {@link Frame}s. * * {@link Frame}s are then decorated (in the design pattern sense of the * word) based on their CSS display property ({@link * http://www.w3.org/TR/CSS21/visuren.html#propdef-display}). * Frame_Decorators augment the basic {@link Frame} class by adding * additional properties and methods specific to the particular type of * {@link Frame}. For example, in the CSS layout model, block frames * (display: block;) contain line boxes that are usually filled with text or * other inline frames. The Block therefore adds a $lines * property as well as methods to add {@link Frame}s to lines and to add * additional lines. {@link Frame}s also are attached to specific * AbstractPositioner and {@link AbstractFrameReflower} objects that contain the * positioining and layout algorithm for a specific type of frame, * respectively. This is an application of the Strategy pattern. * * Layout, or reflow, proceeds recursively (post-order) starting at the root * of the document. Space constraints (containing block width & height) are * pushed down, and resolved positions and sizes bubble up. Thus, every * {@link Frame} in the document tree is traversed once (except for tables * which use a two-pass layout algorithm). If you are interested in the * details, see the reflow() method of the Reflower classes. * * Rendering is relatively straightforward once layout is complete. {@link * Frame}s are rendered using an adapted {@link Cpdf} class, originally * written by Wayne Munro, http://www.ros.co.nz/pdf/. (Some performance * related changes have been made to the original {@link Cpdf} class, and * the {@link Dompdf\Adapter\CPDF} class provides a simple, stateless interface to * PDF generation.) PDFLib support has now also been added, via the {@link * Dompdf\Adapter\PDFLib}. * * * @package dompdf */ class Dompdf { /** * Version string for dompdf * * @var string */ private $version = 'dompdf'; /** * DomDocument representing the HTML document * * @var DOMDocument */ private $dom; /** * FrameTree derived from the DOM tree * * @var FrameTree */ private $tree; /** * Stylesheet for the document * * @var Stylesheet */ private $css; /** * Actual PDF renderer * * @var Canvas */ private $canvas; /** * Desired paper size ('letter', 'legal', 'A4', etc.) * * @var string|array */ private $paperSize; /** * Paper orientation ('portrait' or 'landscape') * * @var string */ private $paperOrientation = "portrait"; /** * Callbacks on new page and new element * * @var array */ private $callbacks = []; /** * Experimental caching capability * * @var string */ private $cacheId; /** * Base hostname * * Used for relative paths/urls * @var string */ private $baseHost = ""; /** * Absolute base path * * Used for relative paths/urls * @var string */ private $basePath = ""; /** * Protocol used to request file (file://, http://, etc) * * @var string */ private $protocol = ""; /** * HTTP context created with stream_context_create() * Will be used for file_get_contents * * @var resource */ private $httpContext; /** * The system's locale * * @var string */ private $systemLocale = null; /** * The system's mbstring internal encoding * * @var string */ private $mbstringEncoding = null; /** * The system's PCRE JIT configuration * * @var string */ private $pcreJit = null; /** * The default view of the PDF in the viewer * * @var string */ private $defaultView = "Fit"; /** * The default view options of the PDF in the viewer * * @var array */ private $defaultViewOptions = []; /** * Tells whether the DOM document is in quirksmode (experimental) * * @var bool */ private $quirksmode = false; /** * Protocol whitelist * * Protocols and PHP wrappers allowed in URLs. Full support is not * guaranteed for the protocols/wrappers contained in this array. * * @var array */ private $allowedProtocols = ["", "file://", "http://", "https://"]; /** * Local file extension whitelist * * File extensions supported by dompdf for local files. * * @var array */ private $allowedLocalFileExtensions = ["htm", "html"]; /** * @var array */ private $messages = []; /** * @var Options */ private $options; /** * @var FontMetrics */ private $fontMetrics; /** * The list of built-in fonts * * @var array * @deprecated */ public static $native_fonts = [ "courier", "courier-bold", "courier-oblique", "courier-boldoblique", "helvetica", "helvetica-bold", "helvetica-oblique", "helvetica-boldoblique", "times-roman", "times-bold", "times-italic", "times-bolditalic", "symbol", "zapfdinbats" ]; /** * The list of built-in fonts * * @var array */ public static $nativeFonts = [ "courier", "courier-bold", "courier-oblique", "courier-boldoblique", "helvetica", "helvetica-bold", "helvetica-oblique", "helvetica-boldoblique", "times-roman", "times-bold", "times-italic", "times-bolditalic", "symbol", "zapfdinbats" ]; /** * Class constructor * * @param array|Options $options */ public function __construct($options = null) { if (isset($options) && $options instanceof Options) { $this->setOptions($options); } elseif (is_array($options)) { $this->setOptions(new Options($options)); } else { $this->setOptions(new Options()); } $versionFile = realpath(__DIR__ . '/../VERSION'); if (file_exists($versionFile) && ($version = trim(file_get_contents($versionFile))) !== false && $version !== '$Format:<%h>$') { $this->version = sprintf('dompdf %s', $version); } $this->setPhpConfig(); $this->paperSize = $this->options->getDefaultPaperSize(); $this->paperOrientation = $this->options->getDefaultPaperOrientation(); $this->setCanvas(CanvasFactory::get_instance($this, $this->paperSize, $this->paperOrientation)); $this->setFontMetrics(new FontMetrics($this->getCanvas(), $this->getOptions())); $this->css = new Stylesheet($this); $this->restorePhpConfig(); } /** * Save the system's existing locale, PCRE JIT, and MBString encoding * configuration and configure the system for Dompdf processing */ private function setPhpConfig() { if (sprintf('%.1f', 1.0) !== '1.0') { $this->systemLocale = setlocale(LC_NUMERIC, "0"); setlocale(LC_NUMERIC, "C"); } $this->pcreJit = @ini_get('pcre.jit'); @ini_set('pcre.jit', '0'); $this->mbstringEncoding = mb_internal_encoding(); mb_internal_encoding('UTF-8'); } /** * Restore the system's locale configuration */ private function restorePhpConfig() { if ($this->systemLocale !== null) { setlocale(LC_NUMERIC, $this->systemLocale); $this->systemLocale = null; } if ($this->pcreJit !== null) { @ini_set('pcre.jit', $this->pcreJit); $this->pcreJit = null; } if ($this->mbstringEncoding !== null) { mb_internal_encoding($this->mbstringEncoding); $this->mbstringEncoding = null; } } /** * @param $file * @deprecated */ public function load_html_file($file) { $this->loadHtmlFile($file); } /** * Loads an HTML file * Parse errors are stored in the global array _dompdf_warnings. * * @param string $file a filename or url to load * @param string $encoding Encoding of $file * * @throws Exception */ public function loadHtmlFile($file, $encoding = null) { $this->setPhpConfig(); if (!$this->protocol && !$this->baseHost && !$this->basePath) { [$this->protocol, $this->baseHost, $this->basePath] = Helpers::explode_url($file); } $protocol = strtolower($this->protocol); $uri = Helpers::build_url($this->protocol, $this->baseHost, $this->basePath, $file); if (!in_array($protocol, $this->allowedProtocols, true)) { throw new Exception("Permission denied on $file. The communication protocol is not supported."); } if (!$this->options->isRemoteEnabled() && ($protocol !== "" && $protocol !== "file://")) { throw new Exception("Remote file requested, but remote file download is disabled."); } if ($protocol === "" || $protocol === "file://") { $realfile = realpath($uri); $chroot = $this->options->getChroot(); $chrootValid = false; foreach ($chroot as $chrootPath) { $chrootPath = realpath($chrootPath); if ($chrootPath !== false && strpos($realfile, $chrootPath) === 0) { $chrootValid = true; break; } } if ($chrootValid !== true) { throw new Exception("Permission denied on $file. The file could not be found under the paths specified by Options::chroot."); } $ext = strtolower(pathinfo($realfile, PATHINFO_EXTENSION)); if (!in_array($ext, $this->allowedLocalFileExtensions)) { throw new Exception("Permission denied on $file. This file extension is forbidden"); } if (!$realfile) { throw new Exception("File '$file' not found."); } $uri = $realfile; } [$contents, $http_response_header] = Helpers::getFileContent($uri, $this->httpContext); if ($contents === null) { throw new Exception("File '$file' not found."); } // See http://the-stickman.com/web-development/php/getting-http-response-headers-when-using-file_get_contents/ if (isset($http_response_header)) { foreach ($http_response_header as $_header) { if (preg_match("@Content-Type:\s*[\w/]+;\s*?charset=([^\s]+)@i", $_header, $matches)) { $encoding = strtoupper($matches[1]); break; } } } $this->restorePhpConfig(); $this->loadHtml($contents, $encoding); } /** * @param string $str * @param string $encoding * @deprecated */ public function load_html($str, $encoding = null) { $this->loadHtml($str, $encoding); } public function loadDOM($doc, $quirksmode = false) { // Remove #text children nodes in nodes that shouldn't have $tag_names = ["html", "head", "table", "tbody", "thead", "tfoot", "tr"]; foreach ($tag_names as $tag_name) { $nodes = $doc->getElementsByTagName($tag_name); foreach ($nodes as $node) { self::removeTextNodes($node); } } $this->dom = $doc; $this->quirksmode = $quirksmode; $this->tree = new FrameTree($this->dom); } /** * Loads an HTML string * Parse errors are stored in the global array _dompdf_warnings. * * @param string $str HTML text to load * @param string $encoding Encoding of $str */ public function loadHtml($str, $encoding = null) { $this->setPhpConfig(); // Determine character encoding when $encoding parameter not used if ($encoding === null) { mb_detect_order('auto'); if (($encoding = mb_detect_encoding($str, null, true)) === false) { //"auto" is expanded to "ASCII,JIS,UTF-8,EUC-JP,SJIS" $encoding = "auto"; } } if (in_array(strtoupper($encoding), array('UTF-8','UTF8')) === false) { $str = mb_convert_encoding($str, 'UTF-8', $encoding); //Update encoding after converting $encoding = 'UTF-8'; } $metatags = [ '@]*charset\s*=\s*["\']?\s*([^"\' ]+)@i', ]; foreach ($metatags as $metatag) { if (preg_match($metatag, $str, $matches)) { if (isset($matches[1]) && in_array($matches[1], mb_list_encodings())) { $document_encoding = $matches[1]; break; } } } if (isset($document_encoding) && in_array(strtoupper($document_encoding), ['UTF-8','UTF8']) === false) { $str = preg_replace('/charset=([^\s"]+)/i', 'charset=UTF-8', $str); } elseif (isset($document_encoding) === false && strpos($str, '') !== false) { $str = str_replace('', '', $str); } elseif (isset($document_encoding) === false) { $str = '' . $str; } // remove BOM mark from UTF-8, it's treated as document text by DOMDocument // FIXME: roll this into the encoding detection using UTF-8/16/32 BOM (http://us2.php.net/manual/en/function.mb-detect-encoding.php#91051)? if (substr($str, 0, 3) == chr(0xEF) . chr(0xBB) . chr(0xBF)) { $str = substr($str, 3); } // Store parsing warnings as messages set_error_handler([Helpers::class, 'record_warnings']); try { // @todo Take the quirksmode into account // http://hsivonen.iki.fi/doctype/ // https://developer.mozilla.org/en/mozilla's_quirks_mode $quirksmode = false; if ($this->options->isHtml5ParserEnabled() && class_exists(HTML5_Tokenizer::class)) { $tokenizer = new HTML5_Tokenizer($str); $tokenizer->parse(); $doc = $tokenizer->save(); $quirksmode = ($tokenizer->getTree()->getQuirksMode() > HTML5_TreeBuilder::NO_QUIRKS); } else { // loadHTML assumes ISO-8859-1 unless otherwise specified on the HTML document header. // http://devzone.zend.com/1538/php-dom-xml-extension-encoding-processing/ (see #4) // http://stackoverflow.com/a/11310258/264628 $doc = new DOMDocument("1.0", $encoding); $doc->preserveWhiteSpace = true; $doc->loadHTML($str); $doc->encoding = $encoding; // If some text is before the doctype, we are in quirksmode if (preg_match("/^(.+) if (!$doc->doctype->publicId && !$doc->doctype->systemId) { $quirksmode = false; } // not XHTML if (!preg_match("/xhtml/i", $doc->doctype->publicId)) { $quirksmode = true; } } } $this->loadDOM($doc, $quirksmode); } finally { restore_error_handler(); $this->restorePhpConfig(); } } /** * @param DOMNode $node * @deprecated */ public static function remove_text_nodes(DOMNode $node) { self::removeTextNodes($node); } /** * @param DOMNode $node */ public static function removeTextNodes(DOMNode $node) { $children = []; for ($i = 0; $i < $node->childNodes->length; $i++) { $child = $node->childNodes->item($i); if ($child->nodeName === "#text") { $children[] = $child; } } foreach ($children as $child) { $node->removeChild($child); } } /** * Builds the {@link FrameTree}, loads any CSS and applies the styles to * the {@link FrameTree} */ private function processHtml() { $this->tree->build_tree(); $this->css->load_css_file($this->css->getDefaultStylesheet(), Stylesheet::ORIG_UA); $acceptedmedia = Stylesheet::$ACCEPTED_GENERIC_MEDIA_TYPES; $acceptedmedia[] = $this->options->getDefaultMediaType(); // $base_nodes = $this->dom->getElementsByTagName("base"); if ($base_nodes->length && ($href = $base_nodes->item(0)->getAttribute("href"))) { [$this->protocol, $this->baseHost, $this->basePath] = Helpers::explode_url($href); } // Set the base path of the Stylesheet to that of the file being processed $this->css->set_protocol($this->protocol); $this->css->set_host($this->baseHost); $this->css->set_base_path($this->basePath); // Get all the stylesheets so that they are processed in document order $xpath = new DOMXPath($this->dom); $stylesheets = $xpath->query("//*[name() = 'link' or name() = 'style']"); /** @var \DOMElement $tag */ foreach ($stylesheets as $tag) { switch (strtolower($tag->nodeName)) { // load tags case "link": if (mb_strtolower(stripos($tag->getAttribute("rel"), "stylesheet") !== false) || // may be "appendix stylesheet" mb_strtolower($tag->getAttribute("type")) === "text/css" ) { //Check if the css file is for an accepted media type //media not given then always valid $formedialist = preg_split("/[\s\n,]/", $tag->getAttribute("media"), -1, PREG_SPLIT_NO_EMPTY); if (count($formedialist) > 0) { $accept = false; foreach ($formedialist as $type) { if (in_array(mb_strtolower(trim($type)), $acceptedmedia)) { $accept = true; break; } } if (!$accept) { //found at least one mediatype, but none of the accepted ones //Skip this css file. break; } } $url = $tag->getAttribute("href"); $url = Helpers::build_url($this->protocol, $this->baseHost, $this->basePath, $url); $this->css->load_css_file($url, Stylesheet::ORIG_AUTHOR); } break; // load $child = $child->nextSibling; } } else { $css = $tag->nodeValue; } // Set the base path of the Stylesheet to that of the file being processed $this->css->set_protocol($this->protocol); $this->css->set_host($this->baseHost); $this->css->set_base_path($this->basePath); $this->css->load_css($css, Stylesheet::ORIG_AUTHOR); break; } // Set the base path of the Stylesheet to that of the file being processed $this->css->set_protocol($this->protocol); $this->css->set_host($this->baseHost); $this->css->set_base_path($this->basePath); } } /** * @param string $cacheId * @deprecated */ public function enable_caching($cacheId) { $this->enableCaching($cacheId); } /** * Enable experimental caching capability * * @param string $cacheId */ public function enableCaching($cacheId) { $this->cacheId = $cacheId; } /** * @param string $value * @return bool * @deprecated */ public function parse_default_view($value) { return $this->parseDefaultView($value); } /** * @param string $value * @return bool */ public function parseDefaultView($value) { $valid = ["XYZ", "Fit", "FitH", "FitV", "FitR", "FitB", "FitBH", "FitBV"]; $options = preg_split("/\s*,\s*/", trim($value)); $defaultView = array_shift($options); if (!in_array($defaultView, $valid)) { return false; } $this->setDefaultView($defaultView, $options); return true; } /** * Renders the HTML to PDF */ public function render() { $this->setPhpConfig(); $options = $this->options; $logOutputFile = $options->getLogOutputFile(); if ($logOutputFile) { if (!file_exists($logOutputFile) && is_writable(dirname($logOutputFile))) { touch($logOutputFile); } $startTime = microtime(true); if (is_writable($logOutputFile)) { ob_start(); } } $this->processHtml(); $this->css->apply_styles($this->tree); // @page style rules : size, margins $pageStyles = $this->css->get_page_styles(); $basePageStyle = $pageStyles["base"]; unset($pageStyles["base"]); foreach ($pageStyles as $pageStyle) { $pageStyle->inherit($basePageStyle); } $defaultOptionPaperSize = $this->getPaperSize($options->getDefaultPaperSize()); // If there is a CSS defined paper size compare to the paper size used to create the canvas to determine a // recreation need if (is_array($basePageStyle->size)) { $basePageStyleSize = $basePageStyle->size; $this->setPaper([0, 0, $basePageStyleSize[0], $basePageStyleSize[1]]); } $paperSize = $this->getPaperSize(); if ( $defaultOptionPaperSize[2] !== $paperSize[2] || $defaultOptionPaperSize[3] !== $paperSize[3] || $options->getDefaultPaperOrientation() !== $this->paperOrientation ) { $this->setCanvas(CanvasFactory::get_instance($this, $this->paperSize, $this->paperOrientation)); $this->fontMetrics->setCanvas($this->getCanvas()); } $canvas = $this->getCanvas(); $root = null; foreach ($this->tree->get_frames() as $frame) { // Set up the root frame if (is_null($root)) { $root = Factory::decorate_root($this->tree->get_root(), $this); continue; } // Create the appropriate decorators, reflowers & positioners. Factory::decorate_frame($frame, $this, $root); } // Add meta information $title = $this->dom->getElementsByTagName("title"); if ($title->length) { $canvas->add_info("Title", trim($title->item(0)->nodeValue)); } $metas = $this->dom->getElementsByTagName("meta"); $labels = [ "author" => "Author", "keywords" => "Keywords", "description" => "Subject", ]; /** @var \DOMElement $meta */ foreach ($metas as $meta) { $name = mb_strtolower($meta->getAttribute("name")); $value = trim($meta->getAttribute("content")); if (isset($labels[$name])) { $canvas->add_info($labels[$name], $value); continue; } if ($name === "dompdf.view" && $this->parseDefaultView($value)) { $canvas->set_default_view($this->defaultView, $this->defaultViewOptions); } } $root->set_containing_block(0, 0, $canvas->get_width(), $canvas->get_height()); $root->set_renderer(new Renderer($this)); // This is where the magic happens: $root->reflow(); // Clean up cached images if (!$this->options->getDebugKeepTemp()) { Cache::clear($this->options->getDebugPng()); } global $_dompdf_warnings, $_dompdf_show_warnings; if ($_dompdf_show_warnings && isset($_dompdf_warnings)) { echo 'Dompdf Warnings
    ';
                foreach ($_dompdf_warnings as $msg) {
                    echo $msg . "\n";
                }
    
                if ($canvas instanceof CPDF) {
                    echo $canvas->get_cpdf()->messages;
                }
                echo '
    '; flush(); } if ($logOutputFile && is_writable($logOutputFile)) { $this->writeLog($logOutputFile, $startTime); ob_end_clean(); } $this->restorePhpConfig(); } /** * Add meta information to the PDF after rendering */ public function add_info($label, $value) { $canvas = $this->getCanvas(); if (!is_null($canvas)) { $canvas->add_info($label, $value); } } /** * Writes the output buffer in the log file * * @param string $logOutputFile * @param float $startTime */ private function writeLog(string $logOutputFile, float $startTime): void { $frames = Frame::$ID_COUNTER; $memory = memory_get_peak_usage(true) / 1024; $time = (microtime(true) - $startTime) * 1000; $out = sprintf( "%6d" . "%10.2f KB" . "%10.2f ms" . " " . ($this->quirksmode ? " ON" : "OFF") . "
    ", $frames, $memory, $time); $out .= ob_get_contents(); ob_clean(); file_put_contents($logOutputFile, $out); } /** * Streams the PDF to the client. * * The file will open a download dialog by default. The options * parameter controls the output. Accepted options (array keys) are: * * 'compress' = > 1 (=default) or 0: * Apply content stream compression * * 'Attachment' => 1 (=default) or 0: * Set the 'Content-Disposition:' HTTP header to 'attachment' * (thereby causing the browser to open a download dialog) * * @param string $filename the name of the streamed file * @param array $options header options (see above) */ public function stream($filename = "document.pdf", $options = []) { $this->setPhpConfig(); $canvas = $this->getCanvas(); if (!is_null($canvas)) { $canvas->stream($filename, $options); } $this->restorePhpConfig(); } /** * Returns the PDF as a string. * * The options parameter controls the output. Accepted options are: * * 'compress' = > 1 or 0 - apply content stream compression, this is * on (1) by default * * @param array $options options (see above) * * @return string|null */ public function output($options = []) { $this->setPhpConfig(); $canvas = $this->getCanvas(); if (is_null($canvas)) { return null; } $output = $canvas->output($options); $this->restorePhpConfig(); return $output; } /** * @return string * @deprecated */ public function output_html() { return $this->outputHtml(); } /** * Returns the underlying HTML document as a string * * @return string */ public function outputHtml() { return $this->dom->saveHTML(); } /** * Get the dompdf option value * * @param string $key * @return mixed * @deprecated */ public function get_option($key) { return $this->options->get($key); } /** * @param string $key * @param mixed $value * @return $this * @deprecated */ public function set_option($key, $value) { $this->options->set($key, $value); return $this; } /** * @param array $options * @return $this * @deprecated */ public function set_options(array $options) { $this->options->set($options); return $this; } /** * @param string $size * @param string $orientation * @deprecated */ public function set_paper($size, $orientation = "portrait") { $this->setPaper($size, $orientation); } /** * Sets the paper size & orientation * * @param string|array $size 'letter', 'legal', 'A4', etc. {@link Dompdf\Adapter\CPDF::$PAPER_SIZES} * @param string $orientation 'portrait' or 'landscape' * @return $this */ public function setPaper($size, $orientation = "portrait") { $this->paperSize = $size; $this->paperOrientation = $orientation; return $this; } /** * Gets the paper size * * @param null|string|array $paperSize * @return int[] A four-element integer array */ public function getPaperSize($paperSize = null) { $size = $paperSize !== null ? $paperSize : $this->paperSize; if (is_array($size)) { return $size; } else if (isset(Adapter\CPDF::$PAPER_SIZES[mb_strtolower($size)])) { return Adapter\CPDF::$PAPER_SIZES[mb_strtolower($size)]; } else { return Adapter\CPDF::$PAPER_SIZES["letter"]; } } /** * Gets the paper orientation * * @return string Either "portrait" or "landscape" */ public function getPaperOrientation() { return $this->paperOrientation; } /** * @param FrameTree $tree * @return $this */ public function setTree(FrameTree $tree) { $this->tree = $tree; return $this; } /** * @return FrameTree * @deprecated */ public function get_tree() { return $this->getTree(); } /** * Returns the underlying {@link FrameTree} object * * @return FrameTree */ public function getTree() { return $this->tree; } /** * @param string $protocol * @return $this * @deprecated */ public function set_protocol($protocol) { return $this->setProtocol($protocol); } /** * Sets the protocol to use * FIXME validate these * * @param string $protocol * @return $this */ public function setProtocol(string $protocol) { $this->protocol = $protocol; return $this; } /** * @return string * @deprecated */ public function get_protocol() { return $this->getProtocol(); } /** * Returns the protocol in use * * @return string */ public function getProtocol() { return $this->protocol; } /** * @param string $host * @deprecated */ public function set_host($host) { $this->setBaseHost($host); } /** * Sets the base hostname * * @param string $baseHost * @return $this */ public function setBaseHost(string $baseHost) { $this->baseHost = $baseHost; return $this; } /** * @return string * @deprecated */ public function get_host() { return $this->getBaseHost(); } /** * Returns the base hostname * * @return string */ public function getBaseHost() { return $this->baseHost; } /** * Sets the base path * * @param string $path * @deprecated */ public function set_base_path($path) { $this->setBasePath($path); } /** * Sets the base path * * @param string $basePath * @return $this */ public function setBasePath(string $basePath) { $this->basePath = $basePath; return $this; } /** * @return string * @deprecated */ public function get_base_path() { return $this->getBasePath(); } /** * Returns the base path * * @return string */ public function getBasePath() { return $this->basePath; } /** * @param string $default_view The default document view * @param array $options The view's options * @return $this * @deprecated */ public function set_default_view($default_view, $options) { return $this->setDefaultView($default_view, $options); } /** * Sets the default view * * @param string $defaultView The default document view * @param array $options The view's options * @return $this */ public function setDefaultView($defaultView, $options) { $this->defaultView = $defaultView; $this->defaultViewOptions = $options; return $this; } /** * @param resource $http_context * @return $this * @deprecated */ public function set_http_context($http_context) { return $this->setHttpContext($http_context); } /** * Sets the HTTP context * * @param resource $httpContext * @return $this */ public function setHttpContext($httpContext) { $this->httpContext = $httpContext; return $this; } /** * @return resource * @deprecated */ public function get_http_context() { return $this->getHttpContext(); } /** * Returns the HTTP context * * @return resource */ public function getHttpContext() { return $this->httpContext; } /** * @param Canvas $canvas * @return $this */ public function setCanvas(Canvas $canvas) { $this->canvas = $canvas; return $this; } /** * @return Canvas * @deprecated */ public function get_canvas() { return $this->getCanvas(); } /** * Return the underlying Canvas instance (e.g. Dompdf\Adapter\CPDF, Dompdf\Adapter\GD) * * @return Canvas */ public function getCanvas() { return $this->canvas; } /** * @param Stylesheet $css * @return $this */ public function setCss(Stylesheet $css) { $this->css = $css; return $this; } /** * @return Stylesheet * @deprecated */ public function get_css() { return $this->getCss(); } /** * Returns the stylesheet * * @return Stylesheet */ public function getCss() { return $this->css; } /** * @param DOMDocument $dom * @return $this */ public function setDom(DOMDocument $dom) { $this->dom = $dom; return $this; } /** * @return DOMDocument * @deprecated */ public function get_dom() { return $this->getDom(); } /** * @return DOMDocument */ public function getDom() { return $this->dom; } /** * @param Options $options * @return $this */ public function setOptions(Options $options) { $this->options = $options; $fontMetrics = $this->getFontMetrics(); if (isset($fontMetrics)) { $fontMetrics->setOptions($options); } return $this; } /** * @return Options */ public function getOptions() { return $this->options; } /** * @return array * @deprecated */ public function get_callbacks() { return $this->getCallbacks(); } /** * Returns the callbacks array * * @return array */ public function getCallbacks() { return $this->callbacks; } /** * @param array $callbacks the set of callbacks to set * @deprecated */ public function set_callbacks($callbacks) { $this->setCallbacks($callbacks); } /** * Sets callbacks for events like rendering of pages and elements. * * The callbacks array should contain arrays with `event` set to a callback * event name and `f` set to a function or any other callable. * * The available callback events are: * * `begin_page_reflow`: called before page reflow * * `begin_frame`: called before a frame is rendered * * `end_frame`: called after frame rendering is complete * * `begin_page_render`: called before a page is rendered * * `end_page_render`: called after page rendering is complete * * The function `f` must take an array as argument, which contains info * about the event (`[0 => Canvas, 1 => Frame, "canvas" => Canvas, * "frame" => Frame]`). * * @param array $callbacks The set of callbacks to set */ public function setCallbacks($callbacks) { if (is_array($callbacks)) { $this->callbacks = []; foreach ($callbacks as $c) { if (is_array($c) && isset($c["event"]) && isset($c["f"])) { $event = $c["event"]; $f = $c["f"]; if (is_string($event) && is_callable($f)) { $this->callbacks[$event][] = $f; } } } } } /** * @return boolean * @deprecated */ public function get_quirksmode() { return $this->getQuirksmode(); } /** * Get the quirks mode * * @return boolean true if quirks mode is active */ public function getQuirksmode() { return $this->quirksmode; } /** * @param FontMetrics $fontMetrics * @return $this */ public function setFontMetrics(FontMetrics $fontMetrics) { $this->fontMetrics = $fontMetrics; return $this; } /** * @return FontMetrics */ public function getFontMetrics() { return $this->fontMetrics; } /** * PHP5 overloaded getter * Along with {@link Dompdf::__set()} __get() provides access to all * properties directly. Typically __get() is not called directly outside * of this class. * * @param string $prop * * @throws Exception * @return mixed */ function __get($prop) { switch ($prop) { case 'version': return $this->version; default: throw new Exception('Invalid property: ' . $prop); } } } PK!ζF>convertformstools/pdf/dompdf/src/Positioner/NullPositioner.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; /** * Dummy positioner * * @package dompdf */ class NullPositioner extends AbstractPositioner { /** * @param AbstractFrameDecorator $frame */ function position(AbstractFrameDecorator $frame) { return; } } PK!\]]Bconvertformstools/pdf/dompdf/src/Positioner/AbstractPositioner.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; /** * Base AbstractPositioner class * * Defines postioner interface * * @access private * @package dompdf */ abstract class AbstractPositioner { /** * @param AbstractFrameDecorator $frame * @return mixed */ abstract function position(AbstractFrameDecorator $frame); /** * @param AbstractFrameDecorator $frame * @param float $offset_x * @param float $offset_y * @param bool $ignore_self */ function move(AbstractFrameDecorator $frame, $offset_x, $offset_y, $ignore_self = false) { list($x, $y) = $frame->get_position(); if (!$ignore_self) { $frame->set_position($x + $offset_x, $y + $offset_y); } foreach ($frame->get_children() as $child) { $child->move($offset_x, $offset_y); } } } PK! BTT5convertformstools/pdf/dompdf/src/Positioner/Fixed.phpnu[ * @author Fabien Ménager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; use Dompdf\FrameReflower\Block; /** * Positions fixely positioned frames */ class Fixed extends Absolute { /** * @param AbstractFrameDecorator $frame */ function position(AbstractFrameDecorator $frame) { if ($frame->get_reflower() instanceof Block) { parent::position($frame); } else { // Legacy positioning logic for image and table frames // TODO: Resolve dimensions, margins, and offsets similar to the // block case in the reflowers and use the simplified logic above $style = $frame->get_original_style(); $root = $frame->get_root(); $initialcb = $root->get_containing_block(); $initialcb_style = $root->get_style(); $p = $frame->find_block_parent(); if ($p) { $p->add_line(); } // Compute the margins of the @page style $margin_top = (float)$initialcb_style->length_in_pt($initialcb_style->margin_top, $initialcb["h"]); $margin_right = (float)$initialcb_style->length_in_pt($initialcb_style->margin_right, $initialcb["w"]); $margin_bottom = (float)$initialcb_style->length_in_pt($initialcb_style->margin_bottom, $initialcb["h"]); $margin_left = (float)$initialcb_style->length_in_pt($initialcb_style->margin_left, $initialcb["w"]); // The needed computed style of the element $height = (float)$style->length_in_pt($style->height, $initialcb["h"]); $width = (float)$style->length_in_pt($style->width, $initialcb["w"]); $top = $style->length_in_pt($style->top, $initialcb["h"]); $right = $style->length_in_pt($style->right, $initialcb["w"]); $bottom = $style->length_in_pt($style->bottom, $initialcb["h"]); $left = $style->length_in_pt($style->left, $initialcb["w"]); $y = $margin_top; if (isset($top)) { $y = (float)$top + $margin_top; if ($top === "auto") { $y = $margin_top; if (isset($bottom) && $bottom !== "auto") { $y = $initialcb["h"] - $bottom - $margin_bottom; if ($frame->is_auto_height()) { $y -= $height; } else { $y -= $frame->get_margin_height(); } } } } $x = $margin_left; if (isset($left)) { $x = (float)$left + $margin_left; if ($left === "auto") { $x = $margin_left; if (isset($right) && $right !== "auto") { $x = $initialcb["w"] - $right - $margin_right; if ($frame->is_auto_width()) { $x -= $width; } else { $x -= $frame->get_margin_width(); } } } } $frame->set_position($x, $y); $children = $frame->get_children(); foreach ($children as $child) { $child->set_position($x, $y); } } } } PK!]hQ6convertformstools/pdf/dompdf/src/Positioner/Inline.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; use Dompdf\FrameDecorator\Inline as InlineFrameDecorator; use Dompdf\Exception; use Dompdf\Helpers; /** * Positions inline frames * * @package dompdf */ class Inline extends AbstractPositioner { /** * @param AbstractFrameDecorator $frame * @throws Exception */ function position(AbstractFrameDecorator $frame) { // Find our nearest block level parent and access its lines property $block = $frame->find_block_parent(); if (!$block) { throw new Exception("No block-level parent found. Not good."); } $cb = $frame->get_containing_block(); $line = $block->get_current_line_box(); if (!$frame->is_text_node() && !($frame instanceof InlineFrameDecorator)) { // Atomic inline boxes and replaced inline elements // (inline-block, inline-table, img etc.) $width = $frame->get_margin_width(); $available_width = $cb["w"] - $line->left - $line->w - $line->right; if (Helpers::lengthGreater($width, $available_width)) { $block->add_line(); $line = $block->get_current_line_box(); } } $frame->set_position($cb["x"] + $line->w, $line->y); } } PK!n9Q:convertformstools/pdf/dompdf/src/Positioner/ListBullet.phpnu[ * @author Helmut Tischer * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; use Dompdf\FrameDecorator\ListBullet as ListBulletFrameDecorator; /** * Positions list bullets * * @package dompdf */ class ListBullet extends AbstractPositioner { /** * @param ListBulletFrameDecorator $frame */ function position(AbstractFrameDecorator $frame) { // List markers are positioned to the left of the border edge of their // parent element (FIXME: right for RTL) $parent = $frame->get_parent(); $style = $parent->get_style(); $cbw = $parent->get_containing_block("w"); $margin_left = (float) $style->length_in_pt($style->margin_left, $cbw); $border_edge = $parent->get_position("x") + $margin_left; // This includes the marker indentation $x = $border_edge - $frame->get_margin_width(); // The marker is later vertically aligned with the corresponding line // box and its vertical position is fine-tuned in the renderer $p = $frame->find_block_parent(); $y = $p->get_current_line_box()->y; $frame->set_position($x, $y); } } PK!p8convertformstools/pdf/dompdf/src/Positioner/TableRow.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; /** * Positions table rows * * @package dompdf */ class TableRow extends AbstractPositioner { /** * @param AbstractFrameDecorator $frame */ function position(AbstractFrameDecorator $frame) { $cb = $frame->get_containing_block(); $p = $frame->get_prev_sibling(); if ($p) { $y = $p->get_position("y") + $p->get_margin_height(); } else { $y = $cb["y"]; } $frame->set_position($cb["x"], $y); } } PK!5convertformstools/pdf/dompdf/src/Positioner/Block.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; /** * Positions block frames * * @access private * @package dompdf */ class Block extends AbstractPositioner { function position(AbstractFrameDecorator $frame) { $style = $frame->get_style(); $cb = $frame->get_containing_block(); $p = $frame->find_block_parent(); if ($p) { $float = $style->float; if (!$float || $float === "none") { $p->add_line(true); } $y = $p->get_current_line_box()->y; } else { $y = $cb["y"]; } $x = $cb["x"]; $frame->set_position($x, $y); } } PK!qև8convertformstools/pdf/dompdf/src/Positioner/Absolute.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; use Dompdf\FrameReflower\Block; /** * Positions absolutely positioned frames */ class Absolute extends AbstractPositioner { /** * @param AbstractFrameDecorator $frame */ function position(AbstractFrameDecorator $frame) { if ($frame->get_reflower() instanceof Block) { $style = $frame->get_style(); [$cbx, $cby, $cbw, $cbh] = $frame->get_containing_block(); // If the `top` value is `auto`, the frame will be repositioned // after its height has been resolved $left = (float) $style->length_in_pt($style->left, $cbw); $top = (float) $style->length_in_pt($style->top, $cbh); $frame->set_position($cbx + $left, $cby + $top); } else { // Legacy positioning logic for image and table frames // TODO: Resolve dimensions, margins, and offsets similar to the // block case in the reflowers and use the simplified logic above $style = $frame->get_style(); $block_parent = $frame->find_block_parent(); $current_line = $block_parent->get_current_line_box(); list($x, $y, $w, $h) = $frame->get_containing_block(); $inflow_x = $block_parent->get_content_box()["x"] + $current_line->left + $current_line->w; $inflow_y = $current_line->y; $top = $style->length_in_pt($style->top, $h); $right = $style->length_in_pt($style->right, $w); $bottom = $style->length_in_pt($style->bottom, $h); $left = $style->length_in_pt($style->left, $w); list($width, $height) = [$frame->get_margin_width(), $frame->get_margin_height()]; $orig_style = $frame->get_original_style(); $orig_width = $orig_style->width; $orig_height = $orig_style->height; /**************************** * * Width auto: * ____________| left=auto | left=fixed | * right=auto | A | B | * right=fixed | C | D | * * Width fixed: * ____________| left=auto | left=fixed | * right=auto | E | F | * right=fixed | G | H | *****************************/ if ($left === "auto") { if ($right === "auto") { // A or E - Keep the frame at the same position $x = $inflow_x; } else { if ($orig_width === "auto") { // C $x += $w - $width - $right; } else { // G $x += $w - $width - $right; } } } else { if ($right === "auto") { // B or F $x += (float)$left; } else { if ($orig_width === "auto") { // D - TODO change width $x += (float)$left; } else { // H - Everything is fixed: left + width win $x += (float)$left; } } } // The same vertically if ($top === "auto") { if ($bottom === "auto") { // A or E - Keep the frame at the same position $y = $inflow_y; } else { if ($orig_height === "auto") { // C $y += (float)$h - $height - (float)$bottom; } else { // G $y += (float)$h - $height - (float)$bottom; } } } else { if ($bottom === "auto") { // B or F $y += (float)$top; } else { if ($orig_height === "auto") { // D - TODO change height $y += (float)$top; } else { // H - Everything is fixed: top + height win $y += (float)$top; } } } $frame->set_position($x, $y); } } } PK!z9convertformstools/pdf/dompdf/src/Positioner/TableCell.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Positioner; use Dompdf\FrameDecorator\AbstractFrameDecorator; use Dompdf\FrameDecorator\Table; /** * Positions table cells * * @package dompdf */ class TableCell extends AbstractPositioner { /** * @param AbstractFrameDecorator $frame */ function position(AbstractFrameDecorator $frame) { $table = Table::find_parent_table($frame); $cellmap = $table->get_cellmap(); $frame->set_position($cellmap->get_frame_position($frame)); } } PK!omm,convertformstools/pdf/dompdf/src/Cellmap.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf; use Dompdf\FrameDecorator\AbstractFrameDecorator; use Dompdf\FrameDecorator\Table as TableFrameDecorator; use Dompdf\FrameDecorator\TableCell as TableCellFrameDecorator; /** * Maps table cells to the table grid. * * This class resolves borders in tables with collapsed borders and helps * place row & column spanned table cells. * * @package dompdf */ class Cellmap { /** * Border style weight lookup for collapsed border resolution. * * @var array */ protected static $_BORDER_STYLE_SCORE = [ "double" => 8, "solid" => 7, "dashed" => 6, "dotted" => 5, "ridge" => 4, "outset" => 3, "groove" => 2, "inset" => 1, "none" => 0 ]; /** * The table object this cellmap is attached to. * * @var TableFrameDecorator */ protected $_table; /** * The total number of rows in the table * * @var int */ protected $_num_rows; /** * The total number of columns in the table * * @var int */ protected $_num_cols; /** * 2D array mapping to frames * * @var Frame[][] */ protected $_cells; /** * 1D array of column dimensions * * @var array */ protected $_columns; /** * 1D array of row dimensions * * @var array */ protected $_rows; /** * 2D array of border specs * * @var array */ protected $_borders; /** * 1D Array mapping frames to (multiple) pairs, keyed on frame_id. * * @var array[] */ protected $_frames; /** * Current column when adding cells, 0-based * * @var int */ private $__col; /** * Current row when adding cells, 0-based * * @var int */ private $__row; /** * Tells whether the columns' width can be modified * * @var bool */ private $_columns_locked = false; /** * Tells whether the table has table-layout:fixed * * @var bool */ private $_fixed_layout = false; /** * @param TableFrameDecorator $table */ public function __construct(TableFrameDecorator $table) { $this->_table = $table; $this->reset(); } /** * */ public function reset() { $this->_num_rows = 0; $this->_num_cols = 0; $this->_cells = []; $this->_frames = []; if (!$this->_columns_locked) { $this->_columns = []; } $this->_rows = []; $this->_borders = []; $this->__col = $this->__row = 0; } /** * */ public function lock_columns() { $this->_columns_locked = true; } /** * @return bool */ public function is_columns_locked() { return $this->_columns_locked; } /** * @param $fixed */ public function set_layout_fixed($fixed) { $this->_fixed_layout = $fixed; } /** * @return bool */ public function is_layout_fixed() { return $this->_fixed_layout; } /** * @return int */ public function get_num_rows() { return $this->_num_rows; } /** * @return int */ public function get_num_cols() { return $this->_num_cols; } /** * @return array */ public function &get_columns() { return $this->_columns; } /** * @param $columns */ public function set_columns($columns) { $this->_columns = $columns; } /** * @param int $i * * @return mixed */ public function &get_column($i) { if (!isset($this->_columns[$i])) { $this->_columns[$i] = [ "x" => 0, "min-width" => 0, "max-width" => 0, "used-width" => null, "absolute" => 0, "percent" => 0, "auto" => true, ]; } return $this->_columns[$i]; } /** * @return array */ public function &get_rows() { return $this->_rows; } /** * @param int $j * * @return mixed */ public function &get_row($j) { if (!isset($this->_rows[$j])) { $this->_rows[$j] = [ "y" => 0, "first-column" => 0, "height" => null, ]; } return $this->_rows[$j]; } /** * @param int $i * @param int $j * @param mixed $h_v * @param null|mixed $prop * * @return mixed */ public function get_border($i, $j, $h_v, $prop = null) { if (!isset($this->_borders[$i][$j][$h_v])) { $this->_borders[$i][$j][$h_v] = [ "width" => 0, "style" => "solid", "color" => "black", ]; } if (isset($prop)) { return $this->_borders[$i][$j][$h_v][$prop]; } return $this->_borders[$i][$j][$h_v]; } /** * @param int $i * @param int $j * * @return array */ public function get_border_properties($i, $j) { return [ "top" => $this->get_border($i, $j, "horizontal"), "right" => $this->get_border($i, $j + 1, "vertical"), "bottom" => $this->get_border($i + 1, $j, "horizontal"), "left" => $this->get_border($i, $j, "vertical"), ]; } /** * @param Frame $frame * * @return array|null */ public function get_spanned_cells(Frame $frame) { $key = $frame->get_id(); if (isset($this->_frames[$key])) { return $this->_frames[$key]; } return null; } /** * @param Frame $frame * * @return bool */ public function frame_exists_in_cellmap(Frame $frame) { $key = $frame->get_id(); return isset($this->_frames[$key]); } /** * @param Frame $frame * * @return array * @throws Exception */ public function get_frame_position(Frame $frame) { global $_dompdf_warnings; $key = $frame->get_id(); if (!isset($this->_frames[$key])) { throw new Exception("Frame not found in cellmap"); } // Positions are stored relative to the table position [$table_x, $table_y] = $this->_table->get_position(); $col = $this->_frames[$key]["columns"][0]; $row = $this->_frames[$key]["rows"][0]; if (!isset($this->_columns[$col])) { $_dompdf_warnings[] = "Frame not found in columns array. Check your table layout for missing or extra TDs."; $x = $table_x; } else { $x = $table_x + $this->_columns[$col]["x"]; } if (!isset($this->_rows[$row])) { $_dompdf_warnings[] = "Frame not found in row array. Check your table layout for missing or extra TDs."; $y = $table_y; } else { $y = $table_y + $this->_rows[$row]["y"]; } return [$x, $y, "x" => $x, "y" => $y]; } /** * @param Frame $frame * * @return int * @throws Exception */ public function get_frame_width(Frame $frame) { $key = $frame->get_id(); if (!isset($this->_frames[$key])) { throw new Exception("Frame not found in cellmap"); } $cols = $this->_frames[$key]["columns"]; $w = 0; foreach ($cols as $i) { $w += $this->_columns[$i]["used-width"]; } return $w; } /** * @param Frame $frame * * @return int * @throws Exception * @throws Exception */ public function get_frame_height(Frame $frame) { $key = $frame->get_id(); if (!isset($this->_frames[$key])) { throw new Exception("Frame not found in cellmap"); } $rows = $this->_frames[$key]["rows"]; $h = 0; foreach ($rows as $i) { if (!isset($this->_rows[$i])) { throw new Exception("The row #$i could not be found, please file an issue in the tracker with the HTML code"); } $h += $this->_rows[$i]["height"]; } return $h; } /** * @param int $j * @param mixed $width */ public function set_column_width($j, $width) { if ($this->_columns_locked) { return; } $col =& $this->get_column($j); $col["used-width"] = $width; $next_col =& $this->get_column($j + 1); $next_col["x"] = $col["x"] + $width; } /** * @param int $i * @param long $height */ public function set_row_height($i, $height) { $row =& $this->get_row($i); if ($height > $row["height"]) { $row["height"] = $height; } $next_row =& $this->get_row($i + 1); $next_row["y"] = $row["y"] + $row["height"]; } /** * https://www.w3.org/TR/CSS21/tables.html#border-conflict-resolution * * @param int $i * @param int $j * @param string $h_v * @param array $border_spec */ protected function _resolve_border($i, $j, $h_v, $border_spec) { if (!isset($this->_borders[$i][$j][$h_v])) { $this->_borders[$i][$j][$h_v] = $border_spec; return; } $border = $this->_borders[$i][$j][$h_v]; $n_width = $border_spec["width"]; $n_style = $border_spec["style"]; $o_width = $border["width"]; $o_style = $border["style"]; if ($o_style === "hidden") { return; } // A style of `none` has lowest priority independent of its specified // width here, as its resolved width is always 0 if ($n_style === "hidden" || $n_width > $o_width || ($o_width == $n_width && isset(self::$_BORDER_STYLE_SCORE[$n_style]) && isset(self::$_BORDER_STYLE_SCORE[$o_style]) && self::$_BORDER_STYLE_SCORE[$n_style] > self::$_BORDER_STYLE_SCORE[$o_style]) ) { $this->_borders[$i][$j][$h_v] = $border_spec; } } /** * Get the resolved border properties for the given frame. * * @param AbstractFrameDecorator $frame * * @return array[] */ protected function get_resolved_border(AbstractFrameDecorator $frame): array { $key = $frame->get_id(); $columns = $this->_frames[$key]["columns"]; $rows = $this->_frames[$key]["rows"]; $first_col = $columns[0]; $last_col = $columns[count($columns) - 1]; $first_row = $rows[0]; $last_row = $rows[count($rows) - 1]; $max_top = null; $max_bottom = null; $max_left = null; $max_right = null; foreach ($columns as $col) { $top = $this->_borders[$first_row][$col]["horizontal"]; $bottom = $this->_borders[$last_row + 1][$col]["horizontal"]; if ($max_top === null || $top["width"] > $max_top["width"]) { $max_top = $top; } if ($max_bottom === null || $bottom["width"] > $max_bottom["width"]) { $max_bottom = $bottom; } } foreach ($rows as $row) { $left = $this->_borders[$row][$first_col]["vertical"]; $right = $this->_borders[$row][$last_col + 1]["vertical"]; if ($max_left === null || $left["width"] > $max_left["width"]) { $max_left = $left; } if ($max_right === null || $right["width"] > $max_right["width"]) { $max_right = $right; } } return [$max_top, $max_right, $max_bottom, $max_left]; } /** * @param AbstractFrameDecorator $frame */ public function add_frame(Frame $frame): void { $style = $frame->get_style(); $display = $style->display; $collapse = $this->_table->get_style()->border_collapse === "collapse"; // Recursively add the frames within the table, its row groups and rows if ($frame === $this->_table || $display === "table-row" || in_array($display, TableFrameDecorator::$ROW_GROUPS, true) ) { $start_row = $this->__row; foreach ($frame->get_children() as $child) { $this->add_frame($child); } if ($display === "table-row") { $this->add_row(); } $num_rows = $this->__row - $start_row - 1; $key = $frame->get_id(); // Row groups always span across the entire table $this->_frames[$key]["columns"] = range(0, max(0, $this->_num_cols - 1)); $this->_frames[$key]["rows"] = range($start_row, max(0, $this->__row - 1)); $this->_frames[$key]["frame"] = $frame; if ($collapse) { $bp = $style->get_border_properties(); // Resolve vertical borders for ($i = 0; $i < $num_rows + 1; $i++) { $this->_resolve_border($start_row + $i, 0, "vertical", $bp["left"]); $this->_resolve_border($start_row + $i, $this->_num_cols, "vertical", $bp["right"]); } // Resolve horizontal borders for ($j = 0; $j < $this->_num_cols; $j++) { $this->_resolve_border($start_row, $j, "horizontal", $bp["top"]); $this->_resolve_border($this->__row, $j, "horizontal", $bp["bottom"]); } if ($frame === $this->_table) { // Clear borders because the cells are now using them. The // border width still needs to be set to half the resolved // width so that the table is positioned properly [$top, $right, $bottom, $left] = $this->get_resolved_border($frame); $style->set_used("border_top_width", $top["width"] / 2); $style->set_used("border_right_width", $right["width"] / 2); $style->set_used("border_bottom_width", $bottom["width"] / 2); $style->set_used("border_left_width", $left["width"] / 2); $style->set_used("border_style", "none"); } else { // Clear borders for rows and row groups $style->set_used("border_width", 0); $style->set_used("border_style", "none"); } } if ($frame === $this->_table) { // Apply resolved borders to table cells and calculate column // widths after all frames have been added $this->calculate_column_widths(); } return; } // Add the frame to the cellmap $key = $frame->get_id(); $node = $frame->get_node(); $bp = $style->get_border_properties(); // Determine where this cell is going $colspan = max((int) $node->getAttribute("colspan"), 1); $rowspan = max((int) $node->getAttribute("rowspan"), 1); // Find the next available column (fix by Ciro Mondueri) $ac = $this->__col; while (isset($this->_cells[$this->__row][$ac])) { $ac++; } $this->__col = $ac; // Rows: for ($i = 0; $i < $rowspan; $i++) { $row = $this->__row + $i; $this->_frames[$key]["rows"][] = $row; for ($j = 0; $j < $colspan; $j++) { $this->_cells[$row][$this->__col + $j] = $frame; } if ($collapse) { // Resolve vertical borders $this->_resolve_border($row, $this->__col, "vertical", $bp["left"]); $this->_resolve_border($row, $this->__col + $colspan, "vertical", $bp["right"]); } } // Columns: for ($j = 0; $j < $colspan; $j++) { $col = $this->__col + $j; $this->_frames[$key]["columns"][] = $col; if ($collapse) { // Resolve horizontal borders $this->_resolve_border($this->__row, $col, "horizontal", $bp["top"]); $this->_resolve_border($this->__row + $rowspan, $col, "horizontal", $bp["bottom"]); } } $this->_frames[$key]["frame"] = $frame; $this->__col += $colspan; if ($this->__col > $this->_num_cols) { $this->_num_cols = $this->__col; } } /** * Apply resolved borders to table cells and calculate column widths. */ protected function calculate_column_widths(): void { $table = $this->_table; $table_style = $table->get_style(); $collapse = $table_style->border_collapse === "collapse"; if ($collapse) { $v_spacing = 0; $h_spacing = 0; } else { // The additional 1/2 width gets added to the table proper [$h, $v] = $table_style->border_spacing; $v = $table_style->length_in_pt($v); $h = $table_style->length_in_pt($h); $v_spacing = is_numeric($v) ? $v / 2 : $v; $h_spacing = is_numeric($v) ? $h / 2 : $h; } foreach ($this->_frames as $frame_info) { /** @var TableCellFrameDecorator */ $frame = $frame_info["frame"]; $style = $frame->get_style(); $display = $style->display; if ($display !== "table-cell") { continue; } if ($collapse) { // Set the resolved border at half width [$top, $right, $bottom, $left] = $this->get_resolved_border($frame); $style->set_used("border_top_width", $top["width"] / 2); $style->set_used("border_top_style", $top["style"]); $style->set_used("border_top_color", $top["color"]); $style->set_used("border_right_width", $right["width"] / 2); $style->set_used("border_right_style", $right["style"]); $style->set_used("border_right_color", $right["color"]); $style->set_used("border_bottom_width", $bottom["width"] / 2); $style->set_used("border_bottom_style", $bottom["style"]); $style->set_used("border_bottom_color", $bottom["color"]); $style->set_used("border_left_width", $left["width"] / 2); $style->set_used("border_left_style", $left["style"]); $style->set_used("border_left_color", $left["color"]); $style->set_used("margin", 0); } else { // Border spacing is effectively a margin between cells $style->set_used("margin_top", $v_spacing); $style->set_used("margin_bottom", $v_spacing); $style->set_used("margin_left", $h_spacing); $style->set_used("margin_right", $h_spacing); } if ($this->_columns_locked) { continue; } $node = $frame->get_node(); $colspan = max((int) $node->getAttribute("colspan"), 1); $first_col = $frame_info["columns"][0]; // Resolve the frame's width if ($this->_fixed_layout) { list($frame_min, $frame_max) = [0, 10e-10]; } else { list($frame_min, $frame_max) = $frame->get_min_max_width(); } $width = $style->width; $val = null; if (Helpers::is_percent($width) && $colspan === 1) { $var = "percent"; $val = (float)rtrim($width, "% "); } elseif ($width !== "auto" && $colspan === 1) { $var = "absolute"; $val = $frame_min; } $min = 0; $max = 0; for ($cs = 0; $cs < $colspan; $cs++) { // Resolve the frame's width(s) with other cells $col =& $this->get_column($first_col + $cs); // Note: $var is either 'percent' or 'absolute'. We compare the // requested percentage or absolute values with the existing widths // and adjust accordingly. if (isset($var) && $val > $col[$var]) { $col[$var] = $val; $col["auto"] = false; } $min += $col["min-width"]; $max += $col["max-width"]; } if ($frame_min > $min && $colspan === 1) { // The frame needs more space. Expand each sub-column // FIXME try to avoid putting this dummy value when table-layout:fixed $inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_min - $min)); for ($c = 0; $c < $colspan; $c++) { $col =& $this->get_column($first_col + $c); $col["min-width"] += $inc; } } if ($frame_max > $max) { // FIXME try to avoid putting this dummy value when table-layout:fixed $inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_max - $max) / $colspan); for ($c = 0; $c < $colspan; $c++) { $col =& $this->get_column($first_col + $c); $col["max-width"] += $inc; } } } } /** * */ public function add_row() { $this->__row++; $this->_num_rows++; // Find the next available column $i = 0; while (isset($this->_cells[$this->__row][$i])) { $i++; } $this->__col = $i; } /** * Remove a row from the cellmap. * * @param Frame */ public function remove_row(Frame $row) { $key = $row->get_id(); if (!isset($this->_frames[$key])) { return; // Presumably this row has already been removed } $this->__row = $this->_num_rows--; $rows = $this->_frames[$key]["rows"]; $columns = $this->_frames[$key]["columns"]; // Remove all frames from this row foreach ($rows as $r) { foreach ($columns as $c) { if (isset($this->_cells[$r][$c])) { $id = $this->_cells[$r][$c]->get_id(); $this->_cells[$r][$c] = null; unset($this->_cells[$r][$c]); // has multiple rows? if (isset($this->_frames[$id]) && count($this->_frames[$id]["rows"]) > 1) { // remove just the desired row, but leave the frame if (($row_key = array_search($r, $this->_frames[$id]["rows"])) !== false) { unset($this->_frames[$id]["rows"][$row_key]); } continue; } $this->_frames[$id] = null; unset($this->_frames[$id]); } } $this->_rows[$r] = null; unset($this->_rows[$r]); } $this->_frames[$key] = null; unset($this->_frames[$key]); } /** * Remove a row group from the cellmap. * * @param Frame $group The group to remove */ public function remove_row_group(Frame $group) { $key = $group->get_id(); if (!isset($this->_frames[$key])) { return; // Presumably this row has already been removed } $iter = $group->get_first_child(); while ($iter) { $this->remove_row($iter); $iter = $iter->get_next_sibling(); } $this->_frames[$key] = null; unset($this->_frames[$key]); } /** * Update a row group after rows have been removed * * @param Frame $group The group to update * @param Frame $last_row The last row in the row group */ public function update_row_group(Frame $group, Frame $last_row) { $g_key = $group->get_id(); $first_index = $this->_frames[$g_key]["rows"][0]; $last_index = $first_index; $row = $last_row; while ($row = $row->get_prev_sibling()) { $last_index++; } $this->_frames[$g_key]["rows"] = range($first_index, $last_index); } /** * */ public function assign_x_positions() { // Pre-condition: widths must be resolved and assigned to columns and // column[0]["x"] must be set. if ($this->_columns_locked) { return; } $x = $this->_columns[0]["x"]; foreach (array_keys($this->_columns) as $j) { $this->_columns[$j]["x"] = $x; $x += $this->_columns[$j]["used-width"]; } } /** * */ public function assign_frame_heights() { // Pre-condition: widths and heights of each column & row must be // calcluated foreach ($this->_frames as $arr) { $frame = $arr["frame"]; $h = 0; foreach ($arr["rows"] as $row) { if (!isset($this->_rows[$row])) { // The row has been removed because of a page split, so skip it. continue; } $h += $this->_rows[$row]["height"]; } if ($frame instanceof TableCellFrameDecorator) { $frame->set_cell_height($h); } else { $frame->get_style()->height = $h; } } } /** * Re-adjust frame height if the table height is larger than its content */ public function set_frame_heights($table_height, $content_height) { // Distribute the increased height proportionally amongst each row foreach ($this->_frames as $arr) { $frame = $arr["frame"]; $h = 0; foreach ($arr["rows"] as $row) { if (!isset($this->_rows[$row])) { continue; } $h += $this->_rows[$row]["height"]; } if ($content_height > 0) { $new_height = ($h / $content_height) * $table_height; } else { $new_height = 0; } if ($frame instanceof TableCellFrameDecorator) { $frame->set_cell_height($new_height); } else { $frame->get_style()->height = $new_height; } } } /** * Used for debugging: * * @return string */ public function __toString() { $str = ""; $str .= "Columns:
    "; $str .= Helpers::pre_r($this->_columns, true); $str .= "Rows:
    "; $str .= Helpers::pre_r($this->_rows, true); $str .= "Frames:
    "; $arr = []; foreach ($this->_frames as $key => $val) { $arr[$key] = ["columns" => $val["columns"], "rows" => $val["rows"]]; } $str .= Helpers::pre_r($arr, true); if (php_sapi_name() == "cli") { $str = strip_tags(str_replace(["
    ", "", ""], ["\n", chr(27) . "[01;33m", chr(27) . "[0m"], $str)); } return $str; } } PK!#t7convertformstools/pdf/dompdf/src/JavascriptEmbedder.phpnu[ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf; /** * Embeds Javascript into the PDF document * * @package dompdf */ class JavascriptEmbedder { /** * @var Dompdf */ protected $_dompdf; /** * JavascriptEmbedder constructor. * * @param Dompdf $dompdf */ public function __construct(Dompdf $dompdf) { $this->_dompdf = $dompdf; } /** * @param $script */ public function insert($script) { $this->_dompdf->getCanvas()->javascript($script); } /** * @param Frame $frame */ public function render(Frame $frame) { if (!$this->_dompdf->getOptions()->getIsJavascriptEnabled()) { return; } $this->insert($frame->get_node()->nodeValue); } } PK!~))0convertformstools/pdf/dompdf/src/Image/Cache.phpnu[ * @author Helmut Tischer * @author Fabien Ménager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Image; use Dompdf\Dompdf; use Dompdf\Helpers; use Dompdf\Exception\ImageException; /** * Static class that resolves image urls and downloads and caches * remote images if required. * * @package dompdf */ class Cache { /** * Array of downloaded images. Cached so that identical images are * not needlessly downloaded. * * @var array */ protected static $_cache = []; /** * @var array */ protected static $tempImages = []; /** * The url to the "broken image" used when images can't be loaded * * @var string */ public static $broken_image = "data:image/svg+xml;charset=utf8,%3C?xml version='1.0'?%3E%3Csvg width='64' height='64' xmlns='http://www.w3.org/2000/svg'%3E%3Cg%3E%3Crect stroke='%23666666' id='svg_1' height='60.499994' width='60.166667' y='1.666669' x='1.999998' stroke-width='1.5' fill='none'/%3E%3Cline stroke-linecap='null' stroke-linejoin='null' id='svg_3' y2='59.333253' x2='59.749916' y1='4.333415' x1='4.250079' stroke-width='1.5' stroke='%23999999' fill='none'/%3E%3Cline stroke-linecap='null' stroke-linejoin='null' id='svg_4' y2='59.999665' x2='4.062838' y1='3.750342' x1='60.062164' stroke-width='1.5' stroke='%23999999' fill='none'/%3E%3C/g%3E%3C/svg%3E"; public static $error_message = "Image not found or type unknown"; /** * Current dompdf instance * * @var Dompdf */ protected static $_dompdf; /** * Resolve and fetch an image for use. * * @param string $url The url of the image * @param string $protocol Default protocol if none specified in $url * @param string $host Default host if none specified in $url * @param string $base_path Default path if none specified in $url * @param Dompdf $dompdf The Dompdf instance * * @throws ImageException * @return array An array with two elements: The local path to the image and the image extension */ static function resolve_url($url, $protocol, $host, $base_path, Dompdf $dompdf) { self::$_dompdf = $dompdf; $protocol = mb_strtolower($protocol); $parsed_url = Helpers::explode_url($url); $message = null; $remote = ($protocol && $protocol !== "file://") || ($parsed_url['protocol'] !== ""); $data_uri = strpos($parsed_url['protocol'], "data:") === 0; $full_url = null; $enable_remote = $dompdf->getOptions()->getIsRemoteEnabled(); $tempfile = false; try { // Remote not allowed and is not DataURI if (!$enable_remote && $remote && !$data_uri) { throw new ImageException("Remote file access is disabled.", E_WARNING); } // remote allowed or DataURI if (($enable_remote && $remote) || $data_uri) { // Download remote files to a temporary directory $full_url = Helpers::build_url($protocol, $host, $base_path, $url); // From cache if (isset(self::$_cache[$full_url])) { $resolved_url = self::$_cache[$full_url]; } // From remote else { $tmp_dir = $dompdf->getOptions()->getTempDir(); if (($resolved_url = @tempnam($tmp_dir, "ca_dompdf_img_")) === false) { throw new ImageException("Unable to create temporary image in " . $tmp_dir, E_WARNING); } $tempfile = $resolved_url; $image = null; if ($data_uri) { if ($parsed_data_uri = Helpers::parse_data_uri($url)) { $image = $parsed_data_uri['data']; } } else { list($image, $http_response_header) = Helpers::getFileContent($full_url, $dompdf->getHttpContext()); } // Image not found or invalid if ($image === null) { $msg = ($data_uri ? "Data-URI could not be parsed" : "Image not found"); throw new ImageException($msg, E_WARNING); } // Image found, put in cache and process else { //e.g. fetch.php?media=url.jpg&cache=1 //- Image file name might be one of the dynamic parts of the url, don't strip off! //- a remote url does not need to have a file extension at all //- local cached file does not have a matching file extension //Therefore get image type from the content if (@file_put_contents($resolved_url, $image) === false) { throw new ImageException("Unable to create temporary image in " . $tmp_dir, E_WARNING); } } } } // Not remote, local image else { $resolved_url = Helpers::build_url($protocol, $host, $base_path, $url); if ($protocol === "" || $protocol === "file://") { $realfile = realpath($resolved_url); $rootDir = realpath($dompdf->getOptions()->getRootDir()); if (strpos($realfile, $rootDir) !== 0) { $chroot = $dompdf->getOptions()->getChroot(); $chrootValid = false; foreach ($chroot as $chrootPath) { $chrootPath = realpath($chrootPath); if ($chrootPath !== false && strpos($realfile, $chrootPath) === 0) { $chrootValid = true; break; } } if ($chrootValid !== true) { throw new ImageException("Permission denied on $resolved_url. The file could not be found under the paths specified by Options::chroot.", E_WARNING); } } if (!$realfile) { throw new ImageException("File '$realfile' not found.", E_WARNING); } $resolved_url = $realfile; } } // Check if the local file is readable if (!is_readable($resolved_url) || !filesize($resolved_url)) { throw new ImageException("Image not readable or empty", E_WARNING); } // Check is the file is an image else { list($width, $height, $type) = Helpers::dompdf_getimagesize($resolved_url, $dompdf->getHttpContext()); // Known image type if ($width && $height && in_array($type, ["gif", "png", "jpeg", "bmp", "svg","webp"], true)) { //Don't put replacement image into cache - otherwise it will be deleted on cache cleanup. //Only execute on successful caching of remote image. if ($enable_remote && $remote || $data_uri) { self::$_cache[$full_url] = $resolved_url; } } // Unknown image type else { throw new ImageException("Image type unknown", E_WARNING); } } } catch (ImageException $e) { if ($tempfile) { unlink($tempfile); } $resolved_url = self::$broken_image; $type = "png"; $message = self::$error_message; Helpers::record_warnings($e->getCode(), $e->getMessage() . " \n $url", $e->getFile(), $e->getLine()); self::$_cache[$full_url] = $resolved_url; } return [$resolved_url, $type, $message]; } /** * Register a temp file for the given original image file. * * @param string $filePath The path of the original image. * @param string $tempPath The path of the temp file to register. * @param string $key An optional key to register the temp file at. */ static function addTempImage(string $filePath, string $tempPath, string $key = "default"): void { if (!isset(self::$tempImages[$filePath])) { self::$tempImages[$filePath] = []; } self::$tempImages[$filePath][$key] = $tempPath; } /** * Get the path of a temp file registered for the given original image file. * * @param string $filePath The path of the original image. * @param string $key The key the temp file is registered at. */ static function getTempImage(string $filePath, string $key = "default"): ?string { return self::$tempImages[$filePath][$key] ?? null; } /** * Unlink all cached images (i.e. temporary images either downloaded * or converted) except for the bundled "broken image" */ static function clear(bool $debugPng = false) { foreach (self::$_cache as $file) { if ($file === self::$broken_image) { continue; } if ($debugPng) { print "[clear unlink $file]"; } unlink($file); } foreach (self::$tempImages as $versions) { foreach ($versions as $file) { if ($file === self::$broken_image) { continue; } if ($debugPng) { print "[unlink temp image $file]"; } if (file_exists($file)) { unlink($file); } } } self::$_cache = []; self::$tempImages = []; } static function detect_type($file, $context = null) { list(, , $type) = Helpers::dompdf_getimagesize($file, $context); return $type; } static function is_broken($url) { return $url === self::$broken_image; } } if (file_exists(realpath(__DIR__ . "/../../lib/res/broken_image.svg"))) { Cache::$broken_image = realpath(__DIR__ . "/../../lib/res/broken_image.svg"); } PK!l 3convertformstools/pdf/dompdf/src/Css/Stylesheet.phpnu[ * @author Helmut Tischer * @author Fabien Ménager * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ namespace Dompdf\Css; use DOMElement; use DOMXPath; use Dompdf\Dompdf; use Dompdf\Helpers; use Dompdf\Exception; use Dompdf\FontMetrics; use Dompdf\Frame\FrameTree; /** * The master stylesheet class * * The Stylesheet class is responsible for parsing stylesheets and style * tags/attributes. It also acts as a registry of the individual Style * objects generated by the current set of loaded CSS files and style * elements. * * @see Style * @package dompdf */ class Stylesheet { /** * The location of the default built-in CSS file. */ const DEFAULT_STYLESHEET = "/lib/res/html.css"; /** * User agent stylesheet origin * * @var int */ const ORIG_UA = 1; /** * User normal stylesheet origin * * @var int */ const ORIG_USER = 2; /** * Author normal stylesheet origin * * @var int */ const ORIG_AUTHOR = 3; /* * The highest possible specificity is 0x01000000 (and that is only for author * stylesheets, as it is for inline styles). Origin precedence can be achieved by * adding multiples of 0x10000000 to the actual specificity. Important * declarations are handled in Style; though technically they should be handled * here so that user important declarations can be made to take precedence over * user important declarations, this doesn't matter in practice as Dompdf does * not support user stylesheets, and user agent stylesheets can not include * important declarations. */ private static $_stylesheet_origins = [ self::ORIG_UA => 0x00000000, // user agent declarations self::ORIG_USER => 0x10000000, // user normal declarations self::ORIG_AUTHOR => 0x30000000, // author normal declarations ]; /** * Non-CSS presentational hints (i.e. HTML 4 attributes) are handled as if added * to the beginning of an author stylesheet, i.e. anything in author stylesheets * should override them. */ const SPEC_NON_CSS = 0x20000000; /** * Current dompdf instance * * @var Dompdf */ private $_dompdf; /** * Array of currently defined styles * * @var Style[] */ private $_styles; /** * Base protocol of the document being parsed * Used to handle relative urls. * * @var string */ private $_protocol = ""; /** * Base hostname of the document being parsed * Used to handle relative urls. * * @var string */ private $_base_host = ""; /** * Base path of the document being parsed * Used to handle relative urls. * * @var string */ private $_base_path = ""; /** * The styles defined by @page rules * * @var array[TEMPLATE]'; /** * Validates and creates the PDF * * @param object $submission * * @return void */ public static function createSubmissionPDF($submission) { // pdf enabled check if (!self::isPDFEnabled($submission)) { return; } $pdf = $submission->form->pdf; // Prepare the PDF's template with content plugins. // This enables us to create a shared template with the Custom Module and // load it across different forms using the {loadmoduleid ID} syntax. $pdf['pdf_template'] = \JHtml::_('content.prepare', $pdf['pdf_template']); // set filename prefix $prefix = (isset($pdf['pdf_filename_prefix']) && !empty($pdf['pdf_filename_prefix'])) ? $pdf['pdf_filename_prefix'] . '_' : ''; // append the _{submission.id] suffix to each file name $pdf['pdf_filename'] = $prefix . '{submission.id}'; // replace Smart Tags $pdf = \ConvertForms\SmartTags::replace($pdf, $submission); // Make safe after the Smart Tags replacement $pdf['pdf_filename'] = self::makeSafe($pdf['pdf_filename']); // upload folder check if (!$upload_folder = $pdf['pdf_upload_folder']) { return; } $upload_folder = rtrim($upload_folder, '/'); // make sure upload folder exists and is writable if (!\NRFramework\File::createDirs(JPATH_ROOT . '/' . $upload_folder)) { return; } $file_path = $pdf['pdf_upload_folder'] . '/' . $pdf['pdf_filename'] . '.pdf'; // make sure the file exists if (!\JFile::exists(JPATH_ROOT . '/' . $file_path)) { // Convert all relative paths found in and elements to absolute URLs $pdf_template = URLHelper::relativePathsToAbsoluteURLs($pdf['pdf_template']); self::create($upload_folder, $pdf_template, $pdf['pdf_filename']); \ConvertForms\SubmissionMeta::add($submission->id, 'pdf', '', $file_path); return JURI::root() . $file_path; } return self::getSubmissionPDF($submission); } /** * Creates a PDF given the upload folder and filename * * @param string $upload_folder The upload folder * @param string $content The content of the PDF * @param string $filename The filename * * @return void */ public static function create($upload_folder, $content, $filename) { // include domPDF library require JPATH_SITE . '/plugins/convertformstools/pdf/dompdf/autoload.inc.php'; // replace [TEMPLATE] with given pdf contents $pdf_html = str_replace('[TEMPLATE]', $content, self::$html); // reference the Dompdf namespace $options = new \Dompdf\Options(); $options->setIsRemoteEnabled(true); // instantiate and use the dompdf class $dompdf = new \Dompdf\Dompdf($options); $dompdf->loadHtml($pdf_html); // Render the HTML as PDF $dompdf->render(); $output = $dompdf->output(); $destination_filename = \JPath::clean(JPATH_ROOT . '/' . $upload_folder . '/' . self::makeSafe($filename) . '.pdf'); file_put_contents($destination_filename, $output); } /** * Retrieves the submission PDF * * @param object $submission * * @return string */ public static function getSubmissionPDF($submission) { if (!isset($submission->form->pdf)) { return; } if (!$file_path = \ConvertForms\SubmissionMeta::getValue($submission->id, 'pdf')) { return; } // make sure the file exists if (!\JFile::exists(JPATH_ROOT . '/' . $file_path)) { return; } return JURI::root() . $file_path; } /** * Sanitizes the file name * * @param string $filename * * @return string */ public static function makeSafe($filename) { // Sanitize filename $filename = \JFile::makeSafe($filename); // Replace spaces with underscore $filename = str_replace(' ', '_', $filename); return $filename; } /** * Checks whether we have PDF enabled * * @param object $submission * * @return boolean */ public static function isPDFEnabled($submission) { return isset($submission->form->pdf['pdf_enabled']) && $submission->form->pdf['pdf_enabled'] == '1'; } }PK!xkkconvertformstools/pdf/pdf.xmlnu[ PLG_CONVERTFORMSTOOLS_PDF PLG_CONVERTFORMSTOOLS_PDF_DESC 1.0 February 2020 Copyright © 2020 Tassos Marinos All Rights Reserved http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL Tassos Marinos (Tassos.gr) info@tassos.gr http://www.tassos.gr script.install.php pdf.php script.install.helper.php form language dompdf helper fields PK!,f**#convertformstools/pdf/form/form.xmlnu[
    PK!m-EE)convertformstools/pdf/form/submission.xmlnu[
    PK!OK__Tconvertformstools/gatracker/language/ru-RU/ru-RU.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Конвертировать формы - Google Analytics Tracker" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Отслеживание Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Отслеживать события формы с помощью своего аккаунта Google Analytics.

    Поддерживаются следующие события: Загрузить , который отслеживается при загрузке страницы, Конверсия , которая отслеживается, когда форма была успешно отправлена, и ошибка регистрируется при возникновении ошибки.

    Зарегистрированные данные можно найти в вашей учетной записи Google Analytics в разделе \"Поведение -> События\". отслеживается по умолчанию в категории \"Преобразование форм\". " PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="Идентификатор отслеживания" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Ваш идентификатор отслеживания Google Analytics." PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Включить отслеживание с помощью Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Идентификатор отслеживания Google Analytics отсутствует." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Установить сейчас" PK!Tconvertformstools/gatracker/language/ca-ES/ca-ES.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms - Google Analytics Tracker" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Rastrejador Google analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Rastreja esdeveniments de formulari amb el teu compte Google Analytics.

    Els esdeveniments suportats son: Carregar que rastreja durant la càrrega de la pagina, Conversió que rastreja quan s'envia amb èxit el formulari i Error que rastreja sempre que hi ha un error.

    Les dades rastrejades es poden trobar a la secció Comportament -> Esdeveniments del teu compte Google Analytics. Per defecte, tots els esdeveniments es registren dins la categoria Convert Forms." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="ID de rastreig" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="La teva ID de rastreig Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Activa el rastreig amb Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Falta l'ID de rastreig de Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Definir ara" PK!C-''Tconvertformstools/gatracker/language/bg-BG/bg-BG.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms – Google Analytics Tracker" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Google Analytics проследяване" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Проследявайте събития във формуляра с акаунт в Google Анализ.

    Поддържаните събития са: Зареждане, което се проследява по време на зареждането на страницата, Преобразуване, което се проследява, когато формулярът е успешно изпратен, и Грешка, която се проследява, когато възникне грешка.

    Проследяваните данни могат да бъдат намерени под Поведение -> раздел „Събития“ в профила ви в Google Analytics. Всички събития се проследяват под категорията Convert Forms по подразбиране." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="Tracking ID / Номер проследяване" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Вашият Google Analytics ID номер проследяване" PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Активиране на проследяването с Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Липсва Google Analytics ID номер проследяване" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Задайте сега" PK!|_  Tconvertformstools/gatracker/language/cs-CZ/cs-CZ.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms - Google Analytics sledování" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Google Analytics sledování" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Sledujte události ve formuláři za pomoci vašeho účtu Google Analytics.

    Podporované události jsou: Načtení, je zaznamenán v průběhu načítání stránky, Konverze, která se zaznamená v případě úspěšného odeslání formuláře a Chyba, která se zanamená v případě chyby.

    Sledovací data najdete v menu Chování -> Události ve vašem účtu Google Analytics. Všechny události jsou zanamenány ve výchozím nastavení v kategorii Convert Forms." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="Sledovací ID" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Vaše Google Analytics sledovací ID." PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Zapnout sledování s Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Chybí sledovací ID Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Nastavit nyní" PK! ffTconvertformstools/gatracker/language/es-ES/es-ES.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convertir formularios - Rastreador de Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Seguimiento de Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Realice un seguimiento de los eventos del formulario con su cuenta de Google Analytics. Los eventos admitidos son: carga que se realiza un seguimiento durante la carga de la página, conversión que realiza un seguimiento cuando el formulario se envía correctamente y error que realiza un seguimiento cada vez que se produce un error. Los datos rastreados se pueden encontrar en la sección Comportamiento -> Eventos de su cuenta de Google Analytics. Todos los eventos se rastrean en la categoría Convertir formularios de forma predeterminada." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="ID de rastreo" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Su ID de seguimiento de Google Analytics." PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Habilite el seguimiento con Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Falta su ID de seguimiento de Google Analytics." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Configurar ahora" PK!?Bo=Tconvertformstools/gatracker/language/fi-FI/fi-FI.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms - Google Analytics Tracker" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Google Analytics Tracking" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Seuraa lomaketapahtumia Google Analytics -tililläsi.

    The supported events are: Kuormitus jota seurataan sivun lataamisen aikana, Tulos jota seurataan, kun lomake lähetetään onnistuneesti, jaVirhe jota seurataan aina, kun tapahtuu virhe.

    Seuratut tiedot löytyvät Käyttäytyminen -> Tapahtumat-osio Google Analytics -tililläsi.. Kaikkia tapahtumia seurataan oletusarvoisesti Convert Formsissa." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="Seuranta ID" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Sinun Google Analytics seuranta ID." PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Ota seuranta käyttöön Google Analyticsilla" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Google Analytics seuranta ID on kadonnut." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Aseta nyt" PK!qTconvertformstools/gatracker/language/en-GB/en-GB.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms - Google Analytics Tracker" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Google Analytics Tracking" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Track form events with your Google Analytics account.

    The supported events are: Load which is tracked during page load, Conversion which is tracked when the form is successfully submitted and Error which is tracked whenever an error is occured.

    Tracked data can be found under the Behavior -> Events section of your Google Analytics account. All events are tracked under the Convert Forms category by default." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="Tracking ID" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Your Google Analytics Tracking ID." PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Enable tracking with Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="The Google Analytics Tracking ID is missing." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Set Now"PK!IsXconvertformstools/gatracker/language/en-GB/en-GB.plg_convertformstools_gatracker.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms - Google Analytics Tracker" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="This plugin enables you to track form impressions and conversions events with your Google Analytics account."PK!Tconvertformstools/gatracker/language/sv-SE/sv-SE.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms - Google Analytics Spårare" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Google Analytics spårning" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Spåra formulärhändelser med ditt Google Analytics-konto.

    De händelser som stöds är: belastning som spåras under sidladdning, omvandling som spåras när formuläret har skickats in och fel som spåras när ett fel inträffar.

    Spårad data kan hittas under Beteende -> Händelser i ditt Google Analytics-konto. Alla händelser spåras under kategorin Convert Forms som standard." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="Spårnings ID" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Ditt Google Analytics spårningsID." PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Aktivera spårning med Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Google Analytics spårnings-ID saknas." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Ställ in nu" PK!Q.55Tconvertformstools/gatracker/language/uk-UA/uk-UA.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Перетворити форми - трекер Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Відстеження Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Відстежуйте події форми з вашим обліковим записом Google Analytics.

    Підтримуються такі події: Завантаження , яка відслідковується при завантаженні сторінки, Конверсія що відстежується після успішного надсилання форми та реєструється помилка , коли виникає помилка.

    Зафіксовані дані можна знайти у вашому обліковому записі Google Analytics у розділі Поведінка -> Події відстежується за замовчуванням у категорії "_QQ_"Перетворити форми"_QQ_". " PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="Ідентифікатор відстеження" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Ваш ідентифікатор відстеження Google Analytics"_QQ_"" PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Увімкнути відстеження за допомогою Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Ідентифікатор відстеження Google Analytics відсутній." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Встановити зараз" PK!uVp,,Tconvertformstools/gatracker/language/fr-FR/fr-FR.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms - Suivi Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Suivi Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Suivez maintenant les événements de formulaires avec votre compte Google Analytics.

    Les événements supportés sont : Load suivi au chargement de la page, Conversion qui est suivi lors d'une soumission réussie du formulaire et Error qui est enregstré dès qu'une erreur survient.

    Le données enregistrées peuvent être trouvées dans la section Comportement -> Evénements de votre compte Google Analytics. Tous les événements sont suivis par défaut dans la catégorie \"Convert Forms\"." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="ID de suivi" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Votre ID de suivi Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Activer le suivi Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="L'ID de suivi Google Analytics est absente " PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Saisissez maintenant" PK!"$77Tconvertformstools/gatracker/language/de-DE/de-DE.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Formulare konvertieren - Google Analytics Tracker" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Google Analytics-Tracking" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Formularereignisse mit Ihrem Google Analytics-Konto nachverfolgen.

    Folgende Ereignisse werden unterstützt: Laden , das beim Laden der Seite nachverfolgt wird, Conversion , das nachverfolgt wird, wann Das Formular wurde erfolgreich gesendet und der Fehler wird protokolliert, wenn ein Fehler auftritt.

    Die protokollierten Daten finden Sie in Ihrem Google Analytics-Konto im Bereich Verhalten -> Ereignisse wird standardmäßig in der Kategorie \"Formulare konvertieren\" nachverfolgt. " PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="Tracking-ID" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Ihre Google Analytics-Tracking-ID." PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Tracking mit Google Analytics aktivieren" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Die Google Analytics-Tracking-ID fehlt." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Jetzt einstellen" PK!,??Tconvertformstools/gatracker/language/it-IT/it-IT.plg_convertformstools_gatracker.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_GATRACKER="Convert Forms - Google Analytics Tracker" PLG_CONVERTFORMSTOOLS_GATRACKER_ALIAS="Monitoraggio Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_DESC="Monitora gli eventi dei moduli dal tuo account Google Analytics.
    Gli eventi supportati sono: Caricamento che è monitorato durante il caricamento di pagina, Conversione che è monitorato quando il modulo è inviato con successo ed Errore che è monitorato ogni qualvolta si verifichi un errore.
    I dati monitorati si trovano nella sezione Comportamenti -> Eventi del tuo account Google Analytics. Tutti gli eventi sono monitorati nella categoria Convert Forms per impostazione predefinita." PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID="ID di monitoraggio" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_DESC="Il tuo ID di monitoraggio di Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_ENABLE="Abilita il monitoraggio con Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING="Manca l'ID di monitoraggio di Google Analytics" PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET="Imposta adesso" PK!ohr995convertformstools/gatracker/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformstoolsGatrackerInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '
    ', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!`>X)convertformstools/gatracker/gatracker.xmlnu[ PLG_CONVERTFORMSTOOLS_GATRACKER PLG_CONVERTFORMSTOOLS_GATRACKER_DESC 1.0 Apr 2019 Copyright © 2020 Tassos Marinos All Rights Reserved http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL Tassos Marinos (Tassos.gr) info@tassos.gr http://www.tassos.gr script.install.php gatracker.php script.install.helper.php language form
    js
    PK!K8)convertformstools/gatracker/gatracker.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class PlgConvertFormsToolsGATracker extends JPlugin { /** * Application Object * * @var object */ protected $app; /** * Auto loads the plugin language file * * @var boolean */ protected $autoloadLanguage = true; /** * Add plugin fields to the form * * @param JForm $form * @param object $data * * @return boolean */ public function onConvertFormsFormPrepareForm($form, $data) { $form->loadFile(__DIR__ . '/form/form.xml', false); return true; } /** * Event triggered during fieldset rendering in the form editing page in the backend. * * @param string $fieldset_name The name of the fieldset is going to be rendered * @param string $fieldset The HTML output of the fieldset * * @return void */ public function onConvertFormsBackendFormPrepareFieldset($fieldset_name, &$fieldset) { if ($this->_name != $fieldset_name) { return; } $tracking_id = $this->params->get('tracking_id'); // Proceed only if Tracking ID is not set yet. if (!empty($tracking_id)) { return; } $extension_id = NRFramework\Extension::getID($this->_name, 'plugin', 'convertformstools'); $url = \JURI::base() . '/index.php?option=com_plugins&task=plugin.edit&extension_id=' . $extension_id; $warning = '
    ' . \JText::_('PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_MISSING') . ' ' . \JText::_("PLG_CONVERTFORMSTOOLS_GATRACKER_TRACKING_ID_SET") . '
    '; $fieldset = $warning . $fieldset; } /** * Undocumented function * * @param [type] $form * * @return void */ public function onConvertFormsFormAfterRender($html, $form) { // Only on front-end if ($this->app->isClient('administrator')) { return; } // Is Google Analytics Tracking enabled for this form? if (! (bool) $form['params']->get('gatracker.enable', false)) { return; } // Make sure we have a valid tracking ID if (!$tracking_id = $this->params->get('tracking_id')) { return; } // Setup settings $doc = JFactory::getDocument(); $options = $doc->getScriptOptions('com_convertforms'); $options['gatracker'] = [ 'options' => [ 'tracking_id' => $tracking_id, 'event_category' => 'Convert Forms' ], 'forms' => [ $form['id'] => [ 'name' => $form['name'] ] ] ]; $doc->addScriptOptions('com_convertforms', $options); // Load script JHtml::script('plg_convertformstools_gatracker/script.js', ['relative' => true, 'version' => 'auto']); } } PK!z(X.convertformstools/gatracker/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2019 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsToolsGATrackerInstallerScript extends PlgConvertFormsToolsGATrackerInstallerScriptHelper { public $name = 'gatracker'; public $alias = 'gatracker'; public $extension_type = 'plugin'; public $plugin_folder = 'convertformstools'; public $show_message = false; public $autopublish = false; }PK!)convertformstools/gatracker/form/form.xmlnu[
    PK!Q  bconvertformstools/conditionallogic/language/ru-RU/ru-RU.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Преобразовать формы - условная логика" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Создавать интеллектуальные формы, которые динамически изменяются в зависимости от выбора, который пользователь делает при заполнении ваших форм." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Условная логика" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Условные поля" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Включить условную логику" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Введите заголовок" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Введите значение" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Добавить условие" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="Новое условие" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Удалить условие" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Дублирующее условие" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="Вы еще не добавили никаких условий в эту форму" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="Если условие не выполнено" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Действия" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Do" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Добавить действие" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Выбрать действие" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Удалить действие" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Правила" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="Когда" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Добавить группу правил" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Добавить правило" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Удалить правило" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Показать поле" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Скрыть поле" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Изменить значение" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Выбрать вариант" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Отменить выбор" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Показать параметр" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Скрыть параметр" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Выбрать оператора" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="Пусто" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="Не пусто" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="Равно" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="Выбрал" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="содержит" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Начинается с" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Заканчивается на" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Соответствует RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="Не равно" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="Не выбрал" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="Не содержит" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="Не начинается с" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="Не заканчивается на" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="Не соответствует RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Меньше чем" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Меньше или равно" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Больше чем" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Больше или равно" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="Проверено" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="Не проверено" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Выбрать поле" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Условия настройки" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Обработать это когда" PK!?ʈbconvertformstools/conditionallogic/language/ca-ES/ca-ES.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Convert Forms - Lògica condicional" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Crea formularis intel·ligents que canvien dinàmicament segons les seleccions de l'usuari en anar-los omplint." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Lògica condicional" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Camps condicionals" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Activar lògica condicional" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Escriu un títol" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Escriu un valor" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Afegeix condició" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="Nova condició" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Esborrar condició" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Duplicar condició" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="Encara no has afegit cap condició a aquest formulari" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="Si la condició no es compleix" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Accions" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Fer" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Afegir acció" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Escollir acció" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Esborrar acció" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Regles" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="Quan" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Afegir grup de regles" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Afegir regla" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Esborrar regla" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Mostrar camp" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Amagar camp" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Canviar valor" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Escollir opció" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Deseleccionar opció" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Mostrar opció" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Amagar opció" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Escollir operador" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="Està buit" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="No està buit" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="Iguals" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="Ha seleccionat" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="Conté" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Comença amb" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Acaba amb" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Concorda amb RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="No és igual" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="No ha seleccionat" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="No conté" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="No comença amb" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="No acaba amb" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="No concorda amb RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Menor que" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Menor o igual que" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Major que" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Major o igual que" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="Està marcat" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="No està marcat" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Escull camp" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Configura condicions" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Procesa això quan" PK!59_bconvertformstools/conditionallogic/language/cs-CZ/cs-CZ.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Convert Forms - podmíněná logika" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Vytváří chytré formuláře, které se dynamicky mění podle toho, jak uživatel vyplňuje formuláře." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Podmíněná logika" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Pole podmínek" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Zapnout podmíněnou logiku" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Zadejte název" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Zadejte hodnotu" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Zadejte podmínku" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="Nová podmínka" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Smazat podmínku" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Duplikovat podmínku" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="Zatím jste do tohoto formuláře nevložili žádnou podmínku" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="Pokud není podmínka splněna" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Akce" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Provést" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Přidat akci" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Vyberte akci" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Smazat akci" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Pravidla" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="Když" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Přidat skupinu rolí" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Přidat roli" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Smazat roli" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Zobrazit pole" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Skrýt pole" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Změnit hodnotu" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Vyberte možnost" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Zrušit výběr možnosti" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Zobrazit možnost" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Skrýt možnost" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Vyberte operátor" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="Je prázdný" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="Není prázdný" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="Odpovídá" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="Vybral" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="Obsahuje" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Začíná" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Končí" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Shoda RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="Není rovno" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="Nevybráno" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="Neobsahuje" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="Nezačíná na" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="Nekončí na" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="Neshoduje se s RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Menší než" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Menší nebo rovno" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Větší než" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Rovno nebo větší než" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="Vybráno" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="Nevybráno" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Vyberte pole" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Nastavit podmínky" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Zpracovat pokud" PK!bconvertformstools/conditionallogic/language/fi-FI/fi-FI.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Convert Forms - Ehdollinen logiikka" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Luo älykkäitä lomakkeita, jotka muuttuvat dynaamisesti käyttäjän tekemien valintojen perusteella täyttäessäsi lomakkeitasi." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Ehdollinen logiikka" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Ehdolliset kentät" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Käytä ehdollista logiikkaa" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Anna otsikko" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Anna arvo" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Lisää ehto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="Uusi ehto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Poista ehto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Kopioi ehto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="Et ole vielä lisännyt ehtoja tähän lomakkeeseen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="Jos ehto ei täyty" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Toiminnot" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Tee" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Lisää toiminto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Valitse toiminto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Poista toiminto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Säännöt" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="Kun" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Lisää sääntöryhmä" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Lisää sääntö" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Poista sääntö" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Näytä kenttä" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Piilota kenttä" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Vaihda arvo" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Valitse vaihtoehto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Poista valinta" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Näytä vaihtoehto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Piilota vaihtoehto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Valitse operaattori" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="on tyhjä" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="ei ole tyhjä" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="Vastaa" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="On valinnut" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="Sisältää" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Alkaa" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Päättyy" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Matches RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="Ei ole sama" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="Ei ole valinnut" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="Ei sisällä" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="Ei ala" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="Ei pääty" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="Does not match RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Vähemmän kuin" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Pienempi tai yhtä suuri kuin" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Suurempi kuin" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Suurempi tai yhtä suuri kuin" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="On valittu" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="Ei ole valittu" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Valitse kenttä" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Aseta ehdot" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Käsittele tämä kun" PK! 1fconvertformstools/conditionallogic/language/en-GB/en-GB.plg_convertformstools_conditionallogic.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Convert Forms - Conditional Logic" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Create smart forms that dynamically change based on the selections the user makes while filling out your forms." PK!m hhbconvertformstools/conditionallogic/language/en-GB/en-GB.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Convert Forms - Conditional Logic" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Create smart forms that dynamically change based on the selections the user makes while filling out your forms." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Conditional Logic" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Conditional Fields" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Enable Conditional Logic" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Enter a title" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Enter a value" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Add Condition" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="New Condition" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Delete Condition" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Duplicate Condition" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="You haven't added any conditions to this form yet" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="If the condition is not met" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Actions" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Do" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Add action" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Select action" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Delete action" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Rules" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="When" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Add Rule Group" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Add Rule" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Delete rule" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Show field" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Hide field" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Change value" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Select option" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Deselect option" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Show option" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Hide option" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Select Operator" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="Is empty" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="Is not empty" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="Equals" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="Has selected" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="Contains" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Starts with" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Ends with" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Matches RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="Does not equal" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="Does not have selected" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="Does not contain" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="Does not start with" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="Does not end with" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="Does not match RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Less than" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Less than or equal to" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Greater than" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Greater than or equal to" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="Is checked" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="Is not checked" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Select Field" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Setup Conditions" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Process this when" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_EQUAL="Total checked equals" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_LESS="Total checked less than" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_LESS_THAN_OR="Total checked less than or equal to" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_GREATER="Total checked greater than" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_GREATER_THAN_OR="Total checked greater than or equal to"PK!I^\\bconvertformstools/conditionallogic/language/uk-UA/uk-UA.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Перетворити форми - умовна логіка" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Створіть розумні форми, які динамічно змінюються на основі вибраних вами користувачем під час заповнення ваших форм." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Умовна логіка" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Умовні поля" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Увімкнути умовну логіку" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Введіть назву" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Введіть значення" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Додати умову" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="Нова умова" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Видалити умову" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Умова дублювання" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="Ви ще не додали жодних умов до цієї форми" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="Якщо умова не виконується" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Дії" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Зробити" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Додати дію" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Вибрати дію" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Видалити дію" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Правила" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="Коли" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Додати групу правил" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Додати правило" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Видалити правило" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Показати поле" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Сховати поле" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Змінити значення" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Вибрати варіант" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Скасувати вибір" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Показати варіант" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Сховати параметр" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Вибрати оператора" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="Порожня" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="Не порожньо" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="Дорівнює" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="Вибрано" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="Містить" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Починається з" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Закінчується" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Збіги RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="Не дорівнює" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="Не вибрано" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="Не містить" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="Не починається з" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="Не закінчується на" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="Не відповідає RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Менше" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Менше або рівне" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Більше" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Більше або дорівнює" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="Перевірено" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="Не перевірено" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Вибрати поле" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Умови настройки" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Обробити це, коли" PK!)bconvertformstools/conditionallogic/language/fr-FR/fr-FR.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Convert Forms - Logique conditionnelle" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Crée des formulaires intelligents qui changent dynamiquement en fonction des sélections que l'utilisateur fait en les remplissant." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Logique conditionnelle" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Champs conditionnels" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Activer la logique conditionnelle" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Saisissez un titre" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Saisissez une valeur" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Ajouter une condition" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="Nouvelle condition" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Supprimer la condition" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Dupliquer la condition" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="Vous n'avez pas encore ajouté de condition à ce formulaire" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="Si la condition n'est pas validée" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Actions" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Exécuter" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Ajouter une action" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Sélectionner une action" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Supprimer l'action" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Règles" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="Quand" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Ajouter un groupe de règles" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Ajouter une règle" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Supprimer la règle" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Afficher le champ" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Masquer le champ" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Modifier la valeur" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Sélectionner le paramètre" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Désélectionner le paramètre" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Afficher le paramètre" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Masquer le paramètre" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Sélectionner l'opérande" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="Est vide" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="N'est pas vide" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="Egale" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="A sélectionné" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="Contient" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Débute par" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Se termine par" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Correspond au RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="N'est pas égal" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="N'a pas été sélectionné" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="Ne contient pas" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="Ne commence pas par" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="Ne se termine pas par" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="Ne correspond pas au RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Inférieur à" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Inférieur ou égal à" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Supérieur à" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Supérieur ou égal à" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="Est coché" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="N'est pas coché" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Sélectionner le champ" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Paramétrage des conditions" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Exécuter quand" PK!>>bconvertformstools/conditionallogic/language/de-DE/de-DE.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Convert Forms - Bedingte Logik" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Erstellen Sie intelligente Formulare, die sich dynamisch ändern, je nachdem, was der Benutzer beim Ausfüllen des Formulars auswählt." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Bedingte Logik" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Bedingte Felder" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Bedingte Logik einschalten" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Einen Titel eingeben" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Einen Wert eingeben" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Bedingung hinzufügen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="Neue Bedingung" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Bedingung löschen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Bedingung duplizieren" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="Sie haben noch keine Bedingungen zu diesem Formular hinzugefügt" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="Wenn die Bedingung nicht erfüllt ist" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Aktionen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Ausführen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Aktion hinzufügen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Aktion auswählen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Aktion löschen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Regeln" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="Wenn" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Regelgruppe hinzufügen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Regel hinzufügen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Regel löschen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Feld anzeigen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Feld verstecken" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Wert ändern" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Option auswählen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Option abwählen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Option anzeigen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Option verstecken" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Operator auswählen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="Ist leer" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="Ist nicht leer" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="Ist gleich" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="Hat ausgewählt" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="Enthält" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Beginnt mit" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Endet mit" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Entspricht RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="Ist nicht gleich" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="Hat nicht ausgewählt" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="Enthält nicht" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="Startet nicht mit" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="Endet nicht mit" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="Entspricht nicht RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Weniger als" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Weniger als oder gleich" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Grösser als" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Grösser als oder gleich" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="Ist ausgewählt" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="Ist nicht ausgewählt" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Feld auswählen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Setup Bedingungen" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Dies ausführen wenn" PK![D22bconvertformstools/conditionallogic/language/it-IT/it-IT.plg_convertformstools_conditionallogic.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr/joomla-extensions ; @copyright Copyright (c) 2020 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC="Convert Forms - Logica condizionale" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC="Crea moduli intelligenti che cambiano dinamicamente basandosi sulle scelte fatte dali utenti mentre compilano i vostri moduli." PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ALIAS="Logica condizionale" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS="Campi condizionali" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENABLE="Abilita logica condizionale" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE="Inserisci un titolo" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE="Inserisci un valore" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION="Aggiungi condizione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION="Nuova condizione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION="Cancella condizione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION="Duplica condizione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS="Non hai ancora aggiunto nessuna condizione a questo modulo" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE="Nel caso in cui la condizione non venga soddisfatta" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS="Azioni" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS="Fai" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION="Aggiungi azione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION="Seleziona azione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION="Cancella azione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES="Regole" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS="Quando" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP="Aggiungi gruppo di regole" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE="Aggiungi regola" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE="Cancella regola" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD="Mostra campo" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD="Nascondi campo" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE="Cambia valore" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION="Seleziona opzione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION="Deseleziona opzione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION="Mostra opzione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION="Nascondi opzione" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR="Seleziona operatore" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY="E' vuoto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY="Non è vuoto" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS="è uguale a" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED="Ha selezionato" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS="Contiene" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH="Inizia con" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH="Finisce con" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX="Corrisponde a RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS="Non è uguale a " PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED="Non ha selezionato" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN="Non contiene" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH="Non inizia con" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH="Non finisce con" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX="Non corrisponde a RegEx" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN="Meno di" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL="Meno di o uguale a" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN="Più grande di" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL="Più grande di o uguale a" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED="E' spuntato" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED="Non è spuntato" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD="Seleziona campo" PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SETUP="Impostazione condizioni " PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS="Processa questo quando" PK!Z7convertformstools/conditionallogic/conditionallogic.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class PlgConvertFormsToolsConditionalLogic extends JPlugin { /** * Application Object * * @var object */ protected $app; /** * Auto loads the plugin language file * * @var boolean */ protected $autoloadLanguage = true; /** * Render the modal box when the form editor loads * * @return void */ public function onConvertFormsEditorView() { echo JHtml::_('bootstrap.renderModal', 'cfcl', [ 'title' => \JText::_('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_FIELDS'), 'backdrop' => 'static', 'footer' => ' ' . JText::_('JHELP') . ' ' ], '
    '); } /** * Validate the conditions during save * * @param string $context The context of the content passed to the plugin (added in 1.6) * @param object $article A JTableContent object * @param bool $isNew If the content has just been created * * @return boolean */ public function onContentBeforeSave($context, $form, $isNew) { if ($context != 'com_convertforms.form') { return; } if (!is_object($form) || !isset($form->params)) { return; } $params = json_decode($form->params); // Proceed only if Conditional Logic is available and enabled if (!isset($params->conditionallogic) || !$params->conditionallogic->enable) { return true; } $conditions = json_decode($params->conditionallogic->rules, true); if (!$conditions) { return true; } // Reset keys $conditions = array_values($conditions); $fields = $params->fields; foreach ($conditions as $conditionKey => $condition) { // Check rules for missing values foreach ($condition['rules'] as $rules) { $error_prefix = 'Conditional Logic: Condition #' . ($conditionKey + 1) . ' - '; foreach ($rules as $rule) { if (empty($rule)) { $form->setError($error_prefix . 'Rule is invalid'); return false; } // Check if the field exists if (!$this->fieldExist($fields, $rule['field'])) { $form->setError($error_prefix . 'Rule field is invalid'); return false; } // Check that we have a valid comparator if (!isset($rule['comparator']) || $rule['comparator'] == '') { $form->setError($error_prefix . 'Rule operator is missing'); return false; } // Check that we have a valid rule value if (isset($rule['arg']) && $rule['arg'] == '' && !in_array($rule['comparator'], ['is_checked', 'not_checked', 'empty', 'not_empty'])) { $form->setError($error_prefix . 'Rule value is empty'); return false; } } } } return true; } public function fieldExist($fields, $field_id) { foreach ($fields as $key => $field) { if ($field->key == $field_id) { return true; } } return false; } /** * Determine whether the form has calculations in order to load the respective scripts. * * @param string $html The form's final HTML layout. * @param object $form The form object * * @return void */ public function onConvertFormsFormAfterRender($html, $form) { // Only on front-end if ($this->app->isClient('administrator')) { return; } if (!$cl = $form['params']->get('conditionallogic')) { return; } if (!$cl->enable || empty($cl->rules)) { return; } $conditions = json_decode($cl->rules, true); // Abort if we don't have any conditions if (!$conditions) { return; } // Setup settings $doc = JFactory::getDocument(); $options = $doc->getScriptOptions('com_convertforms'); $options['conditional_logic'][$form['id']] = $conditions; $doc->addScriptOptions('com_convertforms', $options); // Load scripts JHtml::script('plg_convertformstools_conditionallogic/fields.js', ['relative' => true, 'version' => 'auto']); // When CSS is not loaded, the .cf-hide class must be declared in order for the Show/Hide actions to work. if (!ConvertForms\Helper::getComponentParams()->get('loadCSS', true)) { $doc->addStyleDeclaration(' .cf-hide { display:none; pointer-events: none; } '); } } /** * Add plugin fields to the form * * @param JForm $form * @param object $data * * @return boolean */ public function onConvertFormsFormPrepareForm($form, $data) { $form->loadFile(__DIR__ . '/form/form.xml'); } } PK!bppEconvertformstools/conditionallogic/fields/conditionallogicbuilder.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class JFormFieldConditionalLogicBuilder extends JFormFieldHidden { /** * Method to get a list of options for a list input. * * @return array An array of JHtml options. */ protected function getInput() { // Disable form rendering on textarea change $this->class .= ' norender'; JHtml::script('https://unpkg.com/react@16/umd/react.production.min.js'); JHtml::script('https://unpkg.com/react-dom@16/umd/react-dom.production.min.js'); JHtml::script('plg_convertformstools_conditionallogic/builder.js', ['relative' => true, 'version' => 'auto']); JHtml::stylesheet('plg_convertformstools_conditionallogic/builder.css', ['relative' => true, 'version' => 'auto']); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_TITLE'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENTER_VALUE'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NO_CONDITIONS'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_CONDITION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NEW_CONDITION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_CONDITION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_COPY_CONDITION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONDITION_ELSE'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ACTIONS_ALIAS'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE_GROUP'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_RULE'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_RULES_ALIAS'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_ACTION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DELETE_RULE'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ADD_ACTION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_ACTION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_FIELD'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_FIELD'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CHANGE_VALUE'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPTION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESELECT_OPTION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SHOW_OPTION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HIDE_OPTION'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_OPERATOR'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EQUALS'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_HAS_SELECTED'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_CONTAINS'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_STARTS_WITH'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_ENDS_WITH'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_REGEX'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EQUALS'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_SELECTED'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CONTAIN'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_START_WITH'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_END_WITH'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_REGEX'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_LESS_THAN_EQUAL'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_GREATER_THAN_EQUAL'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_IS_CHECKED'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_CHECKED'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_SELECT_FIELD'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_EMPTY'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_NOT_EMPTY'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_EQUAL'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_LESS'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_LESS_THAN_OR'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_GREATER'); JText::script('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_TOTAL_CHECKED_GREATER_THAN_OR'); $rulesOnly = isset($this->element['rulesOnly']) ? (bool) $this->element['rulesOnly'] : false; if ($rulesOnly) { return '

    ' . JText::_('PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_PROCESS_THIS') . '

    ' . parent::getInput() . '
    '; } return '' . parent::getInput(); } }PK!&j~99<convertformstools/conditionallogic/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformstoolsConditionallogicInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!tC7convertformstools/conditionallogic/conditionallogic.xmlnu[ PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC PLG_CONVERTFORMSTOOLS_CONDITIONALLOGIC_DESC 1.0 April 2020 Copyright © 2020 Tassos Marinos All Rights Reserved http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL Tassos Marinos (Tassos.gr) info@tassos.gr http://www.tassos.gr script.install.php conditionallogic.php script.install.helper.php language form fields js css PK!_"N5convertformstools/conditionallogic/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsToolsConditionalLogicInstallerScript extends PlgConvertFormsToolsConditionalLogicInstallerScriptHelper { public $name = 'conditionallogic'; public $alias = 'conditionallogic'; public $extension_type = 'plugin'; public $plugin_folder = 'convertformstools'; public $show_message = false; }PK! yNN0convertformstools/conditionallogic/form/form.xmlnu[
    PK!Ձ66(content/emailcloak/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\EmailCloak\Extension\EmailCloak; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new EmailCloak( $dispatcher, (array) PluginHelper::getPlugin('content', 'emailcloak') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!y36!content/emailcloak/emailcloak.xmlnu[ plg_content_emailcloak Joomla! Project 2005-11 (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_CONTENT_EMAILCLOAK_XML_DESCRIPTION Joomla\Plugin\Content\EmailCloak services src language/en-GB/plg_content_emailcloak.ini language/en-GB/plg_content_emailcloak.sys.ini
    PK!I$N$N/content/emailcloak/src/Extension/EmailCloak.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\EmailCloak\Extension; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\String\StringHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Email cloak plugin class. * * @since 1.5 */ final class EmailCloak extends CMSPlugin { /** * Plugin that cloaks all emails in content from spambots via Javascript. * * @param string $context The context of the content being passed to the plugin. * @param mixed &$row An object with a "text" property or the string to be cloaked. * @param mixed &$params Additional parameters. * @param integer $page Optional page number. Unused. Defaults to zero. * * @return void */ public function onContentPrepare($context, &$row, &$params, $page = 0) { // Don't run if in the API Application // Don't run this plugin when the content is being indexed if ($this->getApplication()->isClient('api') || $context === 'com_finder.indexer') { return; } // If the row is not an object or does not have a text property there is nothing to do if (!is_object($row) || !property_exists($row, 'text')) { return; } $this->cloak($row->text, $params); } /** * Generate a search pattern based on link and text. * * @param string $link The target of an email link. * @param string $text The text enclosed by the link. * * @return string A regular expression that matches a link containing the parameters. */ private function getPattern($link, $text) { $pattern = '~(?:]*)href\s*=\s*"mailto:' . $link . '"([^>]*))>' . $text . '~i'; return $pattern; } /** * Cloak all emails in text from spambots via Javascript. * * @param string &$text The string to be cloaked. * @param mixed &$params Additional parameters. Parameter "mode" (integer, default 1) * replaces addresses with "mailto:" links if nonzero. * * @return void */ private function cloak(&$text, &$params) { /* * Check for presence of {emailcloak=off} which is explicits disables this * bot for the item. */ if (StringHelper::strpos($text, '{emailcloak=off}') !== false) { $text = StringHelper::str_ireplace('{emailcloak=off}', '', $text); return; } // Simple performance check to determine whether bot should process further. if (StringHelper::strpos($text, '@') === false) { return; } $mode = (int) $this->params->def('mode', 1); $mode = $mode === 1; // Example: any@example.org $searchEmail = '([\w\.\'\-\+]+\@(?:[a-z0-9\.\-]+\.)+(?:[a-zA-Z0-9\-]{2,24}))'; // Example: any@example.org?subject=anyText $searchEmailLink = $searchEmail . '([?&][\x20-\x7f][^"<>]+)'; // Any Text $searchText = '((?:[\x20-\x7f]|[\xA1-\xFF]|[\xC2-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF4][\x80-\xBF]{3})[^<>]+)'; // Any Image link $searchImage = '(]+>)'; // Any Text with |
    |
    )'; // Any address with ||)'; /* * Search and fix derivatives of link code email@example.org. This happens when inserting an email in TinyMCE, cancelling its suggestion to add * the mailto: prefix... */ $pattern = $this->getPattern($searchEmail, $searchEmail); $pattern = str_replace('"mailto:', '"([\x20-\x7f][^<>]+/)', $pattern); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[3][0]; $mailText = $regs[5][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 1, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search and fix derivatives of link code anytext. This happens when inserting an email in TinyMCE, cancelling its suggestion to add * the mailto: prefix... */ $pattern = $this->getPattern($searchEmail, $searchText); $pattern = str_replace('"mailto:', '"([\x20-\x7f][^<>]+/)', $pattern); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[3][0]; $mailText = $regs[5][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code email@example.org */ $pattern = $this->getPattern($searchEmail, $searchEmail); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0]; $mailText = $regs[4][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[3][0]; // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 1, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code email@amail.com */ $pattern = $this->getPattern($searchEmail, $searchEmailSpan); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0]; $mailText = $regs[4][0] . $regs[5][0] . $regs[6][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[3][0]; // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 1, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * anytext */ $pattern = $this->getPattern($searchEmail, $searchTextSpan); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0]; $mailText = $regs[4][0] . $regs[5][0] . $regs[6][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[3][0]; $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * anytext */ $pattern = $this->getPattern($searchEmail, $searchText); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0]; $mailText = $regs[4][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[3][0]; $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * */ $pattern = $this->getPattern($searchEmail, $searchImage); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0]; $mailText = $regs[4][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[3][0]; $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * email@example.org */ $pattern = $this->getPattern($searchEmail, $searchImage . $searchEmail); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0]; $mailText = $regs[4][0] . $regs[5][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[3][0]; $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 1, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * any text */ $pattern = $this->getPattern($searchEmail, $searchImage . $searchText); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0]; $mailText = $regs[4][0] . $regs[5][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[3][0]; $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code email@example.org */ $pattern = $this->getPattern($searchEmailLink, $searchEmail); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0] . $regs[3][0]; $mailText = $regs[5][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; // Needed for handling of Body parameter $mail = str_replace('&', '&', $mail); // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 1, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code anytext */ $pattern = $this->getPattern($searchEmailLink, $searchText); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0] . $regs[3][0]; $mailText = $regs[5][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; // Needed for handling of Body parameter $mail = str_replace('&', '&', $mail); $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code email@amail.com */ $pattern = $this->getPattern($searchEmailLink, $searchEmailSpan); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0] . $regs[3][0]; $mailText = $regs[5][0] . $regs[6][0] . $regs[7][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 1, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * anytext */ $pattern = $this->getPattern($searchEmailLink, $searchTextSpan); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0] . $regs[3][0]; $mailText = $regs[5][0] . $regs[6][0] . $regs[7][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * */ $pattern = $this->getPattern($searchEmailLink, $searchImage); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0] . $regs[3][0]; $mailText = $regs[5][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; // Needed for handling of Body parameter $mail = str_replace('&', '&', $mail); // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * email@amail.com */ $pattern = $this->getPattern($searchEmailLink, $searchImage . $searchEmail); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0] . $regs[3][0]; $mailText = $regs[5][0] . $regs[6][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; // Needed for handling of Body parameter $mail = str_replace('&', '&', $mail); // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 1, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for derivatives of link code * any text */ $pattern = $this->getPattern($searchEmailLink, $searchImage . $searchText); while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[2][0] . $regs[3][0]; $mailText = $regs[5][0] . $regs[6][0]; $attribsBefore = $regs[1][0]; $attribsAfter = $regs[4][0]; // Needed for handling of Body parameter $mail = str_replace('&', '&', $mail); // Check to see if mail text is different from mail addy $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mailText, 0, $attribsBefore, $attribsAfter); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($regs[0][0])); } /* * Search for plain text email addresses, such as email@example.org but within HTML tags: * or * The '<[^<]*>(*SKIP)(*F)|' trick is used to exclude this kind of occurrences */ $pattern = '~<[^<]*(?(*SKIP)(*F)|<[^>]+?(\w*=\"' . $searchEmail . '\")[^>]*\/>~i'; while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[0][0]; $replacement = HTMLHelper::_('email.cloak', $mail, 0, $mail); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($mail)); } /* * Search for plain text email addresses, such as email@example.org but within HTML attributes: * email or
  • email
  • */ $pattern = '(<[^>]+?(\w*=\"' . $searchEmail . '")[^>]*>[^<]+<[^<]+>)'; while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[0][0]; $replacement = HTMLHelper::_('email.cloak', $mail, 0, $mail); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[0][1], strlen($mail)); } /* * Search for plain text email addresses, such as email@example.org but not within HTML tags: *

    email@example.org

    * The '<[^<]*>(*SKIP)(*F)|' trick is used to exclude this kind of occurrences * The '<[^<]*(?(*SKIP)(*F)|' exclude image files with @ in filename */ $pattern = '~<[^<]*(?(*SKIP)(*F)|' . $searchEmail . '~i'; while (preg_match($pattern, $text, $regs, PREG_OFFSET_CAPTURE)) { $mail = $regs[1][0]; $replacement = HTMLHelper::_('email.cloak', $mail, $mode, $mail); // Replace the found address with the js cloaked email $text = substr_replace($text, $replacement, $regs[1][1], strlen($mail)); } } } PK!oGJcontent/vote/vote.xmlnu[ plg_content_vote Joomla! Project 2005-11 (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_VOTE_XML_DESCRIPTION Joomla\Plugin\Content\Vote services src tmpl language/en-GB/plg_content_vote.ini language/en-GB/plg_content_vote.sys.ini
    PK!QUQ"content/vote/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\Vote\Extension\Vote; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Vote( $dispatcher, (array) PluginHelper::getPlugin('content', 'vote') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!06OOcontent/vote/tmpl/vote.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; /** * Layout variables * ----------------- * @var string $context The context of the content being passed to the plugin * @var object &$row The article object * @var object &$params The article params * @var integer $page The 'page' number * @var array $parts The context segments * @var string $path Path to this file */ $uri = clone Uri::getInstance(); // Create option list for voting select box $options = []; for ($i = 1; $i < 6; $i++) { $options[] = HTMLHelper::_('select.option', $i, Text::sprintf('PLG_VOTE_VOTE', $i)); } ?>
    id); ?>
    PK!f content/vote/tmpl/rating.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */ $wa = $this->getApplication()->getDocument()->getWebAssetManager(); $wa->registerAndUseStyle('plg_content_vote', 'plg_content_vote/rating.css'); /** * Layout variables * ----------------- * @var string $context The context of the content being passed to the plugin * @var object &$row The article object * @var object &$params The article params * @var integer $page The 'page' number * @var array $parts The context segments * @var string $path Path to this file */ if ($context === 'com_content.categories') { return; } // Get the icons $iconStar = HTMLHelper::_('image', 'plg_content_vote/vote-star.svg', '', '', true, true); $iconHalfstar = HTMLHelper::_('image', 'plg_content_vote/vote-star-half.svg', '', '', true, true); // If you can't find the icons then skip it if ($iconStar === null || $iconHalfstar === null) { return; } // Get paths to icons $pathStar = JPATH_ROOT . substr($iconStar, strlen(Uri::root(true))); $pathHalfstar = JPATH_ROOT . substr($iconHalfstar, strlen(Uri::root(true))); // Write inline '' elements $star = file_exists($pathStar) ? file_get_contents($pathStar) : ''; $halfstar = file_exists($pathHalfstar) ? file_get_contents($pathHalfstar) : ''; // Get rating $rating = (float) $row->rating; $rcount = (int) $row->rating_count; // Round to 0.5 $rating = round($rating / 0.5) * 0.5; // Determine number of stars $stars = $rating; $img = ''; for ($i = 0; $i < floor($stars); $i++) { $img .= '
  • ' . $star . '
  • '; } if (($stars - floor($stars)) >= 0.5) { $img .= '
  • ' . $star . '
  • '; $img .= '
  • ' . $halfstar . '
  • '; ++$stars; } for ($i = $stars; $i < 5; $i++) { $img .= '
  • ' . $star . '
  • '; } ?> PK!4ZZ#content/vote/src/Extension/Vote.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\Vote\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Vote plugin. * * @since 1.5 */ final class Vote extends CMSPlugin { /** * @var \Joomla\CMS\Application\CMSApplication * * @since 3.7.0 * * @deprecated 4.4.0 will be removed in 6.0 as it is there only for layout overrides * Use getApplication() instead */ protected $app; /** * Displays the voting area when viewing an article and the voting section is displayed before the article * * @param string $context The context of the content being passed to the plugin * @param object &$row The article object * @param object &$params The article params * @param integer $page The 'page' number * * @return string|boolean HTML string containing code for the votes if in com_content else boolean false * * @since 1.6 */ public function onContentBeforeDisplay($context, &$row, &$params, $page = 0) { if ($this->params->get('position', 'top') !== 'top') { return ''; } return $this->displayVotingData($context, $row, $params, $page); } /** * Displays the voting area when viewing an article and the voting section is displayed after the article * * @param string $context The context of the content being passed to the plugin * @param object &$row The article object * @param object &$params The article params * @param integer $page The 'page' number * * @return string|boolean HTML string containing code for the votes if in com_content else boolean false * * @since 3.7.0 */ public function onContentAfterDisplay($context, &$row, &$params, $page = 0) { if ($this->params->get('position', 'top') !== 'bottom') { return ''; } return $this->displayVotingData($context, $row, $params, $page); } /** * Displays the voting area * * @param string $context The context of the content being passed to the plugin * @param object &$row The article object * @param object &$params The article params * @param integer $page The 'page' number * * @return string|boolean HTML string containing code for the votes if in com_content else boolean false * * @since 3.7.0 */ private function displayVotingData($context, &$row, &$params, $page) { $parts = explode('.', $context); if ($parts[0] !== 'com_content') { return false; } if (empty($params) || !$params->get('show_vote', null)) { return ''; } // Load plugin language files only when needed (ex: they are not needed if show_vote is not active). $this->loadLanguage(); // Get the path for the rating summary layout file $path = PluginHelper::getLayoutPath('content', 'vote', 'rating'); // Render the layout ob_start(); include $path; $html = ob_get_clean(); if ($this->getApplication()->getInput()->getString('view', '') === 'article' && $row->state == 1) { // Get the path for the voting form layout file $path = PluginHelper::getLayoutPath('content', 'vote', 'vote'); // Render the layout ob_start(); include $path; $html .= ob_get_clean(); } return $html; } } PK!!@\ \ content/pagebreak/pagebreak.xmlnu[ plg_content_pagebreak Joomla! Project 2005-11 (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_CONTENT_PAGEBREAK_XML_DESCRIPTION Joomla\Plugin\Content\PageBreak services src tmpl language/en-GB/plg_content_pagebreak.ini language/en-GB/plg_content_pagebreak.sys.ini
    PK!I@77'content/pagebreak/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\PageBreak\Extension\PageBreak; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new PageBreak( $dispatcher, (array) PluginHelper::getPlugin('content', 'pagebreak') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!c{%content/pagebreak/tmpl/navigation.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; /** * @var $links array Array with keys 'previous' and 'next' with non-SEO links to the previous and next pages * @var $page integer The page number */ $lang = $this->getApplication()->getLanguage(); ?>
    PK!ㆬcontent/pagebreak/tmpl/toc.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Router\Route; ?>

    PK!we0e0-content/pagebreak/src/Extension/PageBreak.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\PageBreak\Extension; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Pagination\Pagination; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Utility\Utility; use Joomla\Component\Content\Site\Helper\RouteHelper; use Joomla\String\StringHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Page break plugin * * Usage: *
    *
    * or *
    * or *
    * or *
    * * @since 1.6 */ final class PageBreak extends CMSPlugin { /** * The navigation list with all page objects if parameter 'multipage_toc' is active. * * @var array * @since 4.0.0 */ protected $list = []; /** * Plugin that adds a pagebreak into the text and truncates text at that point * * @param string $context The context of the content being passed to the plugin. * @param object &$row The article object. Note $article->text is also available * @param mixed &$params The article params * @param integer $page The 'page' number * * @return void * * @since 1.6 */ public function onContentPrepare($context, &$row, &$params, $page = 0) { $canProceed = $context === 'com_content.article'; if (!$canProceed) { return; } $style = $this->params->get('style', 'pages'); // Expression to search for. $regex = '##iU'; $input = $this->getApplication()->getInput(); $print = $input->getBool('print'); $showall = $input->getBool('showall'); if (!$this->params->get('enabled', 1)) { $print = true; } if ($print) { $row->text = preg_replace($regex, '
    ', $row->text); return; } // Simple performance check to determine whether bot should process further. if (StringHelper::strpos($row->text, 'class="system-pagebreak') === false) { if ($page > 0) { throw new \Exception($this->getApplication()->getLanguage()->_('JERROR_PAGE_NOT_FOUND'), 404); } return; } $view = $input->getString('view'); $full = $input->getBool('fullview'); if (!$page) { $page = 0; } if ($full || $view !== 'article' || $params->get('intro_only') || $params->get('popup')) { $row->text = preg_replace($regex, '', $row->text); return; } // Load plugin language files only when needed (ex: not needed if no system-pagebreak class exists). $this->loadLanguage(); // Find all instances of plugin and put in $matches. $matches = []; preg_match_all($regex, $row->text, $matches, PREG_SET_ORDER); if ($showall && $this->params->get('showall', 1)) { $hasToc = $this->params->get('multipage_toc', 1); if ($hasToc) { // Display TOC. $page = 1; $this->createToc($row, $matches, $page); } else { $row->toc = ''; } $row->text = preg_replace($regex, '
    ', $row->text); return; } // Split the text around the plugin. $text = preg_split($regex, $row->text); if (!isset($text[$page])) { throw new \Exception($this->getApplication()->getLanguage()->_('JERROR_PAGE_NOT_FOUND'), 404); } // Count the number of pages. $n = count($text); // We have found at least one plugin, therefore at least 2 pages. if ($n > 1) { $title = $this->params->get('title', 1); $hasToc = $this->params->get('multipage_toc', 1); // Adds heading or title to Title. if ($title && $page && isset($matches[$page - 1][0])) { $attrs = Utility::parseAttributes($matches[$page - 1][0]); if (isset($attrs['title'])) { $row->page_title = $attrs['title']; } } // Reset the text, we already hold it in the $text array. $row->text = ''; if ($style === 'pages') { // Display TOC. if ($hasToc) { $this->createToc($row, $matches, $page); } else { $row->toc = ''; } // Traditional mos page navigation $pageNav = new Pagination($n, $page, 1); // Flag indicates to not add limitstart=0 to URL $pageNav->hideEmptyLimitstart = true; // Page counter. $row->text .= ''; // Page text. $text[$page] = str_replace('
    ', '', $text[$page]); $row->text .= $text[$page]; // $row->text .= '
    '; $row->text .= '
    '; // Adds navigation between pages to bottom of text. if ($hasToc) { $this->createNavigation($row, $page, $n); } // Page links shown at bottom of page if TOC disabled. if (!$hasToc) { $row->text .= $pageNav->getPagesLinks(); } $row->text .= '
    '; } else { $t[] = $text[0]; if ($style === 'tabs') { $t[] = (string) HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'article' . $row->id . '-' . $style . '0', 'view' => 'tabs']); } else { $t[] = (string) HTMLHelper::_('bootstrap.startAccordion', 'myAccordion', ['active' => 'article' . $row->id . '-' . $style . '0']); } foreach ($text as $key => $subtext) { $index = 'article' . $row->id . '-' . $style . $key; if ($key >= 1) { $match = $matches[$key - 1]; $match = (array) Utility::parseAttributes($match[0]); if (isset($match['alt'])) { $title = stripslashes($match['alt']); } elseif (isset($match['title'])) { $title = stripslashes($match['title']); } else { $title = Text::sprintf('PLG_CONTENT_PAGEBREAK_PAGE_NUM', $key + 1); } if ($style === 'tabs') { $t[] = (string) HTMLHelper::_('uitab.addTab', 'myTab', $index, $title); } else { $t[] = (string) HTMLHelper::_('bootstrap.addSlide', 'myAccordion', $title, $index); } $t[] = (string) $subtext; if ($style === 'tabs') { $t[] = (string) HTMLHelper::_('uitab.endTab'); } else { $t[] = (string) HTMLHelper::_('bootstrap.endSlide'); } } } if ($style === 'tabs') { $t[] = (string) HTMLHelper::_('uitab.endTabSet'); } else { $t[] = (string) HTMLHelper::_('bootstrap.endAccordion'); } $row->text = implode(' ', $t); } } } /** * Creates a Table of Contents for the pagebreak * * @param object &$row The article object. Note $article->text is also available * @param array &$matches Array of matches of a regex in onContentPrepare * @param integer &$page The 'page' number * * @return void * * @since 1.6 */ private function createToc(&$row, &$matches, &$page) { $heading = $row->title ?? $this->getApplication()->getLanguage()->_('PLG_CONTENT_PAGEBREAK_NO_TITLE'); $input = $this->getApplication()->getInput(); $limitstart = $input->getUint('limitstart', 0); $showall = $input->getInt('showall', 0); $headingtext = ''; if ($this->params->get('article_index', 1) == 1) { $headingtext = $this->getApplication()->getLanguage()->_('PLG_CONTENT_PAGEBREAK_ARTICLE_INDEX'); if ($this->params->get('article_index_text')) { $headingtext = htmlspecialchars($this->params->get('article_index_text'), ENT_QUOTES, 'UTF-8'); } } // TOC first Page link. $this->list[1] = new \stdClass(); $this->list[1]->link = RouteHelper::getArticleRoute($row->slug, $row->catid, $row->language); $this->list[1]->title = $heading; $this->list[1]->active = ($limitstart === 0 && $showall === 0); $i = 2; foreach ($matches as $bot) { if (@$bot[0]) { $attrs2 = Utility::parseAttributes($bot[0]); if (@$attrs2['alt']) { $title = stripslashes($attrs2['alt']); } elseif (@$attrs2['title']) { $title = stripslashes($attrs2['title']); } else { $title = Text::sprintf('PLG_CONTENT_PAGEBREAK_PAGE_NUM', $i); } } else { $title = Text::sprintf('PLG_CONTENT_PAGEBREAK_PAGE_NUM', $i); } $this->list[$i] = new \stdClass(); $this->list[$i]->link = RouteHelper::getArticleRoute($row->slug, $row->catid, $row->language) . '&limitstart=' . ($i - 1); $this->list[$i]->title = $title; $this->list[$i]->active = ($limitstart === $i - 1); $i++; } if ($this->params->get('showall')) { $this->list[$i] = new \stdClass(); $this->list[$i]->link = RouteHelper::getArticleRoute($row->slug, $row->catid, $row->language) . '&showall=1'; $this->list[$i]->title = $this->getApplication()->getLanguage()->_('PLG_CONTENT_PAGEBREAK_ALL_PAGES'); $this->list[$i]->active = ($limitstart === $i - 1); } $list = $this->list; $path = PluginHelper::getLayoutPath('content', 'pagebreak', 'toc'); ob_start(); include $path; $row->toc = ob_get_clean(); } /** * Creates the navigation for the item * * @param object &$row The article object. Note $article->text is also available * @param int $page The page number * @param int $n The total number of pages * * @return void * * @since 1.6 */ private function createNavigation(&$row, $page, $n) { $links = [ 'next' => '', 'previous' => '', ]; if ($page < $n - 1) { $links['next'] = RouteHelper::getArticleRoute($row->slug, $row->catid, $row->language) . '&limitstart=' . ($page + 1); } if ($page > 0) { $links['previous'] = RouteHelper::getArticleRoute($row->slug, $row->catid, $row->language); if ($page > 1) { $links['previous'] .= '&limitstart=' . ($page - 1); } } $path = PluginHelper::getLayoutPath('content', 'pagebreak', 'navigation'); ob_start(); include $path; $row->text .= ob_get_clean(); } } PK!xwcontent/igallery/igallery.phpnu[input; if( $input->get('option', '') == 'com_finder' ) { return; } $lang = JFactory::getLanguage(); $lang->load('com_igallery', JPATH_ADMINISTRATOR); $view = $input->get('view', null); $layout = $input->get('layout', null); JFactory::getApplication()->input->set('view', 'category'); JFactory::getApplication()->input->set('layout', 'default'); JFactory::getApplication()->input->set('igsource', 'plugin'); preg_match_all('#\{igallery(.*?)\}#ism',$article->text, $matches); foreach( $matches[1] as $pluginParams ) { if( preg_match('#.*?\sid=([0-9]+).*?#is', $pluginParams, $uid) ) { if( JFactory::getApplication()->input->get('ig-'.$uid[1], 0) == 1 ) { $uid[1] = $uid[1].rand(1,999); } JFactory::getApplication()->input->set('iguniqueid',$uid[1]); JFactory::getApplication()->input->set('ig-'.$uid[1], 1); } else if(preg_match('#.*?\sid="([0-9]+)".*?#is', $pluginParams, $uidJ15) ) { JFactory::getApplication()->input->set('iguniqueid',$uidJ15[1]); } else { JFactory::getApplication()->enqueueMessage('ignite gallery content plugin error: no gallery id set'); } if( preg_match('#.*?cid=([0-9,]+).*?#is', $pluginParams, $cid) ) { JFactory::getApplication()->input->set('igid',$cid[1]); } else if(preg_match('#.*?cid="([0-9,]+)".*?#is', $pluginParams, $cidJ15) ) { JFactory::getApplication()->input->set('igid',$cidJ15[1]); } else { JFactory::getApplication()->enqueueMessage('ignite gallery content plugin error: no gallery id set'); } if( preg_match('#.*?pid=([0-9]+).*?#is', $pluginParams, $pid) ) { JFactory::getApplication()->input->set('igpid',$pid[1]); } else if(preg_match('#.*?pid="([0-9]+)".*?#is', $pluginParams, $pidJ15) ) { JFactory::getApplication()->input->set('igpid',$pidJ15[1]); } else { JFactory::getApplication()->enqueueMessage('ignite gallery content plugin error: no profile set'); } if( preg_match('#.*?type=([a-z_]+).*?#is', $pluginParams, $type) ) { JFactory::getApplication()->input->set('igtype',$type[1]); } else if(preg_match('#.*?type="([a-z_]+)".*?#is', $pluginParams, $typeJ15) ) { if($typeJ15[1] == 'classic') { $typeJ15[1] = 'category'; } JFactory::getApplication()->input->set('igtype', $typeJ15[1]); } else { JFactory::getApplication()->enqueueMessage('ignite gallery content plugin error: no gallery type set'); } if( preg_match('#.*?children=([0-9]+).*?#is', $pluginParams, $children) ) { JFactory::getApplication()->input->set('igchild',$children[1]); } else if(preg_match('#.*?children="([0-9]+)".*?#is', $pluginParams, $childrenJ15) ) { JFactory::getApplication()->input->set('igchild',$childrenJ15[1]); } if( preg_match('#.*?addlinks=([0-9]+).*?#is', $pluginParams, $addlinks) ) { JFactory::getApplication()->input->set('igaddlinks',$addlinks[1]); } if( preg_match('/tags=([0-9\pL,\- ]+)/iu', $pluginParams, $tags) ) { JFactory::getApplication()->input->set('igtags',$tags[1]); } else if(preg_match('#.*?tags="([0-9a-zA-Z, ]+)".*?#is', $pluginParams, $tagsJ15) ) { JFactory::getApplication()->input->set('igtags',$tagsJ15[1]); } else { JFactory::getApplication()->input->set('igtags',''); } if( preg_match('#.*?limit=([0-9]+).*?#is', $pluginParams, $limit) ) { JFactory::getApplication()->input->set('iglimit',$limit[1]); } else if(preg_match('#.*?limit="([0-9]+)".*?#is', $pluginParams, $limitJ15) ) { JFactory::getApplication()->input->set('iglimit',$limitJ15[1]); } else { JFactory::getApplication()->input->set('iglimit',0); } require_once(JPATH_ADMINISTRATOR.'/components/com_igallery/defines.php'); require_once(IG_COMPONENT.'/controller.php'); $controller = new IgalleryController(); ob_start(); $controller->execute('display'); $pluginHtml = ob_get_contents(); ob_end_clean(); $article->text = str_replace('{igallery'.$pluginParams.'}', $pluginHtml, $article->text); } if($view != null) { JFactory::getApplication()->input->set('view', $view); } if($layout != null) { JFactory::getApplication()->input->set('layout', $layout); } return true; } }PK!8WQQcontent/igallery/igallery.xmlnu[ Content - Ignite Gallery Matthew Thomson October 2022 (C) 2020 Matthew Thomson. All rights reserved. GPL v2 www.ignitegallery.com 4.8.2 Changes the gallery plugin code within a Joomla article into a gallery. igallery.php http://www.ignitegallery.com/update/xml/content-plugin-update.xml PK!·GG'content/sppagebuilder/sppagebuilder.phpnu[load('com_sppagebuilder', JPATH_SITE, 'en-GB', true); $language->load('com_sppagebuilder', JPATH_SITE, null, true); class PlgContentSppagebuilder extends CMSPlugin { protected $autoloadLanguage = true; protected $sppagebuilder_content = ''; protected $sppagebuilder_active = 0; protected $isSppagebuilderEnabled = 0; public function __construct(&$subject, $config) { $this->isSppagebuilderEnabled = $this->isSppagebuilderEnabled(); parent::__construct($subject, $config); } public function onContentAfterSave($context, $article, $isNew) { if (!$this->isSppagebuilderEnabled) return; $input = Factory::getApplication()->input; $option = $input->get('option', '', 'STRING'); $view = 'article'; $form = $input->post->get('jform', array(), 'ARRAY'); $sppagebuilder_active = (isset($form['attribs']['sppagebuilder_active']) && $form['attribs']['sppagebuilder_active']) ? (int) $form['attribs']['sppagebuilder_active'] : 0; $sppagebuilder_content = (isset($form['attribs']['sppagebuilder_content']) && $form['attribs']['sppagebuilder_content']) ? $form['attribs']['sppagebuilder_content'] : '[]'; if (!$sppagebuilder_content) return; if ($context === 'com_content.article') { $article_state = $article->state; if (!$sppagebuilder_active) { $article_state = 0; } $values = [ 'title' => $article->title, 'text' => $sppagebuilder_content, 'option' => $option, 'view' => $view, 'id' => $article->id, 'active' => $sppagebuilder_active, 'published' => $article_state, 'catid' => $article->catid, 'created_on' => $article->created, 'created_by' => $article->created_by, 'modified' => $article->modified, 'modified_by' => $article->modified_by, 'access' => $article->access, 'language' => '*', 'action' => 'apply' ]; if ($article->state == 2) { $values['published'] = 1; } /** @TODO: not working for font-end editor now*/ // if ($sppagebuilder_active) // { // self::addFullText($article->id, $sppagebuilder_content); // } SppagebuilderHelper::onAfterIntegrationSave($values); } } /** @TODO: getPrettyText not working. */ private static function addFullText($id, $data) { $article = new stdClass(); $article->id = $id; $article->fulltext = SppagebuilderHelperSite::getPrettyText($data); $result = Factory::getDbo()->updateObject('#__content', $article, 'id'); } public function onContentPrepare($context, $article) { $input = Factory::getApplication()->input; $option = $input->get('option', '', 'STRING'); $view = $input->get('view', '', 'STRING'); $task = $input->get('task', '', 'STRING'); if (!isset($article->id) || !(int) $article->id) { return true; } if ($this->isSppagebuilderEnabled) { if (($option === 'com_content') && ($view === 'article')) { $article->text = SppagebuilderHelper::onIntegrationPrepareContent($article->text, $option, $view, $article->id); } if (($option == 'com_j2store') && ($view === 'products') && ($task === 'view') && ($context === 'com_content.article.productlist')) { $article->text = SppagebuilderHelper::onIntegrationPrepareContent($article->text, 'com_content', 'article', $article->id); } } } public function onContentAfterDelete($context, $data) { if ($this->isSppagebuilderEnabled) { $input = Factory::getApplication()->input; $option = $input->get('option', '', 'STRING'); $task = $input->get('task', '', 'STRING'); if ($option == 'com_content' && $context == 'com_content.article') { $values = array( 'option' => $option, 'view' => 'article', 'id' => $data->id, 'action' => 'delete' ); SppagebuilderHelper::onAfterIntegrationSave($values); } } } public function onContentAfterTitle($context, $article, $params, $limitstart) { $input = Factory::getApplication()->input; $option = $input->get('option', '', 'STRING'); $view = $input->get('view', '', 'STRING'); $task = $input->get('task', '', 'STRING'); if (!isset($article->id) || !(int) $article->id) { return true; } if ($this->isSppagebuilderEnabled) { if ($option == 'com_content' && $view == 'article' && $params->get('access-edit')) { $sppbEditLink = $this->displaySPPBEditLink($article, $params); if ($sppbEditLink) { return $sppbEditLink; } } } return; } public function onContentChangeState($context, $pks, $value) { if ($this->isSppagebuilderEnabled) { $input = Factory::getApplication()->input; $option = $input->get('option', '', 'STRING'); $view = $input->get('view', '', 'STRING'); $task = $input->get('task', '', 'STRING'); if ($option == 'com_content' && $context == 'com_content.article') { $actions = array(0, 1, -2); if (!in_array($value, $actions)) return; foreach ($pks as $id) { $values = array( 'option' => $option, 'view' => 'article', 'id' => $id, 'published' => $value, 'action' => 'stateChange' ); SppagebuilderHelper::onAfterIntegrationSave($values); } } } } private function isSppagebuilderEnabled() { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select('enabled') ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote('com_sppagebuilder')) ->where($db->quoteName('type') . ' = ' . $db->quote('component')); $db->setQuery($query); return (bool) $db->loadResult(); } private function displaySPPBEditLink($article, $params) { $user = Factory::getUser(); // Ignore if in a popup window. if ($params && $params->get('popup')) return; // Ignore if the state is negative (trashed). if ($article->state < 0) return; $item = SppagebuilderHelper::getPageContent('com_content', 'article', $article->id); if (!$item || !$item->id) return; if ( property_exists($article, 'checked_out') && property_exists($article, 'checked_out_time') && $article->checked_out > 0 && $article->checked_out != $user->get('id') ) { return ' Checked out'; } $app = CMSApplication::getInstance('site'); $router = $app->getRouter(); // Get item language code $lang_code = (isset($item->language) && $item->language && explode('-', $item->language)[0]) ? explode('-', $item->language)[0] : ''; // check language filter plugin is enable or not $enable_lang_filter = PluginHelper::getPlugin('system', 'languagefilter'); // get joomla config $conf = Factory::getConfig(); $front_link = 'index.php?option=com_sppagebuilder&view=form&tmpl=component&layout=edit&id=' . $item->id; $sefURI = str_replace('/administrator', '', $router->build($front_link)); if ($lang_code && $lang_code !== '*' && $enable_lang_filter && $conf->get('sef')) { $sefURI = str_replace('/index.php/', '/index.php/' . $lang_code . '/', $sefURI); } elseif ($lang_code && $lang_code !== '*') { $sefURI = $sefURI . '&lang=' . $lang_code; } return 'Edit with SP Page Builder'; } } PK!V$$#content/sppagebuilder/thumbnail.jpgnu[JFIF     &""&0-0>>T     &""&0-0>>T" 0 af"E{3+$i,YYbH Lf6W;lO5]ײ1ŵG!5uq(ؐvIWkm DYٱMQ5s]JP̡=B5֐Wdg]Ӭe  bQŕd;Nŀk38Vg-2Ԗٽy _;y`!Fabw׳t3"x}xgͽ;]0T( d56oms#H|`S 䯌{/OpU (r$:s !6ٵ]#!﮷S~ýG8;.Ldg#w|{x.>Exr3=>ȽҟG|u(X3q٩K'D~' / NPo=o;{Fv\\&3fgGCn?_SMTc#+}Ggyœq3f^y-9l6[ڛ9(%h cm<7[U.s|l/K# /Y9}^,O+ն1l ~H{GZ9# 4,(3qY],3Nux3o%ai͵K0m1fSB|@]N+sG6Gz@hqf So0VћjŐnX;7\AJ2[;R8g _| u(ھ8x1l1~#i\rr?E$JԃRTU(ֈ]gTS;??9"cR~{>?' ͚_{?M/W!szXzgWu3r7ր1+.+ɉ@P\DZ Ibm±"NO3429@) dT*Npz/.u赩J |W˺}S 5{+,^;gEtw^hb ]cIrd!~ŜiY9~B$pb?HnoiGN1UȘ"Ss4mo(d-`Al1l]-CCPv=R6K-3D(iAsp\SC!1 AQ"02aq5B#4@R3br%CS?ܨB Q_Rp@VAP7Y%M{^bJ0E` FWrVwh*O8vy4TvZ7LY>g0#:]Qq5qk4_%}/h YR'.f  –G8 /_8_Tr#V^tZgp:Rkz>oN ɩ7?`(5GD)N):*0EHViVc%+A#A4:Z8 $QK UMJBEEkrE7쟷ܑK@28 #]3W:E b),Un A)TSQSVb:Xp$֢ទN{>oLS*@ +X:B}U7hG ˯~ϛVj"}a88_L4Bq@I+%@S:FgA@* m^1.ɟF?z?_\Ch2b٩+-%ُdV m' DV6fXeN'O[SZx#ڧL}a WfxuOz`eJ\Nt\HAԜBj.m^_0s,8˝R 콄p'bbLTjOţfNYO{)PPCŇ6(J6Va46> ݐS,٨2.WSj@\ 9Ħ ƙg0Nt^I&=;$ƹfq]!83-U|y[N\<8)oI oI zBm RP$ Q99EM˃Ł{&gh@. s ۩ mIZN*HE6.]cş7︼#(=!^Zx .yVl3#< `bZi+ BD]RKm@O710Уn#Q)f$fCZiSO34IYmU8fq<ʂi-V$z2Y+nʇs8Qc0\H =:ɎɎ*GQ)iNĪY]@ݫ^IOҰJA)JZJ9q+kQ6휢e(P~FhhOx@p֭TML%Yg@<3ϛn<< P wNp3b ?(~Pq?Hc^ 9p" ʷ#q&)ou<ޓLe(|#AsC Q<8A4ZRF1Q[4#p+y Xg1bGa55P!LvOq  e202g KPE.,4noFN!vT߱ϛn"*h4Esk'`f)xF5تuR)KVu+}2SԺ/;ȥ?YzM#Z+.u8UX?A#CQ$!+#A^wi VnMnP:77Sv>oIkp\)`QqG|RV_R _F!Rc/`_(Wb٥O_ :^x׭B>(!1AQ aq0@?p] ¥ [6=W t53= x~%>tVcOq]6`kЁ3t g 1g )`[hG4q'H@3E<_Bp 9|g6FX, Eq+]}ol?7 +_,k-[tKZϘsnsq1i GA+EѠXc>NXM3_)94ѫ?dP0 y@f\-?HBg(2꥘&NTvb LAOtbHJu.&FR ԭqGe8}{{8V~fo >,o],n@D?yJR@ t_PB( }k?#:h-mAs$|Ot:0QŽyX4"y S&T]C^=xxɀ1Sh󡺈LP8:HERrZ_M}>L?kLV %lZV2g,ؔVpV[a&AߍbQ>իע M*~ؽ1XGlhU](xY{_5<kmZh)xREOP]G\| ɤYS8D%GKpLQ#a_l,d-_,[9J]y<tD>4f)fKO WdEDɈ !GN4xB{`>:AO9 {?b!b9'Bi"+^<}xZcP Sl3,{umዂp?mf-`G>0<1ua册+ !Uj(@ٮvO?}m]k(P;1jj)){눉ZGW-0yX462'%'K6DT- ?pIڪ0>DlPdʡ5א|XPVn24XN\mVi|(pt0_G"Є7OoyA.B6,F<,?2_ i^i@ $>Q?!.+mctqI i񗴵E ~"0=*?\ߠN+8% BŴc 뵿H~jTŏ`~ LN0/5-:@&]<"(| dP̚T ''#V={?`;h!"VGeJڰQ\V[A"}y;X@ wZILU~aDsƽ>~ f0JfWs?Lb0X2N6pd[ ?Qi7w7ĸzN̜fm `>"lٖ LMiդ.)Y`:uo 7d w/¯1 5հ+2xn9Shנ(yKWG9v~Yn  یm Fc_S]daD~ 7[w u"G!{ ,oYȔ > BWfO0 y1o22;lMR~lbX0q"] Y\\ZS_*-M- ٘'wQŢFĠvhKTLp*Q͠6u aHJbzuB8`pEY3 <(/Rl",ruQ‡ O<%n C{Mnq0׆}w3 !1Ar03Q"2Bab#@q?k47=x|:zμjY޿:U,@$Q}<d+.qWvc0G"5h!UrDdA QA޿:YVnJGY2T*H`4b8:.R ԑU@ j՘f(A'$;xI75><]CWQ6'Zb%x{Ԛt},F۷\Uΐ$9G?uh!pʒ|yִd1 "g'_+Esx Oh|h{6j"@P=Hx_lbͥ%Y_hq%GAW0mn6]Yvᔂ*?`"o?h 5"f-s4O $ L11ܷ`_@-jƒ׋~u97 _Ȭ 畬\j|hWMcp :;<!1A "Qa5qt24Bs#%03Cbcr? &zk DQ9A D֜R5+}ß-NZPM H)@]|J$΄@"z@4LQJS56u|҈1[ RME ވY?f=C_Gj(4I<$(zZ%(IRW~nLgS c6Xnd&JV:|G<8S>LnI+c^"VuA->tvAFLR}F}hդΛNekE)CyhAV1h{jхn"agVSn ’1+T)[ImjLpcuAC ݱn}穬 x_m aDJn.JOSH޿~![Z6ZI}z8k'z6Wp* ":L+jۖ%χs4ړDL*{=R!%I^YZƨPRe*m_Mz>Wn͒ODèY4OaSMF *rsgíX^۔ ,@-Vr'밣z֬eۆu>5$ Hsi A4:iɖ;%뿇s?8k:]YR`5=a\3t.O `@W_CWz: s!\$q/LK%ys游V?z@lpCnz 35WwJ\n7X IS";ð˻ņV[QQ: Qr RQ>R+S.TrHwUc0ݱeMQAYfRۥVk$!/Y-XL@tTID[vq/g^|;)4A@BG)%&;aNfB ϢHܟ.\* A\ !)YZWh")gH-(iuS%C6޳|l2 ("y\x%뿇s4NFqҚDԄNE BEu.ѐ)Q$)$) V%s4@Hc@gi5>gHhOZ;rkx5HN(DvrScuù2M@*'nIGQͧӏPh*5J8:oRI¢9+Z_xQZ|EbNuxAϖ+o]i;RQ\}W_PK!MH++'content/sppagebuilder/sppagebuilder.xmlnu[ Content - SP Page Builder Joomla! Project JoomShaper.com Sep 2016 Copyright (C) 2010 - 2023 JoomShaper. All rights reserved. http://www.gnu.org/licenses/gpl-2.0.html GPLv2 or later support@joomshaper.com www.joomshaper.com 4.0.8 SP Page Builder System plugin to add support for 3rd party components sppagebuilder.php thumbnail.jpg PK!ҁvrr!content/pingomatic/pingomatic.phpnu[> * * @author Joomla! Extensions Store * @package JMAP::plugins::content * @since 3.0 */ class PlgContentPingomatic extends CMSPlugin implements SubscriberInterface { /** * @access private * @var boolean */ private $isPluginStopped; /** * Plugin execution context * * @access private * @var array */ private $context; /** * Plugin Joomla execution context * * @access private * @var string */ private $jcontext; /** * Curl adapter reference * * @access private * @var Object */ private $curlAdapter; /** * Pinger class for webblog services such as Pingomatic * * @access private * @var Object */ private $pingerInstance; /** * Component config params * * @access private * @var Object */ private $cParams; /** * Adapters mapping based on context and route helper * * @access private * @var array */ private $adaptersMapping; /** * Single article routed link * * @access private * @var string */ private $singleArticleRouted; /** * Application reference * * @access protected * @var Object */ protected $appInstance; /** * Database connector * * @access protected * @var Object */ protected $dbInstance; /** * Load the CURL library needed from JMap Framework * * @access private * @return boolean */ private function loadCurlLib() { // Check lib availability and load it if (file_exists ( JPATH_ROOT . '/administrator/components/com_jmap/Framework/Http/Http.php' )) { include_once (JPATH_ROOT . '/administrator/components/com_jmap/Framework/Http/Http.php'); include_once (JPATH_ROOT . '/administrator/components/com_jmap/Framework/Http/Response.php'); include_once (JPATH_ROOT . '/administrator/components/com_jmap/Framework/Http/Transport.php'); include_once (JPATH_ROOT . '/administrator/components/com_jmap/Framework/Http/Transport/Curl.php'); include_once (JPATH_ROOT . '/administrator/components/com_jmap/Framework/Http/Transport/Socket.php'); // Instantiate dependency $this->curlAdapter = new JMapHttp ( new JMapHttpTransportCurl (), $this->cParams ); return true; } return false; } /** * Load the Pinger lib to ping weblog services * * @access private * @return boolean */ private function loadPingerLib() { // Check lib availability and load it if (file_exists ( JPATH_ROOT . '/administrator/components/com_jmap/Framework/Pinger/Weblog.php' )) { include_once (JPATH_ROOT . '/administrator/components/com_jmap/Framework/Pinger/Weblog.php'); // Instantiate dependency $this->pingerInstance = new JMapPingerWeblog(); return true; } return false; } /** * Send auto ping for this article URL available in the ping table using the curl adapter * * @access private * @return boolean */ private function autoSendPing($title, $url, $rssurl, $services) { // Load safely the CURL JMap lib without autoloader if ($this->loadCurlLib ()) { // Array of POST vars $post = array (); $post ['title'] = $title; $post ['blogurl'] = $url; $post ['rssurl'] = $rssurl; $post = array_merge ( $post, ( array ) $services ); // Post HTTP request to Pingomatic $httpResponse = $this->curlAdapter->post ( 'http://pingomatic.com/ping/', $post, array (), 5, 'JSitemap Professional Pinger' ); // Check if HTTP status code is OK if ($httpResponse->code != 200) { throw new \RuntimeException ( Text::_ ( 'COM_JMAP_AUTOPING_ERROR_HTTP_STATUSCODE' ) ); } } return true; } /** * New router Joomla management */ private function findItemidNewRouter($link, $siteRouter) { // 1 STEP: build the route using the new router $articleMenuRoutedUriObject = $siteRouter->build ( $link ); // Add compatibility support for no rewritten links $path = $articleMenuRoutedUriObject->getPath(); $path = str_replace(array('/index.php', '/index.php/'), '/', $path); $articleMenuRoutedUriObject->setPath($path); $path = $articleMenuRoutedUriObject->getPath(); $path = '/administrator' . $path; $path = str_replace(array('/index.php', '/index.php/'), '/', $path); $articleMenuRoutedUriObject->setPath($path); $originalBackendLanguageTag = $this->appInstance->getLanguage()->getTag(); // 2 STEP: parse back the URL now finally including the routed Itemid Factory::getContainer()->get(\Joomla\CMS\Application\SiteApplication::class)->loadLanguage(); // Avoid parse uri redirects when saving an article if ($this->appInstance->get('force_ssl') >= 1) { $articleMenuRoutedUriObject->setScheme('https'); } $articleMenuParsedUriArray = $siteRouter->parse ($articleMenuRoutedUriObject); $jLang = Factory::getContainer()->get(\Joomla\CMS\Language\LanguageFactoryInterface::class)->createLanguage($originalBackendLanguageTag, false); Factory::$language = $jLang; $jLang->load('com_jmap', JPATH_ADMINISTRATOR . '/components/com_jmap', 'en-GB', true, true); if($originalBackendLanguageTag != 'en-GB') { $jLang->load('com_jmap', JPATH_ADMINISTRATOR, $originalBackendLanguageTag, true, false); $jLang->load('com_jmap', JPATH_ADMINISTRATOR . '/components/com_jmap', $originalBackendLanguageTag, true, false); } if(isset($articleMenuParsedUriArray['Itemid'])) { $link .= '&Itemid=' . $articleMenuParsedUriArray['Itemid']; } return $link; } /** * Route save single article to the corresponding SEF link * * @access private * @return string */ private function routeArticleToSefMenu($articleID, $catID, $language, $article) { // Try to route the article to a single article menu item view $helperRouteClass = $this->context ['class']; $classMethod = $this->context ['method']; $siteRouter = Factory::getContainer()->has('SiteRouter') ? Factory::getContainer()->get('SiteRouter'): SiteRouter::getInstance('site'); // Patch for K2, ensure to always evaluate the article language, override the Factory language instance if($this->jcontext == 'com_k2.item' && $language != '*' && JMapMultilang::isEnabled ()) { $originalLanguage = $this->appInstance->getLanguage(); $lang = Factory::getContainer()->get(\Joomla\CMS\Language\LanguageFactoryInterface::class)->createLanguage($language, $language); Factory::$language = $lang; } // Route helper native by component, com_content, com_k2 if (! isset ( $this->context ['routing'] )) { $articleHelperRoute = $helperRouteClass::$classMethod ( $articleID, $catID, $language ); } else { // Route helper universal JSitemap, com_zoo $articleHelperRoute = $helperRouteClass::$classMethod ( $article->option, $article->view, $article->id, $article->catid, null ); // Check if the Zoo item has been routed to the view frontpage and if the linked app matches the correct one. Apps can be multiple. if ($articleHelperRoute) { $query = "SELECT " . $this->dbInstance->quoteName('link') . "," . $this->dbInstance->quoteName('params') . "\n FROM " . $this->dbInstance->quoteName('#__menu') . "\n WHERE " . $this->dbInstance->quoteName('id') . " = " . $this->dbInstance->quote($articleHelperRoute); $menuCurrentObject = $this->dbInstance->setQuery($query)->loadObject(); if($menuCurrentObject->link == 'index.php?option=com_zoo&view=frontpage&layout=frontpage') { // Check if the current application ID of the item matches the menu item id that has been routed $currentAppId = $this->appInstance->getInput()->get('changeapp'); $decodedParams = json_decode($menuCurrentObject->params); $menuAppId = $decodedParams->application; if($currentAppId != $menuAppId) { $query = "SELECT " . $this->dbInstance->quoteName('id') . "," . $this->dbInstance->quoteName('params') . "\n FROM " . $this->dbInstance->quoteName('#__menu') . "\n WHERE " . $this->dbInstance->quoteName('link') . " = " . $this->dbInstance->quote('index.php?option=com_zoo&view=frontpage&layout=frontpage'); $menusZooFrontpage = $this->dbInstance->setQuery($query)->loadObjectList(); foreach ($menusZooFrontpage as $menuZooFrontpage) { $thisMenuParams = json_decode($menuZooFrontpage->params); $thisMenuAppId = $thisMenuParams->application; if($thisMenuAppId == $currentAppId) { $articleHelperRoute = $menuZooFrontpage->id; break; } } } } $articleHelperRoute = '?Itemid=' . $articleHelperRoute; } } // Extract Itemid from the helper routed URL $extractedItemid = preg_match ( '/Itemid=\d+/i', $articleHelperRoute, $result ); // Joomla new router if(stripos($articleHelperRoute, 'com_content') && !$extractedItemid) { $articleRouteWithItemid = $this->findItemidNewRouter ($articleHelperRoute, $siteRouter); $extractedItemid = preg_match ( '/Itemid=\d+/i', $articleRouteWithItemid, $result ); } if (isset ( $result [0] )) { // Patch for K2, ensure to always evaluate the article language, override the Factory language instance if($this->jcontext == 'com_k2.item' && $language != '*' && JMapMultilang::isEnabled ()) { $result [0] .= '&lang='. $language; $articleHelperRoute .= '&lang='. $language; } // Get uri instance avoidng subdomains already included in the routing chunks $uriInstance = Uri::getInstance(); $resourceLiveSite = rtrim($uriInstance->getScheme() . '://' . $uriInstance->getHost(), '/'); $extractedItemid = $result [0]; $articleMenuRouted = $siteRouter->build ( '?' . $extractedItemid )->toString (); // Store a single article routed URL so that i can be used at a later stage for the autoping feature only if($this->cParams->get('default_autoping_single_article', 1)) { if(isset($this->context['routing']) && $this->context['routing'] == 'jmap') { $this->singleArticleRouted = $siteRouter->build ( sprintf($this->context ['rawlink'], $articleID, $extractedItemid ) )->toString (); } else { $this->singleArticleRouted = $siteRouter->build ( $articleHelperRoute )->toString (); } // Integration override with sh404sef if enabled for single article link if (defined('SH404SEF_IS_RUNNING') && class_exists('Sh404sefHelperGeneral')) { if($this->jcontext == 'com_zoo.item') { $articleHelperRoute = sprintf($this->context ['rawlink'], $articleID, $extractedItemid ); } // Sh404Sef processing routing $this->singleArticleRouted = \Sh404sefHelperGeneral::getSefFromNonSef($articleHelperRoute . '&' . $extractedItemid, true, false); // Prevent to append alias at the later stage if($this->jcontext == 'com_k2.item') { $this->sh404sefUrl = true; } } } // Patch for K2, restore the original Factory language instance if($this->jcontext == 'com_k2.item' && $language != '*' && JMapMultilang::isEnabled ()) { Factory::$language = $originalLanguage; } // Check if multilanguage is enabled if (JMapMultilang::isEnabled ()) { $defaultLanguage = ComponentHelper::getParams('com_languages')->get('site'); if ($language != '*') { // New language manager instance $languageManager = JMapMultilang::getInstance ( $language ); } else { // Get the default language tag // New language manager instance $languageManager = JMapMultilang::getInstance ( $defaultLanguage ); } // Extract the language tag $selectedLanguage = $languageManager->getTag(); $languageFilterPlugin = PluginHelper::getPlugin('system', 'languagefilter'); $languageFilterPluginParams = new Registry($languageFilterPlugin->params); if($defaultLanguage == $selectedLanguage && $languageFilterPluginParams->get('remove_default_prefix', 0)) { $articleMenuRouted = str_replace ( '/administrator', '', $articleMenuRouted ); if($this->singleArticleRouted) { $this->singleArticleRouted = str_replace ( '/administrator', '', $this->singleArticleRouted ); } } else { $localeTag = $languageManager->getLocale (); $sefTag = $localeTag [4]; $articleMenuRouted = str_replace ( '/administrator', '/' . $sefTag, $articleMenuRouted ); if($this->singleArticleRouted) { $this->singleArticleRouted = str_replace ( '/administrator', '/' . $sefTag, $this->singleArticleRouted ); } } } else { $articleMenuRouted = str_replace ( '/administrator', '', $articleMenuRouted ); } $articleMenuRouted = preg_match('/http/i', $articleMenuRouted) ? $articleMenuRouted : $resourceLiveSite . '/' . ltrim($articleMenuRouted, '/'); if($this->singleArticleRouted) { $this->singleArticleRouted = preg_match('/http/i', $this->singleArticleRouted) ? $this->singleArticleRouted : $resourceLiveSite . '/' . ltrim($this->singleArticleRouted, '/'); } return $articleMenuRouted; } else { // Patch for K2, restore the original Factory language instance if($this->jcontext == 'com_k2.item' && $language != '*' && JMapMultilang::isEnabled ()) { Factory::$language = $originalLanguage; } // Check if routing is valid otherwise throw exception throw new \RuntimeException ( Text::_ ( 'COM_JMAP_AUTOPING_ERROR_NOSEFROUTE_FOUND' ) ); } } /** * Method to be called everytime an article in backend is saved, * it's responsible to check and find if the SEF link of the article has been * added to the Pingomatic table, and if found submit the ping form through CURL http adapter * * @subparam string $context The context of the content passed to the plugin (added in 1.6) * @subparam object $article A Table Content object * @subparam boolean $isNew If the content is just about to be created * * @return boolean true if function not enabled, is in front-end or is new. Else true or false depending on success of save function. */ public function pingContent(Event $event) { // subparams: $context, $article, $isNew $arguments = $event->getArguments(); $context = $arguments[0]; $article = $arguments[1]; $isNew = $arguments[2]; $arrayPost = $arguments[3]; // Avoid operations if plugin is executed in frontend if (! $this->cParams->get ( 'default_autoping', 0 ) && ! $this->cParams->get ( 'autoping', 0 ) && ! $this->cParams->get ( 'enable_google_indexing_api', 0 )) { return; } // Avoid pinging if the article is unpublished $now = new DateTime('now', new DateTimeZone('UTC')); $articlePublishUp = new DateTime($article->publish_up); $nowFormatted = $now->format('Y-m-d H:i:s'); $articlePublishUpFormatted = $articlePublishUp->format('Y-m-d H:i:s'); // Check also if a workflow transition is set if(isset($arrayPost['transition']) && $arrayPost['transition']) { $query = $this->dbInstance->getQuery ( true ); $query->select ( $this->dbInstance->quoteName('options') ); $query->from ( $this->dbInstance->quoteName ( '#__workflow_transitions' ) ); $query->where ( $this->dbInstance->quoteName ( 'id' ) . '=' . $this->dbInstance->quote ( $arrayPost['transition'] ) ); $transitionOptions = $this->dbInstance->setQuery ( $query )->loadObject (); if($transitionOptions) { $transitionOptions = json_decode($transitionOptions->options); $article->state = $transitionOptions->publishing; } } if($context == 'com_content.article' && ($article->state != 1 || $articlePublishUpFormatted > $nowFormatted)) { return; } if($context == 'com_k2.item' && ($article->published != 1 || $articlePublishUpFormatted > $nowFormatted)) { return; } if($context == 'com_zoo.item' && ($this->appInstance->getInput()->get('state') != 1 || $articlePublishUpFormatted > $nowFormatted)) { return; } // Ensure to process only native Joomla articles if (array_key_exists ( $context, $this->adaptersMapping )) { // Store the Joomla context $this->jcontext = $context; // Extract the correct route helper $routeHelper = $this->adaptersMapping [$context] ['file']; // Include needed files for the correct multilanguage routing from backend to frontend of the save articles if (file_exists ( $routeHelper )) { include_once ($routeHelper); // Store the context for static class method call $this->context = $this->adaptersMapping [$context]; } // Start HTTP submission process, manage users exceptions if debug is enabled try { // Try attempt to resolve the article to a single menu or container category SEF link $hasArticleMenuRoute = $this->routeArticleToSefMenu ( $article->id, $article->catid, $article->language, $article ); // If article has been resolved, fetch pings URLs from jmap_pingomatic table and do lookup if ($hasArticleMenuRoute) { // Check if the auto Pingomatic ping based on records is enabled if($this->cParams->get ( 'autoping', 0 )) { $query = $this->dbInstance->getQuery ( true ); $query->select ( '*' ); $query->from ( $this->dbInstance->quoteName ( '#__jmap_pingomatic' ) ); $query->where ( $this->dbInstance->quoteName ( 'blogurl' ) . '=' . $this->dbInstance->quote ( $hasArticleMenuRoute ) ); // Is there a found pinged link for this article scope? $foundPingUrl = $this->dbInstance->setQuery ( $query )->loadObject (); if ($foundPingUrl) { // Retrieve ping record info and submit form using CURL adapter, else do nothing $titleToPing = $foundPingUrl->title; $urlToPing = $foundPingUrl->blogurl; $rssUrlToPing = $foundPingUrl->rssurl; $servicesToPing = json_decode ( $foundPingUrl->services ); // If ping is OK update the pinging status and datetime in the Pingomatic table if ($this->autoSendPing ( $titleToPing, $urlToPing, $rssUrlToPing, $servicesToPing )) { $query = $this->dbInstance->getQuery ( true ); $query->update ( $this->dbInstance->quoteName ( '#__jmap_pingomatic' ) ); $query->set ( $this->dbInstance->quoteName ( 'lastping' ) . ' = ' . $this->dbInstance->quote ( date ( 'Y-m-d H:i:s' ) ) ); $query->where ( $this->dbInstance->quoteName ( 'id' ) . '=' . ( int ) $foundPingUrl->id ); $this->dbInstance->setQuery ( $query )->execute (); // Everything complete fine, ping sent and updated! if ($this->cParams->get ( 'enable_debug', 0 )) { $this->appInstance->enqueueMessage ( Text::_ ( 'COM_JMAP_AUTOPING_COMPLETED_SUCCESFULLY' ), 'notice' ); } } } else { // Display post message after save only if debug is enabled if ($this->cParams->get ( 'enable_debug', 0 )) { $this->appInstance->enqueueMessage ( Text::_ ( 'COM_JMAP_AUTOPING_ERROR_NOPING_CONTENT_FOUND' ), 'notice' ); } } } // Check if the default Pingomatic/Weblogs ping is enabled if($this->cParams->get ( 'default_autoping', 0 )) { // Always submit autoping using XMLRPC web services if($this->loadPingerLib()) { // Get a single article routed URL override if($this->cParams->get('default_autoping_single_article', 1)) { $hasArticleMenuRoute = $this->singleArticleRouted; } // Normalize language URL if needed, remove untraslated query string $hasArticleMenuRoute = preg_replace('/\?(.)*$/i', '', $hasArticleMenuRoute); // K2 management if($this->cParams->get('default_autoping_single_article', 1)) { if($context == 'com_k2.item' && !isset($this->sh404sefUrl)) { $hasArticleMenuRoute .= '-' . $article->alias; // Check if the SEF suffix is enabled and correct the URL if($this->appInstance->get ( 'sef_suffix', 1 )) { $hasArticleMenuRoute = str_replace('.html', '', $hasArticleMenuRoute) . '.html'; } } } // Get debug state $debugEnabled = $this->cParams->get ( 'enable_debug', 0 ); $pingomaticPinged = $this->pingerInstance->ping_ping_o_matic($article->title, $hasArticleMenuRoute); if($debugEnabled && $pingomaticPinged) { $this->appInstance->enqueueMessage ( Text::_( 'COM_JMAP_AUTOPING_DEFAULT_AUTOPING_SENT_PINGOMATIC' ), 'notice' ); } $googlePinged = $this->pingerInstance->ping_google($article->title, $hasArticleMenuRoute); // Got a 403 Forbidden error for the first request, place a new request to have success if(!$googlePinged) { $googlePinged = $this->pingerInstance->ping_google($article->title, $hasArticleMenuRoute); } if($debugEnabled && $googlePinged) { $this->appInstance->enqueueMessage ( Text::_( 'COM_JMAP_AUTOPING_DEFAULT_AUTOPING_SENT_GOOGLE' ), 'notice' ); } $weblogsPinged = $this->pingerInstance->ping_weblogs_com($article->title, $hasArticleMenuRoute); if($debugEnabled && $weblogsPinged) { $this->appInstance->enqueueMessage ( Text::_( 'COM_JMAP_AUTOPING_DEFAULT_AUTOPING_SENT_WEBLOGS' ), 'notice' ); } $blogsPinged = $this->pingerInstance->ping_blo_gs($article->title, $hasArticleMenuRoute); if($debugEnabled && $blogsPinged) { $this->appInstance->enqueueMessage ( Text::_( 'COM_JMAP_AUTOPING_DEFAULT_AUTOPING_SENT_BLOGS' ), 'notice' ); } if ($this->loadCurlLib ()) { $joomlaConfig = $this->appInstance->getConfig(); $httpTransport = new JMapHttpTransportCurl (); $connectionAdapter = new JMapHttp ( $httpTransport, $this->cParams ); $baiduPinged = $connectionAdapter->post ( 'https://chineseseoshifu.com/tools/submit-to-baidu.php', array('yourname'=>$article->title, 'email'=>$joomlaConfig->get('mailfrom'), 'url'=>$hasArticleMenuRoute) ); if($debugEnabled && $baiduPinged->code == 200) { $this->appInstance->enqueueMessage ( Text::_( 'COM_JMAP_AUTOPING_DEFAULT_AUTOPING_SENT_BAIDU' ), 'notice' ); } $indexNowBing = $connectionAdapter->get('https://www.bing.com/indexnow?url=' . $hasArticleMenuRoute . '&key=28bcb027f9b443719ceac7cd30556c3c'); if($debugEnabled && $indexNowBing->code == 200) { $this->appInstance->enqueueMessage ( Text::_( 'COM_JMAP_AUTOPING_DEFAULT_AUTOPING_SENT_INDEXNOW_BING' ), 'notice' ); } $indexNowYandex = $connectionAdapter->get('https://yandex.com/indexnow?url=' . $hasArticleMenuRoute . '&key=28bcb027f9b443719ceac7cd30556c3c'); if($debugEnabled && $indexNowYandex->code == 202) { $this->appInstance->enqueueMessage ( Text::_( 'COM_JMAP_AUTOPING_DEFAULT_AUTOPING_SENT_INDEXNOW_YANDEX' ), 'notice' ); } } if($debugEnabled) { $this->appInstance->enqueueMessage ( $hasArticleMenuRoute, 'notice' ); } } } // Notify Google if the Indexing API integration is active and the login is available if($this->cParams->get ( 'enable_google_indexing_api', 0 )) { // Get debug state $debugEnabled = $this->cParams->get ( 'enable_debug', 0 ); // Register autoloader prefix // Auto loader setup require_once JPATH_ADMINISTRATOR . '/components/com_jmap/Framework/Loader.php'; $namespace = 'JExtstore\\Component\\JMap'; JExtstore\Component\JMap\Administrator\Framework\Loader::setup (); JExtstore\Component\JMap\Administrator\Framework\Loader::registerNamespacePsr4 ( $namespace . '\Site', JPATH_ROOT . '/components/com_jmap' ); JExtstore\Component\JMap\Administrator\Framework\Loader::registerNamespacePsr4 ( $namespace . '\Administrator', JPATH_ROOT . '/administrator/components/com_jmap' ); // Composer autoloader require_once JPATH_ADMINISTRATOR. '/components/com_jmap/Framework/composer/autoload_real.php'; \ComposerAutoloaderInitcb4c0ac1dedbbba2f0b42e9cdf4d93d7::getLoader(); $extensionMVCFactory = $this->appInstance->bootComponent('com_jmap')->getMVCFactory(); $googleModel = $extensionMVCFactory->createModel('Google', 'Administrator'); $apiResponse = $googleModel->indexingAPIAuthUpdate($hasArticleMenuRoute); if($debugEnabled && is_object($apiResponse)) { $this->appInstance->enqueueMessage ( Text::sprintf( 'COM_JMAP_GOOGLE_INDEXING_API_SUCCESS', $hasArticleMenuRoute), 'notice' ); } } } } catch ( \Exception $e ) { // Display post message after save only if debug is enabled if ($this->cParams->get ( 'enable_debug', 0 )) { $this->appInstance->enqueueMessage ( $e->getMessage (), 'notice' ); } } } } /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.0.0 */ public static function getSubscribedEvents(): array { return [ 'onContentAfterSave' => 'pingContent' ]; } /** * Override registers Listeners to the Dispatcher * It allows to stop a plugin execution based on the return value of its constructor * * @override * @return void */ public function registerListeners(?DispatcherInterface $dispatcher = null) { // Check if the plugin has not been stopped by the constructor if(!$this->isPluginStopped) { parent::registerListeners($dispatcher); } } /** * Class Constructor * @access protected * @param object $subject The object to observe * @param array $config An array that holds the plugin configuration * @since 1.0 */ public function __construct(& $subject, $config = array()) { parent::__construct ( $subject, $config ); // Init application $this->appInstance = Factory::getApplication(); // Init database $this->dbInstance = Factory::getContainer()->get('DatabaseDriver'); // Load component config $this->cParams = ComponentHelper::getParams ( 'com_jmap' ); // Avoid operations if plugin is not executed in backend if (!$this->appInstance->isClient ('administrator')) { $this->isPluginStopped = true; return; } // Avoid operation if not supported extension is detected if(!in_array($this->appInstance->getInput()->get('option'), array('com_content', 'com_k2', 'com_zoo'))) { $this->isPluginStopped = true; return; } if (file_exists ( JPATH_ROOT . '/administrator/components/com_jmap/Framework/Language/Multilang.php' )) { include_once (JPATH_ROOT . '/administrator/components/com_jmap/Framework/Language/Multilang.php'); } $this->adaptersMapping = array ( 'com_content.article' => array ( 'file' => JPATH_ROOT . '/components/com_content/src/Helper/RouteHelper.php', 'class' => '\\Joomla\\Component\\Content\\Site\\Helper\\RouteHelper', 'method' => 'getArticleRoute' ), 'com_k2.item' => array ( 'file' => JPATH_ROOT . '/components/com_k2/helpers/route.php', 'class' => 'K2HelperRoute', 'method' => 'getItemRoute' ), 'com_zoo.item' => array ( 'routing' => 'jmap', 'rawlink' => 'index.php?option=com_zoo&view=item&task=item&item_id=%s&%s', 'file' => JPATH_ROOT . '/administrator/components/com_jmap/Framework/Route/Helper.php', 'class' => '\JExtstore\Component\JMap\Administrator\Framework\Route\Helper', 'method' => 'getItemRoute' ) ); // Manage partial language translations $jLang = Factory::getApplication()->getLanguage (); $jLang->load ( 'com_jmap', JPATH_ROOT . '/administrator/components/com_jmap', 'en-GB', true, true ); if ($jLang->getTag () != 'en-GB') { $jLang->load ( 'com_jmap', JPATH_SITE, null, true, false ); $jLang->load ( 'com_jmap', JPATH_SITE . '/administrator/components/com_jmap', null, true, false ); } } }PK!͢a!content/pingomatic/pingomatic.xmlnu[ Content - JSitemap Pingomatic Joomla! Extensions Store 2022-11-18 Copyright (C) 2016 - Joomla! Extensions Store. All Rights Reserved. http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL info@storejextensions.org http://storejextensions.org 4.11 JSitemap Pingomatic plugin pingomatic.php index.html PK!#o,,content/pingomatic/index.htmlnu[PK!kdcontent/fields/fields.xmlnu[ plg_content_fields Joomla! Project 2017-02 (C) 2017 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.7.0 PLG_CONTENT_FIELDS_XML_DESCRIPTION Joomla\Plugin\Content\Fields services src language/en-GB/plg_content_fields.ini language/en-GB/plg_content_fields.sys.ini
    PK!$content/fields/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\Fields\Extension\Fields; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Fields( $dispatcher, (array) PluginHelper::getPlugin('content', 'fields') ); return $plugin; } ); } }; PK!RȪ'content/fields/src/Extension/Fields.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\Fields\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\Fields\Administrator\Helper\FieldsHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Plug-in to show a custom field in eg an article * This uses the {fields ID} syntax * * @since 3.7.0 */ final class Fields extends CMSPlugin { /** * Plugin that shows a custom field * * @param string $context The context of the content being passed to the plugin. * @param object &$item The item object. Note $article->text is also available * @param object &$params The article params * @param int $page The 'page' number * * @return void * * @since 3.7.0 */ public function onContentPrepare($context, &$item, &$params, $page = 0) { // If the item has a context, overwrite the existing one if ($context === 'com_finder.indexer' && !empty($item->context)) { $context = $item->context; } elseif ($context === 'com_finder.indexer') { // Don't run this plugin when the content is being indexed and we have no real context return; } // This plugin only works if $item is an object if (!is_object($item)) { return; } // Don't run if there is no text property (in case of bad calls) or it is empty if (!property_exists($item, 'text') || empty($item->text)) { return; } // Prepare the text if (property_exists($item, 'text') && strpos($item->text, 'field') !== false) { $item->text = $this->prepare($item->text, $context, $item); } // Prepare the intro text if (property_exists($item, 'introtext') && is_string($item->introtext) && strpos($item->introtext, 'field') !== false) { $item->introtext = $this->prepare($item->introtext, $context, $item); } } /** * Prepares the given string by parsing {field} and {fieldgroup} groups and replacing them. * * @param string $string The text to prepare * @param string $context The context of the content * @param object $item The item object * * @return string * * @since 3.8.1 */ private function prepare($string, $context, $item) { // Search for {field ID} or {fieldgroup ID} tags and put the results into $matches. $regex = '/{(field|fieldgroup)\s+(.*?)}/i'; preg_match_all($regex, $string, $matches, PREG_SET_ORDER); if (!$matches) { return $string; } $parts = FieldsHelper::extract($context); if (!$parts || count($parts) < 2) { return $string; } $context = $parts[0] . '.' . $parts[1]; $fields = FieldsHelper::getFields($context, $item, true); $fieldsById = []; $groups = []; // Rearranging fields in arrays for easier lookup later. foreach ($fields as $field) { $fieldsById[$field->id] = $field; $groups[$field->group_id][] = $field; } foreach ($matches as $i => $match) { // $match[0] is the full pattern match, $match[1] is the type (field or fieldgroup) and $match[2] the ID and optional the layout $explode = explode(',', $match[2]); $id = (int) $explode[0]; $output = ''; if ($match[1] === 'field' && $id) { if (isset($fieldsById[$id])) { $layout = !empty($explode[1]) ? trim($explode[1]) : $fieldsById[$id]->params->get('layout', 'render'); $output = FieldsHelper::render( $context, 'field.' . $layout, [ 'item' => $item, 'context' => $context, 'field' => $fieldsById[$id], ] ); } } else { if ($match[2] === '*') { $match[0] = str_replace('*', '\*', $match[0]); $renderFields = $fields; } else { $renderFields = $groups[$id] ?? ''; } if ($renderFields) { $layout = !empty($explode[1]) ? trim($explode[1]) : 'render'; $output = FieldsHelper::render( $context, 'fields.' . $layout, [ 'item' => $item, 'context' => $context, 'fields' => $renderFields, ] ); } } $string = preg_replace("|$match[0]|", addcslashes($output, '\\$'), $string, 1); } return $string; } } PK!4,content/pagenavigation/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\PageNavigation\Extension\PageNavigation; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new PageNavigation( $dispatcher, (array) PluginHelper::getPlugin('content', 'pagenavigation') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!*T)content/pagenavigation/pagenavigation.xmlnu[ plg_content_pagenavigation Joomla! Project 2006-01 (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_PAGENAVIGATION_XML_DESCRIPTION Joomla\Plugin\Content\PageNavigation services src tmpl language/en-GB/plg_content_pagenavigation.ini language/en-GB/plg_content_pagenavigation.sys.ini
    PK!d_))'content/pagenavigation/tmpl/default.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; $lang = $this->getLanguage(); ?> PK!!&&7content/pagenavigation/src/Extension/PageNavigation.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\PageNavigation\Extension; use Joomla\CMS\Access\Access; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Component\Content\Site\Helper\RouteHelper; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Pagenavigation plugin class. * * @since 1.5 */ final class PageNavigation extends CMSPlugin { use DatabaseAwareTrait; /** * If in the article view and the parameter is enabled shows the page navigation * * @param string $context The context of the content being passed to the plugin * @param object &$row The article object * @param mixed &$params The article params * @param integer $page The 'page' number * * @return mixed void or true * * @since 1.6 */ public function onContentBeforeDisplay($context, &$row, &$params, $page = 0) { $app = $this->getApplication(); $view = $app->getInput()->get('view'); $print = $app->getInput()->getBool('print'); if ($print) { return false; } if ($context === 'com_content.article' && $view === 'article' && $params->get('show_item_navigation')) { $db = $this->getDatabase(); $user = $app->getIdentity(); $lang = $app->getLanguage(); $now = Factory::getDate()->toSql(); $query = $db->getQuery(true); $uid = $row->id; $option = 'com_content'; $canPublish = $user->authorise('core.edit.state', $option . '.article.' . $row->id); /** * The following is needed as different menu items types utilise a different param to control ordering. * For Blogs the `orderby_sec` param is the order controlling param. * For Table and List views it is the `orderby` param. */ $params_list = $params->toArray(); if (array_key_exists('orderby_sec', $params_list)) { $order_method = $params->get('orderby_sec', ''); } else { $order_method = $params->get('orderby', ''); } // Additional check for invalid sort ordering. if ($order_method === 'front') { $order_method = ''; } if (in_array($order_method, ['date', 'rdate'])) { // Get the order code $orderDate = $params->get('order_date'); switch ($orderDate) { // Use created if modified is not set case 'modified': $orderby = 'CASE WHEN ' . $db->quoteName('a.modified') . ' IS NULL THEN ' . $db->quoteName('a.created') . ' ELSE ' . $db->quoteName('a.modified') . ' END'; break; // Use created if publish_up is not set case 'published': $orderby = 'CASE WHEN ' . $db->quoteName('a.publish_up') . ' IS NULL THEN ' . $db->quoteName('a.created') . ' ELSE ' . $db->quoteName('a.publish_up') . ' END'; break; // Use created as default default: $orderby = $db->quoteName('a.created'); break; } if ($order_method === 'rdate') { $orderby .= ' DESC'; } } else { // Determine sort order. switch ($order_method) { case 'alpha': $orderby = $db->quoteName('a.title'); break; case 'ralpha': $orderby = $db->quoteName('a.title') . ' DESC'; break; case 'hits': $orderby = $db->quoteName('a.hits'); break; case 'rhits': $orderby = $db->quoteName('a.hits') . ' DESC'; break; case 'author': $orderby = $db->quoteName(['a.created_by_alias', 'u.name']); break; case 'rauthor': $orderby = $db->quoteName('a.created_by_alias') . ' DESC, ' . $db->quoteName('u.name') . ' DESC'; break; case 'front': $orderby = $db->quoteName('f.ordering'); break; default: $orderby = $db->quoteName('a.ordering'); break; } } $query->order($orderby); $case_when = ' CASE WHEN ' . $query->charLength($db->quoteName('a.alias'), '!=', '0') . ' THEN ' . $query->concatenate([$query->castAsChar($db->quoteName('a.id')), $db->quoteName('a.alias')], ':') . ' ELSE ' . $query->castAsChar('a.id') . ' END AS ' . $db->quoteName('slug'); $case_when1 = ' CASE WHEN ' . $query->charLength($db->quoteName('cc.alias'), '!=', '0') . ' THEN ' . $query->concatenate([$query->castAsChar($db->quoteName('cc.id')), $db->quoteName('cc.alias')], ':') . ' ELSE ' . $query->castAsChar('cc.id') . ' END AS ' . $db->quoteName('catslug'); $query->select($db->quoteName(['a.id', 'a.title', 'a.catid', 'a.language'])) ->select([$case_when, $case_when1]) ->from($db->quoteName('#__content', 'a')) ->join('LEFT', $db->quoteName('#__categories', 'cc'), $db->quoteName('cc.id') . ' = ' . $db->quoteName('a.catid')); if ($order_method === 'author' || $order_method === 'rauthor') { $query->select($db->quoteName(['a.created_by', 'u.name'])); $query->join('LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('a.created_by')); } $query->where( [ $db->quoteName('a.catid') . ' = :catid', $db->quoteName('a.state') . ' = :state', ] ) ->bind(':catid', $row->catid, ParameterType::INTEGER) ->bind(':state', $row->state, ParameterType::INTEGER); if (!$canPublish) { $query->whereIn($db->quoteName('a.access'), Access::getAuthorisedViewLevels($user->id)); } $query->where( [ '(' . $db->quoteName('publish_up') . ' IS NULL OR ' . $db->quoteName('publish_up') . ' <= :nowDate1)', '(' . $db->quoteName('publish_down') . ' IS NULL OR ' . $db->quoteName('publish_down') . ' >= :nowDate2)', ] ) ->bind(':nowDate1', $now) ->bind(':nowDate2', $now); if ($app->isClient('site') && $app->getLanguageFilter()) { $query->whereIn($db->quoteName('a.language'), [$lang->getTag(), '*'], ParameterType::STRING); } $db->setQuery($query); $list = $db->loadObjectList('id'); // This check needed if incorrect Itemid is given resulting in an incorrect result. if (!is_array($list)) { $list = []; } reset($list); // Location of current content item in array list. $location = array_search($uid, array_keys($list)); $rows = array_values($list); $row->prev = null; $row->next = null; if ($location - 1 >= 0) { // The previous content item cannot be in the array position -1. $row->prev = $rows[$location - 1]; } if (($location + 1) < count($rows)) { // The next content item cannot be in an array position greater than the number of array positions. $row->next = $rows[$location + 1]; } if ($row->prev) { $row->prev_label = ($this->params->get('display', 0) == 0) ? $lang->_('JPREV') : $row->prev->title; $row->prev = RouteHelper::getArticleRoute($row->prev->slug, $row->prev->catid, $row->prev->language); } else { $row->prev_label = ''; $row->prev = ''; } if ($row->next) { $row->next_label = ($this->params->get('display', 0) == 0) ? $lang->_('JNEXT') : $row->next->title; $row->next = RouteHelper::getArticleRoute($row->next->slug, $row->next->catid, $row->next->language); } else { $row->next_label = ''; $row->next = ''; } // Output. if ($row->prev || $row->next) { // Get the path for the layout file $path = PluginHelper::getLayoutPath('content', 'pagenavigation'); // Render the pagenav ob_start(); include $path; $row->pagination = ob_get_clean(); $row->paginationposition = $this->params->get('position', 1); // This will default to the 1.5 and 1.6-1.7 behavior. $row->paginationrelative = $this->params->get('relative', 0); } } } } PK!F3content/jce/jce.phpnu[triggerEvent('onPlgSystemJceContentPrepareForm', array($form, $data)); } } PK!DKcontent/jce/jce.xmlnu[ plg_content_jce 2.9.33 18-01-2023 Ryan Demmer info@joomlacontenteditor.net http://www.joomlacontenteditor.net Copyright (C) 2006 - 2022 Ryan Demmer. All rights reserved GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html PLG_CONTENT_JCE_XML_DESCRIPTION jce.php en-GB.plg_content_jce.ini en-GB.plg_content_jce.sys.ini PK!Hx/!!$content/joomla/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\User\UserFactoryInterface; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\Joomla\Extension\Joomla; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Joomla( $dispatcher, (array) PluginHelper::getPlugin('content', 'joomla') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); $plugin->setUserFactory($container->get(UserFactoryInterface::class)); return $plugin; } ); } }; PK!{'^content/joomla/joomla.xmlnu[ plg_content_joomla Joomla! Project 2010-11 (C) 2010 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_CONTENT_JOOMLA_XML_DESCRIPTION Joomla\Plugin\Content\Joomla services src language/en-GB/plg_content_joomla.ini language/en-GB/plg_content_joomla.sys.ini
    PK!pJJ'content/joomla/src/Extension/Joomla.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\Joomla\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Language\Language; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Table\CoreContent; use Joomla\CMS\User\UserFactoryAwareTrait; use Joomla\CMS\Workflow\WorkflowServiceInterface; use Joomla\Component\Workflow\Administrator\Table\StageTable; use Joomla\Component\Workflow\Administrator\Table\WorkflowTable; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Example Content Plugin * * @since 1.6 */ final class Joomla extends CMSPlugin { use DatabaseAwareTrait; use UserFactoryAwareTrait; /** * The save event. * * @param string $context The context * @param object $table The item * @param boolean $isNew Is new item * @param array $data The validated data * * @return boolean * * @since 4.0.0 */ public function onContentBeforeSave($context, $table, $isNew, $data) { if ($context === 'com_menus.item') { return $this->checkMenuItemBeforeSave($context, $table, $isNew, $data); } // Check we are handling the frontend edit form. if (!in_array($context, ['com_workflow.stage', 'com_workflow.workflow']) || $isNew || !$table->hasField('published')) { return true; } $item = clone $table; $item->load($table->id); $publishedField = $item->getColumnAlias('published'); if ($item->$publishedField > 0 && isset($data[$publishedField]) && $data[$publishedField] < 1) { switch ($context) { case 'com_workflow.workflow': return $this->workflowNotUsed($item->id); case 'com_workflow.stage': return $this->stageNotUsed($item->id); } } return true; } /** * Example after save content method * Article is passed by reference, but after the save, so no changes will be saved. * Method is called right after the content is saved * * @param string $context The context of the content passed to the plugin (added in 1.6) * @param object $article A JTableContent object * @param boolean $isNew If the content is just about to be created * * @return void * * @since 1.6 */ public function onContentAfterSave($context, $article, $isNew): void { // Check we are handling the frontend edit form. if ($context !== 'com_content.form') { return; } // Check if this function is enabled. if (!$this->params->def('email_new_fe', 1)) { return; } // Check this is a new article. if (!$isNew) { return; } $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName('id')) ->from($db->quoteName('#__users')) ->where($db->quoteName('sendEmail') . ' = 1') ->where($db->quoteName('block') . ' = 0'); $db->setQuery($query); $users = (array) $db->loadColumn(); if (empty($users)) { return; } $user = $this->getApplication()->getIdentity(); // Messaging for new items $default_language = ComponentHelper::getParams('com_languages')->get('administrator'); $debug = $this->getApplication()->get('debug_lang'); foreach ($users as $user_id) { if ($user_id != $user->id) { // Load language for messaging $receiver = $this->getUserFactory()->loadUserById($user_id); $lang = Language::getInstance($receiver->getParam('admin_language', $default_language), $debug); $lang->load('com_content'); $message = [ 'user_id_to' => $user_id, 'subject' => $lang->_('COM_CONTENT_NEW_ARTICLE'), 'message' => sprintf($lang->_('COM_CONTENT_ON_NEW_CONTENT'), $user->get('name'), $article->title), ]; $model_message = $this->getApplication()->bootComponent('com_messages')->getMVCFactory() ->createModel('Message', 'Administrator'); $model_message->save($message); } } } /** * Don't allow categories to be deleted if they contain items or subcategories with items * * @param string $context The context for the content passed to the plugin. * @param object $data The data relating to the content that was deleted. * * @return boolean * * @since 1.6 */ public function onContentBeforeDelete($context, $data) { // Skip plugin if we are deleting something other than categories if (!in_array($context, ['com_categories.category', 'com_workflow.stage', 'com_workflow.workflow'])) { return true; } switch ($context) { case 'com_categories.category': return $this->canDeleteCategories($data); case 'com_workflow.workflow': return $this->workflowNotUsed($data->id); case 'com_workflow.stage': return $this->stageNotUsed($data->id); } } /** * Don't allow workflows/stages to be deleted if they contain items * * @param string $context The context for the content passed to the plugin. * @param object $pks The IDs of the records which will be changed. * @param object $value The new state. * * @return boolean * * @since 4.0.0 */ public function onContentBeforeChangeState($context, $pks, $value) { if ($value > 0 || !in_array($context, ['com_workflow.workflow', 'com_workflow.stage'])) { return true; } $result = true; foreach ($pks as $id) { switch ($context) { case 'com_workflow.workflow': $result = $result && $this->workflowNotUsed($id); break; case 'com_workflow.stage': $result = $result && $this->stageNotUsed($id); break; } } return $result; } /** * Checks if a given category can be deleted * * @param object $data The category object * * @return boolean */ private function canDeleteCategories($data) { // Check if this function is enabled. if (!$this->params->def('check_categories', 1)) { return true; } $extension = $this->getApplication()->getInput()->getString('extension'); // Default to true if not a core extension $result = true; $tableInfo = [ 'com_banners' => ['table_name' => '#__banners'], 'com_contact' => ['table_name' => '#__contact_details'], 'com_content' => ['table_name' => '#__content'], 'com_newsfeeds' => ['table_name' => '#__newsfeeds'], 'com_users' => ['table_name' => '#__user_notes'], 'com_weblinks' => ['table_name' => '#__weblinks'], ]; // Now check to see if this is a known core extension if (isset($tableInfo[$extension])) { // Get table name for known core extensions $table = $tableInfo[$extension]['table_name']; // See if this category has any content items $count = $this->countItemsInCategory($table, $data->get('id')); // Return false if db error if ($count === false) { $result = false; } else { // Show error if items are found in the category if ($count > 0) { $msg = Text::sprintf('COM_CATEGORIES_DELETE_NOT_ALLOWED', $data->get('title')) . ' ' . Text::plural('COM_CATEGORIES_N_ITEMS_ASSIGNED', $count); $this->getApplication()->enqueueMessage($msg, 'error'); $result = false; } // Check for items in any child categories (if it is a leaf, there are no child categories) if (!$data->isLeaf()) { $count = $this->countItemsInChildren($table, $data->get('id'), $data); if ($count === false) { $result = false; } elseif ($count > 0) { $msg = Text::sprintf('COM_CATEGORIES_DELETE_NOT_ALLOWED', $data->get('title')) . ' ' . Text::plural('COM_CATEGORIES_HAS_SUBCATEGORY_ITEMS', $count); $this->getApplication()->enqueueMessage($msg, 'error'); $result = false; } } } } return $result; } /** * Checks if a given workflow can be deleted * * @param int $pk The stage ID * * @return boolean * * @since 4.0.0 */ private function workflowNotUsed($pk) { // Check if this workflow is the default stage $table = new WorkflowTable($this->getDatabase()); $table->load($pk); if (empty($table->id)) { return true; } if ($table->default) { throw new \Exception($this->getApplication()->getLanguage()->_('COM_WORKFLOW_MSG_DELETE_IS_DEFAULT')); } $parts = explode('.', $table->extension); $component = $this->getApplication()->bootComponent($parts[0]); $section = ''; if (!empty($parts[1])) { $section = $parts[1]; } // No core interface => we're ok if (!$component instanceof WorkflowServiceInterface) { return true; } /** @var \Joomla\Component\Workflow\Administrator\Model\StagesModel $model */ $model = $this->getApplication()->bootComponent('com_workflow')->getMVCFactory() ->createModel('Stages', 'Administrator', ['ignore_request' => true]); $model->setState('filter.workflow_id', $pk); $model->setState('filter.extension', $table->extension); $stages = $model->getItems(); $stage_ids = array_column($stages, 'id'); $result = $this->countItemsInStage($stage_ids, $table->extension); // Return false if db error if ($result > 0) { throw new \Exception($this->getApplication()->getLanguage()->_('COM_WORKFLOW_MSG_DELETE_WORKFLOW_IS_ASSIGNED')); } return true; } /** * Checks if a given stage can be deleted * * @param int $pk The stage ID * * @return boolean * * @since 4.0.0 */ private function stageNotUsed($pk) { $table = new StageTable($this->getDatabase()); $table->load($pk); if (empty($table->id)) { return true; } // Check if this stage is the default stage if ($table->default) { throw new \Exception($this->getApplication()->getLanguage()->_('COM_WORKFLOW_MSG_DELETE_IS_DEFAULT')); } $workflow = new WorkflowTable($this->getDatabase()); $workflow->load($table->workflow_id); if (empty($workflow->id)) { return true; } $parts = explode('.', $workflow->extension); $component = $this->getApplication()->bootComponent($parts[0]); // No core interface => we're ok if (!$component instanceof WorkflowServiceInterface) { return true; } $stage_ids = [$table->id]; $result = $this->countItemsInStage($stage_ids, $workflow->extension); // Return false if db error if ($result > 0) { throw new \Exception($this->getApplication()->getLanguage()->_('COM_WORKFLOW_MSG_DELETE_STAGE_IS_ASSIGNED')); } return true; } /** * Get count of items in a category * * @param string $table table name of component table (column is catid) * @param integer $catid id of the category to check * * @return mixed count of items found or false if db error * * @since 1.6 */ private function countItemsInCategory($table, $catid) { $db = $this->getDatabase(); $query = $db->getQuery(true); // Count the items in this category $query->select('COUNT(' . $db->quoteName('id') . ')') ->from($db->quoteName($table)) ->where($db->quoteName('catid') . ' = :catid') ->bind(':catid', $catid, ParameterType::INTEGER); $db->setQuery($query); try { $count = $db->loadResult(); } catch (\RuntimeException $e) { $this->getApplication()->enqueueMessage($e->getMessage(), 'error'); return false; } return $count; } /** * Get count of items in assigned to a stage * * @param array $stageIds The stage ids to test for * @param string $extension The extension of the workflow * * @return bool * * @since 4.0.0 */ private function countItemsInStage(array $stageIds, string $extension): bool { $db = $this->getDatabase(); $parts = explode('.', $extension); $stageIds = ArrayHelper::toInteger($stageIds); $stageIds = array_filter($stageIds); $section = ''; if (!empty($parts[1])) { $section = $parts[1]; } $component = $this->getApplication()->bootComponent($parts[0]); $table = $component->getWorkflowTableBySection($section); if (empty($stageIds) || !$table) { return false; } $query = $db->getQuery(true); $query->select('COUNT(' . $db->quoteName('b.id') . ')') ->from($db->quoteName('#__workflow_associations', 'wa')) ->from($db->quoteName('#__workflow_stages', 's')) ->from($db->quoteName($table, 'b')) ->where($db->quoteName('wa.stage_id') . ' = ' . $db->quoteName('s.id')) ->where($db->quoteName('wa.item_id') . ' = ' . $db->quoteName('b.id')) ->whereIn($db->quoteName('s.id'), $stageIds); try { return (int) $db->setQuery($query)->loadResult(); } catch (\Exception $e) { $this->getApplication()->enqueueMessage($e->getMessage(), 'error'); } return false; } /** * Get count of items in a category's child categories * * @param string $table table name of component table (column is catid) * @param integer $catid id of the category to check * @param object $data The data relating to the content that was deleted. * * @return mixed count of items found or false if db error * * @since 1.6 */ private function countItemsInChildren($table, $catid, $data) { $db = $this->getDatabase(); // Create subquery for list of child categories $childCategoryTree = $data->getTree(); // First element in tree is the current category, so we can skip that one unset($childCategoryTree[0]); $childCategoryIds = []; foreach ($childCategoryTree as $node) { $childCategoryIds[] = (int) $node->id; } // Make sure we only do the query if we have some categories to look in if (count($childCategoryIds)) { // Count the items in this category $query = $db->getQuery(true) ->select('COUNT(' . $db->quoteName('id') . ')') ->from($db->quoteName($table)) ->whereIn($db->quoteName('catid'), $childCategoryIds); $db->setQuery($query); try { $count = $db->loadResult(); } catch (\RuntimeException $e) { $this->getApplication()->enqueueMessage($e->getMessage(), 'error'); return false; } return $count; } else { // If we didn't have any categories to check, return 0 return 0; } } /** * Change the state in core_content if the stage in a table is changed * * @param string $context The context for the content passed to the plugin. * @param array $pks A list of primary key ids of the content that has changed stage. * @param integer $value The value of the condition that the content has been changed to * * @return boolean * * @since 3.1 */ public function onContentChangeState($context, $pks, $value) { $pks = ArrayHelper::toInteger($pks); if ($context === 'com_workflow.stage' && $value < 1) { foreach ($pks as $pk) { if (!$this->stageNotUsed($pk)) { return false; } } return true; } $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName('core_content_id')) ->from($db->quoteName('#__ucm_content')) ->where($db->quoteName('core_type_alias') . ' = :context') ->whereIn($db->quoteName('core_content_item_id'), $pks) ->bind(':context', $context); $db->setQuery($query); $ccIds = $db->loadColumn(); $cctable = new CoreContent($db); $cctable->publish($ccIds, $value); return true; } /** * The save event. * * @param string $context The context * @param object $table The item * @param boolean $isNew Is new item * @param array $data The validated data * * @return boolean * * @since 3.9.12 */ private function checkMenuItemBeforeSave($context, $table, $isNew, $data) { // Special case for Create article menu item if ($table->link !== 'index.php?option=com_content&view=form&layout=edit') { return true; } // Display error if catid is not set when enable_category is enabled $params = json_decode($table->params, true); if ($params['enable_category'] == 1 && empty($params['catid'])) { $table->setError($this->getApplication()->getLanguage()->_('COM_CONTENT_CREATE_ARTICLE_ERROR')); return false; } return true; } } PK!^gcontent/finder/finder.xmlnu[ plg_content_finder Joomla! Project 2011-12 (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_CONTENT_FINDER_XML_DESCRIPTION Joomla\Plugin\Content\Finder services src language/en-GB/plg_content_finder.ini language/en-GB/plg_content_finder.sys.ini PK!U̪(($content/finder/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\Finder\Extension\Finder; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Finder( $dispatcher, (array) PluginHelper::getPlugin('content', 'finder') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!/{'''content/finder/src/Extension/Finder.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\Finder\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Smart Search Content Plugin * * @since 2.5 */ final class Finder extends CMSPlugin { /** * Smart Search after save content method. * Content is passed by reference, but after the save, so no changes will be saved. * Method is called right after the content is saved. * * @param string $context The context of the content passed to the plugin (added in 1.6) * @param object $article A JTableContent object * @param bool $isNew If the content has just been created * * @return void * * @since 2.5 */ public function onContentAfterSave($context, $article, $isNew): void { PluginHelper::importPlugin('finder'); // Trigger the onFinderAfterSave event. $this->getApplication()->triggerEvent('onFinderAfterSave', [$context, $article, $isNew]); } /** * Smart Search before save content method. * Content is passed by reference. Method is called before the content is saved. * * @param string $context The context of the content passed to the plugin (added in 1.6). * @param object $article A JTableContent object. * @param bool $isNew If the content is just about to be created. * * @return void * * @since 2.5 */ public function onContentBeforeSave($context, $article, $isNew) { PluginHelper::importPlugin('finder'); // Trigger the onFinderBeforeSave event. $this->getApplication()->triggerEvent('onFinderBeforeSave', [$context, $article, $isNew]); } /** * Smart Search after delete content method. * Content is passed by reference, but after the deletion. * * @param string $context The context of the content passed to the plugin (added in 1.6). * @param object $article A JTableContent object. * * @return void * * @since 2.5 */ public function onContentAfterDelete($context, $article): void { PluginHelper::importPlugin('finder'); // Trigger the onFinderAfterDelete event. $this->getApplication()->triggerEvent('onFinderAfterDelete', [$context, $article]); } /** * Smart Search content state change method. * Method to update the link information for items that have been changed * from outside the edit screen. This is fired when the item is published, * unpublished, archived, or unarchived from the list view. * * @param string $context The context for the content passed to the plugin. * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ public function onContentChangeState($context, $pks, $value) { PluginHelper::importPlugin('finder'); // Trigger the onFinderChangeState event. $this->getApplication()->triggerEvent('onFinderChangeState', [$context, $pks, $value]); } /** * Smart Search change category state content method. * Method is called when the state of the category to which the * content item belongs is changed. * * @param string $extension The extension whose category has been updated. * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ public function onCategoryChangeState($extension, $pks, $value) { PluginHelper::importPlugin('finder'); // Trigger the onFinderCategoryChangeState event. $this->getApplication()->triggerEvent('onFinderCategoryChangeState', [$extension, $pks, $value]); } } PK!<<(content/loadmodule/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\LoadModule\Extension\LoadModule; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new LoadModule( $dispatcher, (array) PluginHelper::getPlugin('content', 'loadmodule') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!p99!content/loadmodule/loadmodule.xmlnu[ plg_content_loadmodule Joomla! Project 2005-11 (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_LOADMODULE_XML_DESCRIPTION Joomla\Plugin\Content\LoadModule services src language/en-GB/plg_content_loadmodule.ini language/en-GB/plg_content_loadmodule.sys.ini
    PK!F!!/content/loadmodule/src/Extension/LoadModule.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\LoadModule\Extension; use Joomla\CMS\Helper\ModuleHelper; use Joomla\CMS\Plugin\CMSPlugin; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Plugin to enable loading modules into content (e.g. articles) * This uses the {loadmodule} syntax * * @since 1.5 */ final class LoadModule extends CMSPlugin { protected static $modules = []; protected static $mods = []; /** * Plugin that loads module positions within content * * @param string $context The context of the content being passed to the plugin. * @param object &$article The article object. Note $article->text is also available * @param mixed &$params The article params * @param integer $page The 'page' number * * @return void * * @since 1.6 */ public function onContentPrepare($context, &$article, &$params, $page = 0) { // Only execute if $article is an object and has a text property if (!is_object($article) || !property_exists($article, 'text') || is_null($article->text)) { return; } $defaultStyle = $this->params->get('style', 'none'); // Fallback xhtml (used in Joomla 3) to html5 if ($defaultStyle === 'xhtml') { $defaultStyle = 'html5'; } // Expression to search for (positions) $regex = '/{loadposition\s(.*?)}/i'; // Expression to search for(modules) $regexmod = '/{loadmodule\s(.*?)}/i'; // Expression to search for(id) $regexmodid = '/{loadmoduleid\s([1-9][0-9]*)}/i'; // Remove macros and don't run this plugin when the content is being indexed if ($context === 'com_finder.indexer') { if (str_contains($article->text, 'loadposition')) { $article->text = preg_replace($regex, '', $article->text); } if (str_contains($article->text, 'loadmoduleid')) { $article->text = preg_replace($regexmodid, '', $article->text); } if (str_contains($article->text, 'loadmodule')) { $article->text = preg_replace($regexmod, '', $article->text); } return; } if (str_contains($article->text, '{loadposition ')) { // Find all instances of plugin and put in $matches for loadposition // $matches[0] is full pattern match, $matches[1] is the position preg_match_all($regex, $article->text, $matches, PREG_SET_ORDER); // No matches, skip this if ($matches) { foreach ($matches as $match) { $matcheslist = explode(',', $match[1]); // We may not have a module style so fall back to the plugin default. if (!array_key_exists(1, $matcheslist)) { $matcheslist[1] = $defaultStyle; } $position = trim($matcheslist[0]); $style = trim($matcheslist[1]); $output = $this->load($position, $style); // We should replace only first occurrence in order to allow positions with the same name to regenerate their content: if (($start = strpos($article->text, $match[0])) !== false) { $article->text = substr_replace($article->text, $output, $start, strlen($match[0])); } } } } if (str_contains($article->text, '{loadmodule ')) { // Find all instances of plugin and put in $matchesmod for loadmodule preg_match_all($regexmod, $article->text, $matchesmod, PREG_SET_ORDER); // If no matches, skip this if ($matchesmod) { foreach ($matchesmod as $matchmod) { $matchesmodlist = explode(',', $matchmod[1]); // First parameter is the module, will be prefixed with mod_ later $module = trim($matchesmodlist[0]); // Second parameter is the title $title = ''; if (array_key_exists(1, $matchesmodlist)) { $title = htmlspecialchars_decode(trim($matchesmodlist[1])); } // Third parameter is the module style, (fallback is the plugin default set earlier). $stylemod = $defaultStyle; if (array_key_exists(2, $matchesmodlist)) { $stylemod = trim($matchesmodlist[2]); } $output = $this->loadModule($module, $title, $stylemod); // We should replace only first occurrence in order to allow positions with the same name to regenerate their content: if (($start = strpos($article->text, $matchmod[0])) !== false) { $article->text = substr_replace($article->text, $output, $start, strlen($matchmod[0])); } } } } if (str_contains($article->text, '{loadmoduleid ')) { // Find all instances of plugin and put in $matchesmodid for loadmoduleid preg_match_all($regexmodid, $article->text, $matchesmodid, PREG_SET_ORDER); // If no matches, skip this if ($matchesmodid) { foreach ($matchesmodid as $match) { $id = trim($match[1]); $output = $this->loadID($id); // We should replace only first occurrence in order to allow positions with the same name to regenerate their content: if (($start = strpos($article->text, $match[0])) !== false) { $article->text = substr_replace($article->text, $output, $start, strlen($match[0])); } } } } } /** * Loads and renders the module * * @param string $position The position assigned to the module * @param string $style The style assigned to the module * * @return mixed * * @since 1.6 */ private function load($position, $style = 'none') { $document = $this->getApplication()->getDocument(); $renderer = $document->loadRenderer('module'); $modules = ModuleHelper::getModules($position); $params = ['style' => $style]; ob_start(); foreach ($modules as $module) { echo $renderer->render($module, $params); } return ob_get_clean(); } /** * This is always going to get the first instance of the module type unless * there is a title. * * @param string $module The module title * @param string $title The title of the module * @param string $style The style of the module * * @return mixed * * @since 1.6 */ private function loadModule($module, $title, $style = 'none') { $document = $this->getApplication()->getDocument(); $renderer = $document->loadRenderer('module'); $mod = ModuleHelper::getModule($module, $title); // If the module without the mod_ isn't found, try it with mod_. // This allows people to enter it either way in the content if (!isset($mod)) { $name = 'mod_' . $module; $mod = ModuleHelper::getModule($name, $title); } $params = ['style' => $style]; ob_start(); if ($mod->id) { echo $renderer->render($mod, $params); } return ob_get_clean(); } /** * Loads and renders the module * * @param string $id The id of the module * * @return mixed * * @since 3.9.0 */ private function loadID($id) { $document = $this->getApplication()->getDocument(); $renderer = $document->loadRenderer('module'); $modules = ModuleHelper::getModuleById($id); $params = ['style' => 'none']; ob_start(); if ($modules->id > 0) { echo $renderer->render($modules, $params); } return ob_get_clean(); } } PK!m/Y%content/contact/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\Contact\Extension\Contact; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Contact( $dispatcher, (array) PluginHelper::getPlugin('content', 'contact') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!(9content/contact/contact.xmlnu[ plg_content_contact Joomla! Project 2014-01 (C) 2014 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.2.2 PLG_CONTENT_CONTACT_XML_DESCRIPTION Joomla\Plugin\Content\Contact services src language/en-GB/plg_content_contact.ini language/en-GB/plg_content_contact.sys.ini
    PK!%})content/contact/src/Extension/Contact.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\Contact\Extension; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Router\Route; use Joomla\Component\Contact\Site\Helper\RouteHelper; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Contact Plugin * * @since 3.2 */ final class Contact extends CMSPlugin { use DatabaseAwareTrait; /** * Plugin that retrieves contact information for contact * * @param string $context The context of the content being passed to the plugin. * @param mixed &$row An object with a "text" property * @param mixed $params Additional parameters. See {@see PlgContentContent()}. * @param integer $page Optional page number. Unused. Defaults to zero. * * @return void */ public function onContentPrepare($context, &$row, $params, $page = 0) { $allowed_contexts = ['com_content.category', 'com_content.article', 'com_content.featured']; if (!in_array($context, $allowed_contexts)) { return; } // Return if we don't have valid params or don't link the author if (!($params instanceof Registry) || !$params->get('link_author')) { return; } // Return if an alias is used if ((int) $this->params->get('link_to_alias', 0) === 0 && $row->created_by_alias != '') { return; } // Return if we don't have a valid article id if (!isset($row->id) || !(int) $row->id) { return; } $contact = $this->getContactData($row->created_by); if ($contact === null) { return; } $row->contactid = $contact->contactid; $row->webpage = $contact->webpage; $row->email = $contact->email_to; $url = $this->params->get('url', 'url'); if ($row->contactid && $url === 'url') { $row->contact_link = Route::_(RouteHelper::getContactRoute($contact->contactid . ':' . $contact->alias, $contact->catid)); } elseif ($row->webpage && $url === 'webpage') { $row->contact_link = $row->webpage; } elseif ($row->email && $url === 'email') { $row->contact_link = 'mailto:' . $row->email; } else { $row->contact_link = ''; } } /** * Retrieve Contact * * @param int $userId Id of the user who created the article * * @return stdClass|null Object containing contact details or null if not found */ private function getContactData($userId) { static $contacts = []; // Note: don't use isset() because value could be null. if (array_key_exists($userId, $contacts)) { return $contacts[$userId]; } $db = $this->getDatabase(); $query = $db->getQuery(true); $userId = (int) $userId; $query->select($db->quoteName('contact.id', 'contactid')) ->select( $db->quoteName( [ 'contact.alias', 'contact.catid', 'contact.webpage', 'contact.email_to', ] ) ) ->from($db->quoteName('#__contact_details', 'contact')) ->where( [ $db->quoteName('contact.published') . ' = 1', $db->quoteName('contact.user_id') . ' = :createdby', ] ) ->bind(':createdby', $userId, ParameterType::INTEGER); if (Multilanguage::isEnabled() === true) { $query->where( '(' . $db->quoteName('contact.language') . ' IN (' . implode(',', $query->bindArray([$this->getApplication()->getLanguage()->getTag(), '*'], ParameterType::STRING)) . ') OR ' . $db->quoteName('contact.language') . ' IS NULL)' ); } $query->order($db->quoteName('contact.id') . ' DESC') ->setLimit(1); $db->setQuery($query); $contacts[$userId] = $db->loadObject(); return $contacts[$userId]; } } PK!`JJ,content/confirmconsent/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Content\ConfirmConsent\Extension\ConfirmConsent; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new ConfirmConsent( $dispatcher, (array) PluginHelper::getPlugin('content', 'confirmconsent') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!u99 9 )content/confirmconsent/confirmconsent.xmlnu[ plg_content_confirmconsent Joomla! Project 2018-05 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_CONTENT_CONFIRMCONSENT_XML_DESCRIPTION Joomla\Plugin\Content\ConfirmConsent services src language/en-GB/plg_content_confirmconsent.ini language/en-GB/plg_content_confirmconsent.sys.ini
    PK!'L 7content/confirmconsent/src/Extension/ConfirmConsent.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\ConfirmConsent\Extension; use Joomla\CMS\Form\Form; use Joomla\CMS\Plugin\CMSPlugin; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * The Joomla Core confirm consent plugin * * @since 3.9.0 */ final class ConfirmConsent extends CMSPlugin { /** * Load the language file on instantiation. * * @var boolean * * @since 3.9.0 */ protected $autoloadLanguage = true; /** * The supported form contexts * * @var array * * @since 3.9.0 */ protected $supportedContext = [ 'com_contact.contact', 'com_privacy.request', ]; /** * Add additional fields to the supported forms * * @param Form $form The form to be altered. * @param mixed $data The associated data for the form. * * @return boolean * * @since 3.9.0 */ public function onContentPrepareForm(Form $form, $data) { if ($this->getApplication()->isClient('administrator') || !in_array($form->getName(), $this->supportedContext)) { return true; } // Get the consent box Text & the selected privacyarticle $consentboxText = (string) $this->params->get( 'consentbox_text', $this->getApplication()->getLanguage()->_('PLG_CONTENT_CONFIRMCONSENT_FIELD_NOTE_DEFAULT') ); $privacyArticle = $this->params->get('privacy_article', false); $privacyType = $this->params->get('privacy_type', 'article'); $privacyMenuItem = $this->params->get('privacy_menu_item', false); $form->load('
    '); return true; } } PK!s))))4content/confirmconsent/src/Field/ConsentBoxField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Content\ConfirmConsent\Field; use Joomla\CMS\Factory; use Joomla\CMS\Form\Field\CheckboxesField; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Associations; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Router\Route; use Joomla\Component\Content\Site\Helper\RouteHelper; use Joomla\Database\Exception\ExecutionFailureException; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Consentbox Field class for the Confirm Consent Plugin. * * @since 3.9.1 */ class ConsentBoxField extends CheckboxesField { /** * The form field type. * * @var string * @since 3.9.1 */ protected $type = 'ConsentBox'; /** * Flag to tell the field to always be in multiple values mode. * * @var boolean * @since 3.9.1 */ protected $forceMultiple = false; /** * The article ID. * * @var integer * @since 3.9.1 */ protected $articleid; /** * The menu item ID. * * @var integer * @since 4.0.0 */ protected $menuItemId; /** * Type of the privacy policy. * * @var string * @since 4.0.0 */ protected $privacyType; /** * Method to set certain otherwise inaccessible properties of the form field object. * * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void * * @since 3.9.1 */ public function __set($name, $value) { switch ($name) { case 'articleid': $this->articleid = (int) $value; break; default: parent::__set($name, $value); } } /** * Method to get certain otherwise inaccessible properties from the form field object. * * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * * @since 3.9.1 */ public function __get($name) { if ($name == 'articleid') { return $this->$name; } return parent::__get($name); } /** * Method to attach a JForm object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see \Joomla\CMS\Form\FormField::setup() * @since 3.9.1 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $return = parent::setup($element, $value, $group); if ($return) { $this->articleid = (int) $this->element['articleid']; $this->menuItemId = (int) $this->element['menu_item_id']; $this->privacyType = (string) $this->element['privacy_type']; } return $return; } /** * Method to get the field label markup. * * @return string The field label markup. * * @since 3.9.1 */ protected function getLabel() { if ($this->hidden) { return ''; } $data = $this->getLayoutData(); // Forcing the Alias field to display the tip below $position = $this->element['name'] == 'alias' ? ' data-bs-placement="bottom" ' : ''; // When we have an article let's add the modal and make the title clickable $hasLink = ($data['privacyType'] === 'article' && $data['articleid']) || ($data['privacyType'] === 'menu_item' && $data['menuItemId']); if ($hasLink) { $attribs['data-bs-toggle'] = 'modal'; $data['label'] = HTMLHelper::_( 'link', '#modal-' . $this->id, $data['label'], $attribs ); } // Here mainly for B/C with old layouts. This can be done in the layouts directly $extraData = [ 'text' => $data['label'], 'for' => $this->id, 'classes' => explode(' ', $data['labelclass']), 'position' => $position, ]; return $this->getRenderer($this->renderLabelLayout)->render(array_merge($data, $extraData)); } /** * Method to get the field input markup. * * @return string The field input markup. * * @since 4.0.0 */ protected function getInput() { $modalHtml = ''; $layoutData = $this->getLayoutData(); $hasLink = ($this->privacyType === 'article' && $this->articleid) || ($this->privacyType === 'menu_item' && $this->menuItemId); if ($hasLink) { $modalParams['title'] = $layoutData['label']; $modalParams['url'] = ($this->privacyType === 'menu_item') ? $this->getAssignedMenuItemUrl() : $this->getAssignedArticleUrl(); $modalParams['height'] = '100%'; $modalParams['width'] = '100%'; $modalParams['bodyHeight'] = 70; $modalParams['modalWidth'] = 80; $modalHtml = HTMLHelper::_('bootstrap.renderModal', 'modal-' . $this->id, $modalParams); } return $modalHtml . parent::getInput(); } /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 3.9.1 */ protected function getLayoutData() { $data = parent::getLayoutData(); $extraData = [ 'articleid' => (int) $this->articleid, 'menuItemId' => (int) $this->menuItemId, 'privacyType' => (string) $this->privacyType, ]; return array_merge($data, $extraData); } /** * Return the url of the assigned article based on the current user language * * @return string Returns the link to the article * * @since 3.9.1 */ private function getAssignedArticleUrl() { $db = $this->getDatabase(); // Get the info from the article $query = $db->getQuery(true) ->select($db->quoteName(['id', 'catid', 'language'])) ->from($db->quoteName('#__content')) ->where($db->quoteName('id') . ' = ' . (int) $this->articleid); $db->setQuery($query); try { $article = $db->loadObject(); } catch (ExecutionFailureException $e) { // Something at the database layer went wrong return Route::_( 'index.php?option=com_content&view=article&id=' . $this->articleid . '&tmpl=component' ); } if (!\is_object($article)) { // We have not found the article object lets show a 404 to the user return Route::_( 'index.php?option=com_content&view=article&id=' . $this->articleid . '&tmpl=component' ); } if (!Associations::isEnabled()) { return Route::_( RouteHelper::getArticleRoute( $article->id, $article->catid, $article->language ) . '&tmpl=component' ); } $associatedArticles = Associations::getAssociations('com_content', '#__content', 'com_content.item', $article->id); $currentLang = Factory::getLanguage()->getTag(); if (isset($associatedArticles) && $currentLang !== $article->language && \array_key_exists($currentLang, $associatedArticles)) { return Route::_( RouteHelper::getArticleRoute( $associatedArticles[$currentLang]->id, $associatedArticles[$currentLang]->catid, $associatedArticles[$currentLang]->language ) . '&tmpl=component' ); } // Association is enabled but this article is not associated return Route::_( 'index.php?option=com_content&view=article&id=' . $article->id . '&catid=' . $article->catid . '&tmpl=component&lang=' . $article->language ); } /** * Get privacy menu item URL. If the site is a multilingual website and there is associated menu item for the * current language, the URL of the associated menu item will be returned. * * @return string * * @since 4.0.0 */ private function getAssignedMenuItemUrl() { $itemId = $this->menuItemId; $languageSuffix = ''; if ($itemId > 0 && Associations::isEnabled()) { $privacyAssociated = Associations::getAssociations('com_menus', '#__menu', 'com_menus.item', $itemId, 'id', '', ''); $currentLang = Factory::getLanguage()->getTag(); if (isset($privacyAssociated[$currentLang])) { $itemId = $privacyAssociated[$currentLang]->id; } if (Multilanguage::isEnabled()) { $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName(['id', 'language'])) ->from($db->quoteName('#__menu')) ->where($db->quoteName('id') . ' = :id') ->bind(':id', $itemId, ParameterType::INTEGER); $db->setQuery($query); $menuItem = $db->loadObject(); $languageSuffix = '&lang=' . $menuItem->language; } } return Route::_( 'index.php?Itemid=' . (int) $itemId . '&tmpl=component' . $languageSuffix ); } } PK!:fB B 3captcha/recaptcha_invisible/recaptcha_invisible.xmlnu[ plg_captcha_recaptcha_invisible 3.8 2017-11 Joomla! Project admin@joomla.org www.joomla.org (C) 2017 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt PLG_CAPTCHA_RECAPTCHA_INVISIBLE_XML_DESCRIPTION Joomla\Plugin\Captcha\InvisibleReCaptcha services src language/en-GB/plg_captcha_recaptcha_invisible.ini language/en-GB/plg_captcha_recaptcha_invisible.sys.ini
    PK!yYT1captcha/recaptcha_invisible/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Captcha\Google\HttpBridgePostRequestMethod; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Captcha\InvisibleReCaptcha\Extension\InvisibleReCaptcha; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $plugin = new InvisibleReCaptcha( $container->get(DispatcherInterface::class), (array) PluginHelper::getPlugin('captcha', 'recaptcha_invisible'), new HttpBridgePostRequestMethod() ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK! ˲oo@captcha/recaptcha_invisible/src/Extension/InvisibleReCaptcha.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Captcha\InvisibleReCaptcha\Extension; use Joomla\CMS\Application\CMSWebApplicationInterface; use Joomla\CMS\Form\Field\CaptchaField; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\DispatcherInterface; use Joomla\Utilities\IpHelper; use ReCaptcha\ReCaptcha; use ReCaptcha\RequestMethod; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Invisible reCAPTCHA Plugin. * * @since 3.9.0 */ final class InvisibleReCaptcha extends CMSPlugin { /** * Load the language file on instantiation. * * @var boolean * @since 3.9.0 */ protected $autoloadLanguage = true; /** * The http request method * * @var RequestMethod * @since 4.3.0 */ private $requestMethod; /** * Constructor. * * @param DispatcherInterface $dispatcher The dispatcher * @param array $config An optional associative array of configuration settings * @param RequestMethod $requestMethod The http request method * * @since 4.3.0 */ public function __construct(DispatcherInterface $dispatcher, array $config, RequestMethod $requestMethod) { parent::__construct($dispatcher, $config); $this->requestMethod = $requestMethod; } /** * Reports the privacy related capabilities for this plugin to site administrators. * * @return array * * @since 3.9.0 */ public function onPrivacyCollectAdminCapabilities() { $this->loadLanguage(); return [ $this->getApplication()->getLanguage()->_('PLG_CAPTCHA_RECAPTCHA_INVISIBLE') => [ $this->getApplication()->getLanguage()->_('PLG_RECAPTCHA_INVISIBLE_PRIVACY_CAPABILITY_IP_ADDRESS'), ], ]; } /** * Initializes the captcha * * @param string $id The id of the field. * * @return boolean True on success, false otherwise * * @since 3.9.0 * @throws \RuntimeException */ public function onInit($id = 'dynamic_recaptcha_invisible_1') { $app = $this->getApplication(); if (!$app instanceof CMSWebApplicationInterface) { return false; } $pubkey = $this->params->get('public_key', ''); if ($pubkey === '') { throw new \RuntimeException($app->getLanguage()->_('PLG_RECAPTCHA_INVISIBLE_ERROR_NO_PUBLIC_KEY')); } $apiSrc = 'https://www.google.com/recaptcha/api.js?onload=JoomlainitReCaptchaInvisible&render=explicit&hl=' . $app->getLanguage()->getTag(); // Load assets, the callback should be first $app->getDocument()->getWebAssetManager() ->registerAndUseScript('plg_captcha_recaptchainvisible', 'plg_captcha_recaptcha_invisible/recaptcha.min.js', [], ['defer' => true]) ->registerAndUseScript('plg_captcha_recaptchainvisible.api', $apiSrc, [], ['defer' => true], ['plg_captcha_recaptchainvisible']) ->registerAndUseStyle('plg_captcha_recaptchainvisible', 'plg_captcha_recaptcha_invisible/recaptcha_invisible.css'); return true; } /** * Gets the challenge HTML * * @param string $name The name of the field. Not Used. * @param string $id The id of the field. * @param string $class The class of the field. * * @return string The HTML to be embedded in the form. * * @since 3.9.0 */ public function onDisplay($name = null, $id = 'dynamic_recaptcha_invisible_1', $class = '') { $dom = new \DOMDocument('1.0', 'UTF-8'); $ele = $dom->createElement('div'); $ele->setAttribute('id', $id); $ele->setAttribute('class', ((trim($class) == '') ? 'g-recaptcha' : ($class . ' g-recaptcha'))); $ele->setAttribute('data-sitekey', $this->params->get('public_key', '')); $ele->setAttribute('data-badge', $this->params->get('badge', 'bottomright')); $ele->setAttribute('data-size', 'invisible'); $ele->setAttribute('data-tabindex', $this->params->get('tabindex', '0')); $ele->setAttribute('data-callback', $this->params->get('callback', '')); $ele->setAttribute('data-expired-callback', $this->params->get('expired_callback', '')); $ele->setAttribute('data-error-callback', $this->params->get('error_callback', '')); $dom->appendChild($ele); return $dom->saveHTML($ele); } /** * Calls an HTTP POST function to verify if the user's guess was correct * * @param string $code Answer provided by user. Not needed for the Recaptcha implementation * * @return boolean True if the answer is correct, false otherwise * * @since 3.9.0 * @throws \RuntimeException */ public function onCheckAnswer($code = null) { $input = $this->getApplication()->getInput(); $privatekey = $this->params->get('private_key'); $remoteip = IpHelper::getIp(); $response = $input->get('g-recaptcha-response', '', 'string'); // Check for Private Key if (empty($privatekey)) { throw new \RuntimeException($this->getApplication()->getLanguage()->_('PLG_RECAPTCHA_INVISIBLE_ERROR_NO_PRIVATE_KEY')); } // Check for IP if (empty($remoteip)) { throw new \RuntimeException($this->getApplication()->getLanguage()->_('PLG_RECAPTCHA_INVISIBLE_ERROR_NO_IP')); } // Discard spam submissions if (trim($response) == '') { throw new \RuntimeException($this->getApplication()->getLanguage()->_('PLG_RECAPTCHA_INVISIBLE_ERROR_EMPTY_SOLUTION')); } return $this->getResponse($privatekey, $remoteip, $response); } /** * Method to react on the setup of a captcha field. Gives the possibility * to change the field and/or the XML element for the field. * * @param CaptchaField $field Captcha field instance * @param \SimpleXMLElement $element XML form definition * * @return void * * @since 3.9.0 */ public function onSetupField(CaptchaField $field, \SimpleXMLElement $element) { // Hide the label for the invisible recaptcha type $element['hiddenLabel'] = 'true'; } /** * Get the reCaptcha response. * * @param string $privatekey The private key for authentication. * @param string $remoteip The remote IP of the visitor. * @param string $response The response received from Google. * * @return boolean True if response is good | False if response is bad. * * @since 3.9.0 * @throws \RuntimeException */ private function getResponse($privatekey, $remoteip, $response) { $reCaptcha = new ReCaptcha($privatekey, $this->requestMethod); $response = $reCaptcha->verify($response, $remoteip); if (!$response->isSuccess()) { foreach ($response->getErrorCodes() as $error) { throw new \RuntimeException($error); } return false; } return true; } } PK!S& * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Captcha\Google\HttpBridgePostRequestMethod; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Captcha\ReCaptcha\Extension\ReCaptcha; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $plugin = new ReCaptcha( $container->get(DispatcherInterface::class), (array) PluginHelper::getPlugin('captcha', 'recaptcha'), new HttpBridgePostRequestMethod() ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!ή  captcha/recaptcha/recaptcha.xmlnu[ plg_captcha_recaptcha 3.4.0 2011-12 Joomla! Project admin@joomla.org www.joomla.org (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt PLG_CAPTCHA_RECAPTCHA_XML_DESCRIPTION Joomla\Plugin\Captcha\ReCaptcha services src language/en-GB/plg_captcha_recaptcha.ini language/en-GB/plg_captcha_recaptcha.sys.ini
    PK!~v-captcha/recaptcha/src/Extension/ReCaptcha.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Captcha\ReCaptcha\Extension; use Joomla\CMS\Application\CMSWebApplicationInterface; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\DispatcherInterface; use Joomla\Utilities\IpHelper; use ReCaptcha\ReCaptcha as Captcha; use ReCaptcha\RequestMethod; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Recaptcha Plugin * Based on the official recaptcha library( https://packagist.org/packages/google/recaptcha ) * * @since 2.5 */ final class ReCaptcha extends CMSPlugin { /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * The http request method * * @var RequestMethod * @since 4.3.0 */ private $requestMethod; /** * Constructor. * * @param DispatcherInterface $dispatcher The dispatcher * @param array $config An optional associative array of configuration settings * @param RequestMethod $requestMethod The http request method * * @since 4.3.0 */ public function __construct(DispatcherInterface $dispatcher, array $config, RequestMethod $requestMethod) { parent::__construct($dispatcher, $config); $this->requestMethod = $requestMethod; } /** * Reports the privacy related capabilities for this plugin to site administrators. * * @return array * * @since 3.9.0 */ public function onPrivacyCollectAdminCapabilities() { return [ $this->getApplication()->getLanguage()->_('PLG_CAPTCHA_RECAPTCHA') => [ $this->getApplication()->getLanguage()->_('PLG_RECAPTCHA_PRIVACY_CAPABILITY_IP_ADDRESS'), ], ]; } /** * Initializes the captcha * * @param string $id The id of the field. * * @return Boolean True on success, false otherwise * * @since 2.5 * @throws \RuntimeException */ public function onInit($id = 'dynamic_recaptcha_1') { $app = $this->getApplication(); if (!$app instanceof CMSWebApplicationInterface) { return false; } $pubkey = $this->params->get('public_key', ''); if ($pubkey === '') { throw new \RuntimeException($app->getLanguage()->_('PLG_RECAPTCHA_ERROR_NO_PUBLIC_KEY')); } $apiSrc = 'https://www.google.com/recaptcha/api.js?onload=JoomlainitReCaptcha2&render=explicit&hl=' . $app->getLanguage()->getTag(); // Load assets, the callback should be first $app->getDocument()->getWebAssetManager() ->registerAndUseScript('plg_captcha_recaptcha', 'plg_captcha_recaptcha/recaptcha.min.js', [], ['defer' => true]) ->registerAndUseScript('plg_captcha_recaptcha.api', $apiSrc, [], ['defer' => true], ['plg_captcha_recaptcha']); return true; } /** * Gets the challenge HTML * * @param string $name The name of the field. Not Used. * @param string $id The id of the field. * @param string $class The class of the field. * * @return string The HTML to be embedded in the form. * * @since 2.5 */ public function onDisplay($name = null, $id = 'dynamic_recaptcha_1', $class = '') { $dom = new \DOMDocument('1.0', 'UTF-8'); $ele = $dom->createElement('div'); $ele->setAttribute('id', $id); $ele->setAttribute('class', ((trim($class) == '') ? 'g-recaptcha' : ($class . ' g-recaptcha'))); $ele->setAttribute('data-sitekey', $this->params->get('public_key', '')); $ele->setAttribute('data-theme', $this->params->get('theme2', 'light')); $ele->setAttribute('data-size', $this->params->get('size', 'normal')); $ele->setAttribute('data-tabindex', $this->params->get('tabindex', '0')); $ele->setAttribute('data-callback', $this->params->get('callback', '')); $ele->setAttribute('data-expired-callback', $this->params->get('expired_callback', '')); $ele->setAttribute('data-error-callback', $this->params->get('error_callback', '')); $dom->appendChild($ele); return $dom->saveHTML($ele); } /** * Calls an HTTP POST function to verify if the user's guess was correct * * @param string $code Answer provided by user. Not needed for the Recaptcha implementation * * @return True if the answer is correct, false otherwise * * @since 2.5 * @throws \RuntimeException */ public function onCheckAnswer($code = null) { $input = $this->getApplication()->getInput(); $privatekey = $this->params->get('private_key'); $version = $this->params->get('version', '2.0'); $remoteip = IpHelper::getIp(); $response = null; $spam = false; switch ($version) { case '2.0': $response = $code ?: $input->get('g-recaptcha-response', '', 'string'); $spam = ($response === ''); break; } // Check for Private Key if (empty($privatekey)) { throw new \RuntimeException($this->getApplication()->getLanguage()->_('PLG_RECAPTCHA_ERROR_NO_PRIVATE_KEY'), 500); } // Check for IP if (empty($remoteip)) { throw new \RuntimeException($this->getApplication()->getLanguage()->_('PLG_RECAPTCHA_ERROR_NO_IP'), 500); } // Discard spam submissions if ($spam) { throw new \RuntimeException($this->getApplication()->getLanguage()->_('PLG_RECAPTCHA_ERROR_EMPTY_SOLUTION'), 500); } return $this->getResponse($privatekey, $remoteip, $response); } /** * Get the reCaptcha response. * * @param string $privatekey The private key for authentication. * @param string $remoteip The remote IP of the visitor. * @param string $response The response received from Google. * * @return bool True if response is good | False if response is bad. * * @since 3.4 * @throws \RuntimeException */ private function getResponse(string $privatekey, string $remoteip, string $response) { $version = $this->params->get('version', '2.0'); switch ($version) { case '2.0': $apiResponse = (new Captcha($privatekey, $this->requestMethod))->verify($response, $remoteip); if (!$apiResponse->isSuccess()) { foreach ($apiResponse->getErrorCodes() as $error) { throw new \RuntimeException($error, 403); } return false; } break; } return true; } } PK!sپޜ"user/profile/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\User\Profile\Extension\Profile; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Profile( $dispatcher, (array) PluginHelper::getPlugin('user', 'profile') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!O$$user/profile/profile.xmlnu[ plg_user_profile Joomla! Project 2008-01 (C) 2008 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_USER_PROFILE_XML_DESCRIPTION Joomla\Plugin\User\Profile forms services src language/en-GB/plg_user_profile.ini language/en-GB/plg_user_profile.sys.ini
    PK!{+AAuser/profile/forms/profile.xmlnu[
    PK!/99&user/profile/src/Extension/Profile.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\User\Profile\Extension; use Exception; use Joomla\CMS\Date\Date; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormHelper; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\String\PunycodeHelper; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * An example custom profile plugin. * * @since 1.6 */ final class Profile extends CMSPlugin { use DatabaseAwareTrait; /** * Load the language file on instantiation. * * @var boolean * * @since 3.1 */ protected $autoloadLanguage = true; /** * Date of birth. * * @var string * * @since 3.1 */ private $date = ''; /** * Runs on content preparation * * @param string $context The context for the data * @param object $data An object containing the data for the form. * * @return boolean * * @since 1.6 */ public function onContentPrepareData($context, $data) { // Check we are manipulating a valid form. if (!in_array($context, ['com_users.profile', 'com_users.user', 'com_users.registration'])) { return true; } if (is_object($data)) { $userId = $data->id ?? 0; if (!isset($data->profile) && $userId > 0) { // Load the profile data from the database. $db = $this->getDatabase(); $query = $db->getQuery(true) ->select( [ $db->quoteName('profile_key'), $db->quoteName('profile_value'), ] ) ->from($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userid') ->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('profile.%')) ->order($db->quoteName('ordering')) ->bind(':userid', $userId, ParameterType::INTEGER); $db->setQuery($query); $results = $db->loadRowList(); // Merge the profile data. $data->profile = []; foreach ($results as $v) { $k = str_replace('profile.', '', $v[0]); $data->profile[$k] = json_decode($v[1], true); if ($data->profile[$k] === null) { $data->profile[$k] = $v[1]; } } } if (!HTMLHelper::isRegistered('users.url')) { HTMLHelper::register('users.url', [__CLASS__, 'url']); } if (!HTMLHelper::isRegistered('users.calendar')) { HTMLHelper::register('users.calendar', [__CLASS__, 'calendar']); } if (!HTMLHelper::isRegistered('users.tos')) { HTMLHelper::register('users.tos', [__CLASS__, 'tos']); } if (!HTMLHelper::isRegistered('users.dob')) { HTMLHelper::register('users.dob', [__CLASS__, 'dob']); } } return true; } /** * Returns an anchor tag generated from a given value * * @param string $value URL to use * * @return mixed|string */ public static function url($value) { if (empty($value)) { return HTMLHelper::_('users.value', $value); } else { // Convert website URL to utf8 for display $value = PunycodeHelper::urlToUTF8(htmlspecialchars($value)); if (strpos($value, 'http') === 0) { return '' . $value . ''; } else { return '' . $value . ''; } } } /** * Returns html markup showing a date picker * * @param string $value valid date string * * @return mixed */ public static function calendar($value) { if (empty($value)) { return HTMLHelper::_('users.value', $value); } else { return HTMLHelper::_('date', $value, null, null); } } /** * Returns the date of birth formatted and calculated using server timezone. * * @param string $value valid date string * * @return mixed */ public static function dob($value) { if (!$value) { return ''; } return HTMLHelper::_('date', $value, Text::_('DATE_FORMAT_LC1'), false); } /** * Return the translated strings yes or no depending on the value * * @param boolean $value input value * * @return string */ public static function tos($value) { if ($value) { return Text::_('JYES'); } else { return Text::_('JNO'); } } /** * Adds additional fields to the user editing form * * @param Form $form The form to be altered. * @param mixed $data The associated data for the form. * * @return boolean * * @since 1.6 */ public function onContentPrepareForm(Form $form, $data) { // Check we are manipulating a valid form. $name = $form->getName(); if (!in_array($name, ['com_users.user', 'com_users.profile', 'com_users.registration'])) { return true; } // Add the registration fields to the form. FormHelper::addFieldPrefix('Joomla\\Plugin\\User\\Profile\\Field'); FormHelper::addFormPath(JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/forms'); $form->loadFile('profile'); $fields = [ 'address1', 'address2', 'city', 'region', 'country', 'postal_code', 'phone', 'website', 'favoritebook', 'aboutme', 'dob', 'tos', ]; $tosArticle = $this->params->get('register_tos_article'); $tosEnabled = $this->params->get('register-require_tos', 0); // We need to be in the registration form and field needs to be enabled if ($name !== 'com_users.registration' || !$tosEnabled) { // We only want the TOS in the registration form $form->removeField('tos', 'profile'); } else { // Push the TOS article ID into the TOS field. $form->setFieldAttribute('tos', 'article', $tosArticle, 'profile'); } foreach ($fields as $field) { // Case using the users manager in admin if ($name === 'com_users.user') { // Toggle whether the field is required. if ($this->params->get('profile-require_' . $field, 1) > 0) { $form->setFieldAttribute($field, 'required', ($this->params->get('profile-require_' . $field) == 2) ? 'required' : '', 'profile'); } elseif ( // Remove the field if it is disabled in registration and profile $this->params->get('register-require_' . $field, 1) == 0 && $this->params->get('profile-require_' . $field, 1) == 0 ) { $form->removeField($field, 'profile'); } } elseif ($name === 'com_users.registration') { // Case registration // Toggle whether the field is required. if ($this->params->get('register-require_' . $field, 1) > 0) { $form->setFieldAttribute($field, 'required', ($this->params->get('register-require_' . $field) == 2) ? 'required' : '', 'profile'); } else { $form->removeField($field, 'profile'); } } elseif ($name === 'com_users.profile') { // Case profile in site or admin // Toggle whether the field is required. if ($this->params->get('profile-require_' . $field, 1) > 0) { $form->setFieldAttribute($field, 'required', ($this->params->get('profile-require_' . $field) == 2) ? 'required' : '', 'profile'); } else { $form->removeField($field, 'profile'); } } } // Drop the profile form entirely if there aren't any fields to display. $remainingfields = $form->getGroup('profile'); if (!count($remainingfields)) { $form->removeGroup('profile'); } return true; } /** * Method is called before user data is stored in the database * * @param array $user Holds the old user data. * @param boolean $isnew True if a new user is stored. * @param array $data Holds the new user data. * * @return boolean * * @since 3.1 * @throws \InvalidArgumentException on invalid date. */ public function onUserBeforeSave($user, $isnew, $data) { // Check that the date is valid. if (!empty($data['profile']['dob'])) { try { $date = new Date($data['profile']['dob']); $this->date = $date->format('Y-m-d H:i:s'); } catch (\Exception $e) { // Throw an exception if date is not valid. throw new \InvalidArgumentException($this->getApplication()->getLanguage()->_('PLG_USER_PROFILE_ERROR_INVALID_DOB')); } if (Date::getInstance('now') < $date) { // Throw an exception if dob is greater than now. throw new \InvalidArgumentException($this->getApplication()->getLanguage()->_('PLG_USER_PROFILE_ERROR_INVALID_DOB_FUTURE_DATE')); } } // Check that the tos is checked if required ie only in registration from frontend. $task = $this->getApplication()->getInput()->getCmd('task'); $option = $this->getApplication()->getInput()->getCmd('option'); $tosEnabled = ($this->params->get('register-require_tos', 0) == 2); // Check that the tos is checked. if ($task === 'register' && $tosEnabled && $option === 'com_users' && !$data['profile']['tos']) { throw new \InvalidArgumentException($this->getApplication()->getLanguage()->_('PLG_USER_PROFILE_FIELD_TOS_DESC_SITE')); } return true; } /** * Saves user profile data * * @param array $data entered user data * @param boolean $isNew true if this is a new user * @param boolean $result true if saving the user worked * @param string $error error message * * @return void */ public function onUserAfterSave($data, $isNew, $result, $error): void { $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); if ($userId && $result && isset($data['profile']) && count($data['profile'])) { $db = $this->getDatabase(); // Sanitize the date if (!empty($data['profile']['dob'])) { $data['profile']['dob'] = $this->date; } $keys = array_keys($data['profile']); foreach ($keys as &$key) { $key = 'profile.' . $key; } $query = $db->getQuery(true) ->delete($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userid') ->whereIn($db->quoteName('profile_key'), $keys, ParameterType::STRING) ->bind(':userid', $userId, ParameterType::INTEGER); $db->setQuery($query); $db->execute(); $query->clear() ->select($db->quoteName('ordering')) ->from($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userid') ->bind(':userid', $userId, ParameterType::INTEGER); $db->setQuery($query); $usedOrdering = $db->loadColumn(); $order = 1; $query->clear() ->insert($db->quoteName('#__user_profiles')); foreach ($data['profile'] as $k => $v) { while (in_array($order, $usedOrdering)) { $order++; } $query->values( implode( ',', $query->bindArray( [ $userId, 'profile.' . $k, json_encode($v), $order++, ], [ ParameterType::INTEGER, ParameterType::STRING, ParameterType::STRING, ParameterType::INTEGER, ] ) ) ); } $db->setQuery($query); $db->execute(); } } /** * Remove all user profile information for the given user ID * * Method is called after user data is deleted from the database * * @param array $user Holds the user data * @param boolean $success True if user was successfully stored in the database * @param string $msg Message * * @return void */ public function onUserAfterDelete($user, $success, $msg): void { if (!$success) { return; } $userId = ArrayHelper::getValue($user, 'id', 0, 'int'); if ($userId) { $db = $this->getDatabase(); $query = $db->getQuery(true) ->delete($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userid') ->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('profile.%')) ->bind(':userid', $userId, ParameterType::INTEGER); $db->setQuery($query); $db->execute(); } } } PK!䟠L#user/profile/src/Field/TosField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\User\Profile\Field; use Joomla\CMS\Factory; use Joomla\CMS\Form\Field\RadioField; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Associations; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\Component\Content\Site\Helper\RouteHelper; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Provides input for TOS * * @since 2.5.5 */ class TosField extends RadioField { /** * The form field type. * * @var string * @since 2.5.5 */ protected $type = 'Tos'; /** * Method to get the field label markup. * * @return string The field label markup. * * @since 2.5.5 */ protected function getLabel() { $label = ''; if ($this->hidden) { return $label; } // Get the label text from the XML element, defaulting to the element name. $text = $this->element['label'] ? (string) $this->element['label'] : (string) $this->element['name']; $text = $this->translateLabel ? Text::_($text) : $text; // Set required to true as this field is not displayed at all if not required. $this->required = true; // Build the class for the label. $class = !empty($this->description) ? 'hasPopover' : ''; $class = $class . ' required'; $class = !empty($this->labelClass) ? $class . ' ' . $this->labelClass : $class; // Add the opening label tag and main attributes attributes. $label .= ''; return $label; } } PK!SiTGG)user/contactcreator/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\User\ContactCreator\Extension\ContactCreator; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new ContactCreator( $dispatcher, (array) PluginHelper::getPlugin('user', 'contactcreator') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!\`;;&user/contactcreator/contactcreator.xmlnu[ plg_user_contactcreator Joomla! Project 2009-08 (C) 2009 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_CONTACTCREATOR_XML_DESCRIPTION Joomla\Plugin\User\ContactCreator services src language/en-GB/plg_user_contactcreator.ini language/en-GB/plg_user_contactcreator.sys.ini
    PK!I<4user/contactcreator/src/Extension/ContactCreator.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\User\ContactCreator\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\Contact\Administrator\Table\ContactTable; use Joomla\String\StringHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Class for Contact Creator * * A tool to automatically create and synchronise contacts with a user * * @since 1.6 */ final class ContactCreator extends CMSPlugin { /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * Utility method to act on a user after it has been saved. * * This method creates a contact for the saved user * * @param array $user Holds the new user data. * @param boolean $isnew True if a new user is stored. * @param boolean $success True if user was successfully stored in the database. * @param string $msg Message. * * @return void * * @since 1.6 */ public function onUserAfterSave($user, $isnew, $success, $msg): void { // If the user wasn't stored we don't resync if (!$success) { return; } // If the user isn't new we don't sync if (!$isnew) { return; } // Ensure the user id is really an int $user_id = (int) $user['id']; // If the user id appears invalid then bail out just in case if (empty($user_id)) { return; } $categoryId = $this->params->get('category', 0); if (empty($categoryId)) { $this->getApplication()->enqueueMessage($this->getApplication()->getLanguage()->_('PLG_CONTACTCREATOR_ERR_NO_CATEGORY'), 'error'); return; } if ($contact = $this->getContactTable()) { /** * Try to pre-load a contact for this user. Apparently only possible if other plugin creates it * Note: $user_id is cleaned above */ if (!$contact->load(['user_id' => (int) $user_id])) { $contact->published = $this->params->get('autopublish', 0); } $contact->name = $user['name']; $contact->user_id = $user_id; $contact->email_to = $user['email']; $contact->catid = $categoryId; $contact->access = (int) $this->getApplication()->get('access'); $contact->language = '*'; $contact->generateAlias(); // Check if the contact already exists to generate new name & alias if required if ($contact->id == 0) { list($name, $alias) = $this->generateAliasAndName($contact->alias, $contact->name, $categoryId); $contact->name = $name; $contact->alias = $alias; } $autowebpage = $this->params->get('autowebpage', ''); if (!empty($autowebpage)) { // Search terms $search_array = ['[name]', '[username]', '[userid]', '[email]']; // Replacement terms, urlencoded $replace_array = array_map('urlencode', [$user['name'], $user['username'], $user['id'], $user['email']]); // Now replace it in together $contact->webpage = str_replace($search_array, $replace_array, $autowebpage); } if ($contact->check() && $contact->store()) { return; } } $this->getApplication()->enqueueMessage($this->getApplication()->getLanguage()->_('PLG_CONTACTCREATOR_ERR_FAILED_CREATING_CONTACT'), 'error'); } /** * Method to change the name & alias if alias is already in use * * @param string $alias The alias. * @param string $name The name. * @param integer $categoryId Category identifier * * @return array Contains the modified title and alias. * * @since 3.2.3 */ private function generateAliasAndName($alias, $name, $categoryId) { $table = $this->getContactTable(); while ($table->load(['alias' => $alias, 'catid' => $categoryId])) { if ($name === $table->name) { $name = StringHelper::increment($name); } $alias = StringHelper::increment($alias, 'dash'); } return [$name, $alias]; } /** * Get an instance of the contact table * * @return ContactTable|null * * @since 3.2.3 */ private function getContactTable() { return $this->getApplication()->bootComponent('com_contact')->getMVCFactory()->createTable('Contact', 'Administrator'); } } PK!S_ user/token/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\User\Token\Extension\Token; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Token( $dispatcher, (array) PluginHelper::getPlugin('user', 'token') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!1&auser/token/forms/token.xmlnu[
    PK!♲KK"user/token/src/Extension/Token.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\User\Token\Extension; use Joomla\CMS\Crypt\Crypt; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * An example custom terms and conditions plugin. * * @since 3.9.0 */ final class Token extends CMSPlugin { use DatabaseAwareTrait; /** * Load the language file on instantiation. * * @var boolean * @since 4.0.0 */ protected $autoloadLanguage = true; /** * Joomla XML form contexts where we should inject our token management user interface. * * @var array * @since 4.0.0 */ private $allowedContexts = [ 'com_users.profile', 'com_users.user', ]; /** * The prefix of the user profile keys, without the dot. * * @var string * @since 4.0.0 */ private $profileKeyPrefix = 'joomlatoken'; /** * Token length, in bytes. * * @var integer * @since 4.0.0 */ private $tokenLength = 32; /** * Inject the Joomla token management panel's data into the User Profile. * * This method is called whenever Joomla is preparing the data for an XML form for display. * * @param string $context Form context, passed by Joomla * @param mixed $data Form data * * @return boolean * @since 4.0.0 */ public function onContentPrepareData(string $context, &$data): bool { // Only do something if the api-authentication plugin with the same name is published if (!PluginHelper::isEnabled('api-authentication', $this->_name)) { return true; } // Check we are manipulating a valid form. if (!in_array($context, $this->allowedContexts)) { return true; } // $data must be an object if (!is_object($data)) { return true; } // We expect the numeric user ID in $data->id if (!isset($data->id)) { return true; } // Get the user ID $userId = intval($data->id); // Make sure we have a positive integer user ID if ($userId <= 0) { return true; } if (!$this->isInAllowedUserGroup($userId)) { return true; } $data->{$this->profileKeyPrefix} = []; // Load the profile data from the database. try { $db = $this->getDatabase(); $query = $db->getQuery(true) ->select([ $db->quoteName('profile_key'), $db->quoteName('profile_value'), ]) ->from($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userId') ->where($db->quoteName('profile_key') . ' LIKE :profileKey') ->order($db->quoteName('ordering')); $profileKey = $this->profileKeyPrefix . '.%'; $query->bind(':userId', $userId, ParameterType::INTEGER); $query->bind(':profileKey', $profileKey, ParameterType::STRING); $results = $db->setQuery($query)->loadRowList(); foreach ($results as $v) { $k = str_replace($this->profileKeyPrefix . '.', '', $v[0]); $data->{$this->profileKeyPrefix}[$k] = $v[1]; } } catch (\Exception $e) { // We suppress any database error. It means we get no token saved by default. } /** * Modify the data for display in the user profile view page in the frontend. * * It's important to note that we deliberately not register HTMLHelper methods to do the * same (unlike e.g. the actionlogs system plugin) because the names of our fields are too * generic and we run the risk of creating naming clashes. Instead, we manipulate the data * directly. */ if (($context === 'com_users.profile') && ($this->getApplication()->getInput()->get('layout') !== 'edit')) { $pluginData = $data->{$this->profileKeyPrefix} ?? []; $enabled = $pluginData['enabled'] ?? false; $token = $pluginData['token'] ?? ''; $pluginData['enabled'] = $this->getApplication()->getLanguage()->_('JDISABLED'); $pluginData['token'] = ''; if ($enabled) { $algo = $this->getAlgorithmFromFormFile(); $pluginData['enabled'] = $this->getApplication()->getLanguage()->_('JENABLED'); $pluginData['token'] = $this->getTokenForDisplay($userId, $token, $algo); } $data->{$this->profileKeyPrefix} = $pluginData; } return true; } /** * Runs whenever Joomla is preparing a form object. * * @param Form $form The form to be altered. * @param mixed $data The associated data for the form. * * @return boolean * * @throws \Exception When $form is not a valid form object * @since 4.0.0 */ public function onContentPrepareForm(Form $form, $data): bool { // Only do something if the api-authentication plugin with the same name is published if (!PluginHelper::isEnabled('api-authentication', $this->_name)) { return true; } // Check we are manipulating a valid form. if (!in_array($form->getName(), $this->allowedContexts)) { return true; } // If we are on the save command, no data is passed to $data variable, we need to get it directly from request $jformData = $this->getApplication()->getInput()->get('jform', [], 'array'); if ($jformData && !$data) { $data = $jformData; } if (is_array($data)) { $data = (object) $data; } // Check if the user belongs to an allowed user group $userId = (is_object($data) && isset($data->id)) ? $data->id : 0; if (!empty($userId) && !$this->isInAllowedUserGroup($userId)) { return true; } // Add the registration fields to the form. Form::addFormPath(JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/forms'); $form->loadFile('token', false); // No token: no reset $userTokenSeed = $this->getTokenSeedForUser($userId); $currentUser = Factory::getUser(); if (empty($userTokenSeed)) { $form->removeField('notokenforotherpeople', 'joomlatoken'); $form->removeField('reset', 'joomlatoken'); $form->removeField('token', 'joomlatoken'); $form->removeField('enabled', 'joomlatoken'); } else { $form->removeField('saveme', 'joomlatoken'); } if ($userId != $currentUser->id) { $form->removeField('token', 'joomlatoken'); } else { $form->removeField('notokenforotherpeople', 'joomlatoken'); } if (($userId != $currentUser->id) && empty($userTokenSeed)) { $form->removeField('saveme', 'joomlatoken'); } else { $form->removeField('savemeforotherpeople', 'joomlatoken'); } // Remove the Reset field when displaying the user profile form if (($form->getName() === 'com_users.profile') && ($this->getApplication()->getInput()->get('layout') !== 'edit')) { $form->removeField('reset', 'joomlatoken'); } return true; } /** * Save the Joomla token in the user profile field * * @param mixed $data The incoming form data * @param bool $isNew Is this a new user? * @param bool $result Has Joomla successfully saved the user? * @param string $error Error string * * @return void * @since 4.0.0 */ public function onUserAfterSave($data, bool $isNew, bool $result, ?string $error): void { if (!is_array($data)) { return; } $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); if ($userId <= 0) { return; } if (!$result) { return; } $noToken = false; // No Joomla token data. Set the $noToken flag which results in a new token being generated. if (!isset($data[$this->profileKeyPrefix])) { /** * Is the user being saved programmatically, without passing the user profile * information? In this case I do not want to accidentally try to generate a new token! * * We determine that by examining whether the Joomla token field exists. If it does but * it wasn't passed when saving the user I know it's a programmatic user save and I have * to ignore it. */ if ($this->hasTokenProfileFields($userId)) { return; } $noToken = true; $data[$this->profileKeyPrefix] = []; } if (isset($data[$this->profileKeyPrefix]['reset'])) { $reset = $data[$this->profileKeyPrefix]['reset'] == 1; unset($data[$this->profileKeyPrefix]['reset']); if ($reset) { $noToken = true; } } // We may have a token already saved. Let's check, shall we? if (!$noToken) { $noToken = true; $existingToken = $this->getTokenSeedForUser($userId); if (!empty($existingToken)) { $noToken = false; $data[$this->profileKeyPrefix]['token'] = $existingToken; } } // If there is no token or this is a new user generate a new token. if ($noToken || $isNew) { if ( isset($data[$this->profileKeyPrefix]['token']) && empty($data[$this->profileKeyPrefix]['token']) ) { unset($data[$this->profileKeyPrefix]['token']); } $default = $this->getDefaultProfileFieldValues(); $data[$this->profileKeyPrefix] = array_merge($default, $data[$this->profileKeyPrefix]); } // Remove existing Joomla Token user profile values $db = $this->getDatabase(); $query = $db->getQuery(true) ->delete($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userId') ->where($db->quoteName('profile_key') . ' LIKE :profileKey'); $profileKey = $this->profileKeyPrefix . '.%'; $query->bind(':userId', $userId, ParameterType::INTEGER); $query->bind(':profileKey', $profileKey, ParameterType::STRING); $db->setQuery($query)->execute(); // If the user is not in the allowed user group don't save any new token information. if (!$this->isInAllowedUserGroup($data['id'])) { return; } // Save the new Joomla Token user profile values $order = 1; $query = $db->getQuery(true) ->insert($db->quoteName('#__user_profiles')) ->columns([ $db->quoteName('user_id'), $db->quoteName('profile_key'), $db->quoteName('profile_value'), $db->quoteName('ordering'), ]); foreach ($data[$this->profileKeyPrefix] as $k => $v) { $query->values($userId . ', ' . $db->quote($this->profileKeyPrefix . '.' . $k) . ', ' . $db->quote($v) . ', ' . ($order++)); } $db->setQuery($query)->execute(); } /** * Remove the Joomla token when the user account is deleted from the database. * * This event is called after the user data is deleted from the database. * * @param array $user Holds the user data * @param boolean $success True if user was successfully stored in the database * @param string $msg Message * * @return void * * @throws \Exception * @since 4.0.0 */ public function onUserAfterDelete(array $user, bool $success, string $msg): void { if (!$success) { return; } $userId = ArrayHelper::getValue($user, 'id', 0, 'int'); if ($userId <= 0) { return; } try { $db = $this->getDatabase(); $query = $db->getQuery(true) ->delete($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userId') ->where($db->quoteName('profile_key') . ' LIKE :profileKey'); $profileKey = $this->profileKeyPrefix . '.%'; $query->bind(':userId', $userId, ParameterType::INTEGER); $query->bind(':profileKey', $profileKey, ParameterType::STRING); $db->setQuery($query)->execute(); } catch (\Exception $e) { // Do nothing. } } /** * Returns an array with the default profile field values. * * This is used when saving the form data of a user (new or existing) without a token already * set. * * @return array * @since 4.0.0 */ private function getDefaultProfileFieldValues(): array { return [ 'token' => base64_encode(Crypt::genRandomBytes($this->tokenLength)), 'enabled' => true, ]; } /** * Retrieve the token seed string for the given user ID. * * @param int $userId The numeric user ID to return the token seed string for. * * @return string|null Null if there is no token configured or the user doesn't exist. * @since 4.0.0 */ private function getTokenSeedForUser(int $userId): ?string { try { $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName('profile_value')) ->from($db->quoteName('#__user_profiles')) ->where($db->quoteName('profile_key') . ' = :profileKey') ->where($db->quoteName('user_id') . ' = :userId'); $profileKey = $this->profileKeyPrefix . '.token'; $query->bind(':profileKey', $profileKey, ParameterType::STRING); $query->bind(':userId', $userId, ParameterType::INTEGER); return $db->setQuery($query)->loadResult(); } catch (\Exception $e) { return null; } } /** * Get the configured user groups which are allowed to have access to tokens. * * @return int[] * @since 4.0.0 */ private function getAllowedUserGroups(): array { $userGroups = $this->params->get('allowedUserGroups', [8]); if (empty($userGroups)) { return []; } if (!is_array($userGroups)) { $userGroups = [$userGroups]; } return $userGroups; } /** * Is the user with the given ID in the allowed User Groups with access to tokens? * * @param int $userId The user ID to check * * @return boolean False when doesn't belong to allowed user groups, user not found, or guest * @since 4.0.0 */ private function isInAllowedUserGroup($userId) { $allowedUserGroups = $this->getAllowedUserGroups(); $user = Factory::getUser($userId); if ($user->id != $userId) { return false; } if ($user->guest) { return false; } // No specifically allowed user groups: allow ALL user groups. if (empty($allowedUserGroups)) { return true; } $groups = $user->getAuthorisedGroups(); $intersection = array_intersect($groups, $allowedUserGroups); return !empty($intersection); } /** * Returns the token formatted suitably for the user to copy. * * @param integer $userId The user id for token * @param string $tokenSeed The token seed data stored in the database * @param string $algorithm The hashing algorithm to use for the token (default: sha256) * * @return string * @since 4.0.0 */ private function getTokenForDisplay( int $userId, string $tokenSeed, string $algorithm = 'sha256' ): string { if (empty($tokenSeed)) { return ''; } try { $siteSecret = $this->getApplication()->get('secret'); } catch (\Exception $e) { $siteSecret = ''; } // NO site secret? You monster! if (empty($siteSecret)) { return ''; } $rawToken = base64_decode($tokenSeed); $tokenHash = hash_hmac($algorithm, $rawToken, $siteSecret); $message = base64_encode("$algorithm:$userId:$tokenHash"); if ($userId !== $this->getApplication()->getIdentity()->id) { $message = ''; } return $message; } /** * Get the token algorithm as defined in the form file * * We use a simple RegEx match instead of loading the form for better performance. * * @return string The configured algorithm, 'sha256' as a fallback if none is found. */ private function getAlgorithmFromFormFile(): string { $algo = 'sha256'; $file = JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/forms/token.xml'; $contents = @file_get_contents($file); if ($contents === false) { return $algo; } if (preg_match('/\s*algo=\s*"\s*([a-z0-9]+)\s*"/i', $contents, $matches) !== 1) { return $algo; } return $matches[1]; } /** * Does the user have the Joomla Token profile fields? * * @param int|null $userId The user we're interested in * * @return bool True if the user has Joomla Token profile fields */ private function hasTokenProfileFields(?int $userId): bool { if (is_null($userId) || ($userId <= 0)) { return false; } $db = $this->getDatabase(); $q = $db->getQuery(true) ->select('COUNT(*)') ->from($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = ' . $userId) ->where($db->quoteName('profile_key') . ' = ' . $db->quote($this->profileKeyPrefix . '.token')); try { $numRows = $db->setQuery($q)->loadResult() ?? 0; } catch (\Exception $e) { return false; } return $numRows > 0; } } PK!ҠOO)user/token/src/Field/JoomlatokenField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\User\Token\Field; use Joomla\CMS\Factory; use Joomla\CMS\Form\Field\TextField; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomlatoken field class * * @since 4.0.0 */ class JoomlatokenField extends TextField { /** * Name of the layout being used to render the field * * @var string * @since 4.0.0 */ protected $layout = 'plugins.user.token.token'; /** * Method to attach a Form object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` * tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an * array container for the field. For example if the * field has name="foo" and the group value is set to * "bar" then the full field name would end up being * "bar[foo]". * * @return boolean True on success. * * @see FormField::setup() * @since 4.0.0 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $ret = parent::setup($element, $value, $group); /** * Security and privacy precaution: do not display the token field when the user being * edited is not the same as the logged in user. Tokens are conceptually a combination of * a username and password, therefore they should be treated in the same mode of * confidentiality and privacy as passwords i.e. you can reset them for other users but NOT * be able to see them, thus preventing impersonation attacks by a malicious administrator. */ $userId = $this->form->getData()->get('id'); if ($userId != Factory::getUser()->id) { $this->hidden = true; } return $ret; } /** * Method to get the field input markup. * * @return string The field input markup. * * @since 4.0.0 */ protected function getInput() { // Do not display the token field when the user being edited is not the same as the logged in user if ($this->hidden) { return ''; } return parent::getInput(); } /** * Returns the token formatted suitably for the user to copy. * * @param string $tokenSeed The token seed data stored in the database * * @return string * @since 4.0.0 */ private function getTokenForDisplay(string $tokenSeed): string { if (empty($tokenSeed)) { return ''; } $algorithm = $this->getAttribute('algo', 'sha256'); try { $siteSecret = Factory::getApplication()->get('secret'); } catch (\Exception $e) { $siteSecret = ''; } // NO site secret? You monster! if (empty($siteSecret)) { return ''; } $rawToken = base64_decode($tokenSeed); $tokenHash = hash_hmac($algorithm, $rawToken, $siteSecret); $userId = $this->form->getData()->get('id'); $message = base64_encode("$algorithm:$userId:$tokenHash"); if ($userId != Factory::getUser()->id) { $message = ''; } return $message; } /** * Get the data for the layout * * @return array * * @since 4.0.0 */ protected function getLayoutData() { $data = parent::getLayoutData(); $data['value'] = $this->getTokenForDisplay($this->value); return $data; } } PK!}R))user/token/token.xmlnu[ plg_user_token Joomla! Project 2019-11 (C) 2020 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_USER_TOKEN_XML_DESCRIPTION Joomla\Plugin\User\Token forms services src language/en-GB/plg_user_token.ini language/en-GB/plg_user_token.sys.ini
    PK!a0!user/joomla/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\User\Joomla\Extension\Joomla; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Joomla( $dispatcher, (array) PluginHelper::getPlugin('user', 'joomla') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!P9user/joomla/joomla.xmlnu[ plg_user_joomla Joomla! Project 2006-12 (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_USER_JOOMLA_XML_DESCRIPTION Joomla\Plugin\User\Joomla services src language/en-GB/plg_user_joomla.ini language/en-GB/plg_user_joomla.sys.ini
    PK!lClC$user/joomla/src/Extension/Joomla.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\User\Joomla\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Language\LanguageFactoryInterface; use Joomla\CMS\Log\Log; use Joomla\CMS\Mail\MailTemplate; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\User; use Joomla\CMS\User\UserHelper; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\Exception\ExecutionFailureException; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla User plugin * * @since 1.5 */ final class Joomla extends CMSPlugin { use DatabaseAwareTrait; /** * Set as required the passwords fields when mail to user is set to No * * @param \Joomla\CMS\Form\Form $form The form to be altered. * @param mixed $data The associated data for the form. * * @return boolean * * @since 4.0.0 */ public function onContentPrepareForm($form, $data) { // Check we are manipulating a valid user form before modifying it. $name = $form->getName(); if ($name === 'com_users.user') { // In case there is a validation error (like duplicated user), $data is an empty array on save. // After returning from error, $data is an array but populated if (!$data) { $data = $this->getApplication()->getInput()->get('jform', [], 'array'); } if (is_array($data)) { $data = (object) $data; } // Passwords fields are required when mail to user is set to No if (empty($data->id) && !$this->params->get('mail_to_user', 1)) { $form->setFieldAttribute('password', 'required', 'true'); $form->setFieldAttribute('password2', 'required', 'true'); } } return true; } /** * Remove all sessions for the user name * * Method is called after user data is deleted from the database * * @param array $user Holds the user data * @param boolean $success True if user was successfully stored in the database * @param string $msg Message * * @return void * * @since 1.6 */ public function onUserAfterDelete($user, $success, $msg): void { if (!$success) { return; } $userId = (int) $user['id']; // Only execute this if the session metadata is tracked if ($this->getApplication()->get('session_metadata', true)) { UserHelper::destroyUserSessions($userId, true); } $db = $this->getDatabase(); try { $db->setQuery( $db->getQuery(true) ->delete($db->quoteName('#__messages')) ->where($db->quoteName('user_id_from') . ' = :userId') ->bind(':userId', $userId, ParameterType::INTEGER) )->execute(); } catch (ExecutionFailureException $e) { // Do nothing. } // Delete Multi-factor Authentication user profile records $profileKey = 'mfa.%'; $query = $db->getQuery(true) ->delete($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userId') ->where($db->quoteName('profile_key') . ' LIKE :profileKey') ->bind(':userId', $userId, ParameterType::INTEGER) ->bind(':profileKey', $profileKey, ParameterType::STRING); try { $db->setQuery($query)->execute(); } catch (\Exception $e) { // Do nothing } // Delete Multi-factor Authentication records $query = $db->getQuery(true) ->delete($db->quoteName('#__user_mfa')) ->where($db->quoteName('user_id') . ' = :userId') ->bind(':userId', $userId, ParameterType::INTEGER); try { $db->setQuery($query)->execute(); } catch (\Exception $e) { // Do nothing } } /** * Utility method to act on a user after it has been saved. * * This method sends a registration email to new users created in the backend. * * @param array $user Holds the new user data. * @param boolean $isnew True if a new user is stored. * @param boolean $success True if user was successfully stored in the database. * @param string $msg Message. * * @return void * * @since 1.6 */ public function onUserAfterSave($user, $isnew, $success, $msg): void { $mail_to_user = $this->params->get('mail_to_user', 1); if (!$isnew || !$mail_to_user) { return; } $app = $this->getApplication(); $language = $app->getLanguage(); $defaultLocale = $language->getTag(); // @todo: Suck in the frontend registration emails here as well. Job for a rainy day. // The method check here ensures that if running as a CLI Application we don't get any errors if (method_exists($app, 'isClient') && ($app->isClient('site') || $app->isClient('cli'))) { return; } // Check if we have a sensible from email address, if not bail out as mail would not be sent anyway if (strpos($app->get('mailfrom'), '@') === false) { $app->enqueueMessage($language->_('JERROR_SENDING_EMAIL'), 'warning'); return; } /** * Look for user language. Priority: * 1. User frontend language * 2. User backend language */ $userParams = new Registry($user['params']); $userLocale = $userParams->get('language', $userParams->get('admin_language', $defaultLocale)); // Temporarily set application language to user's language. if ($userLocale !== $defaultLocale) { Factory::$language = Factory::getContainer() ->get(LanguageFactoryInterface::class) ->createLanguage($userLocale, $app->get('debug_lang', false)); if (method_exists($app, 'loadLanguage')) { $app->loadLanguage(Factory::$language); } } // Load plugin language files. $this->loadLanguage(); // Collect data for mail $data = [ 'name' => $user['name'], 'sitename' => $app->get('sitename'), 'url' => Uri::root(), 'username' => $user['username'], 'password' => $user['password_clear'], 'email' => $user['email'], ]; $mailer = new MailTemplate('plg_user_joomla.mail', $userLocale); $mailer->addTemplateData($data); $mailer->addRecipient($user['email'], $user['name']); try { $res = $mailer->send(); } catch (\Exception $exception) { try { Log::add($language->_($exception->getMessage()), Log::WARNING, 'jerror'); $res = false; } catch (\RuntimeException $exception) { $app->enqueueMessage($language->_($exception->getMessage()), 'warning'); $res = false; } } if ($res === false) { $app->enqueueMessage($language->_('JERROR_SENDING_EMAIL'), 'warning'); } // Set application language back to default if we changed it if ($userLocale !== $defaultLocale) { Factory::$language = $language; if (method_exists($app, 'loadLanguage')) { $app->loadLanguage($language); } } } /** * This method should handle any login logic and report back to the subject * * @param array $user Holds the user data * @param array $options Array holding options (remember, autoregister, group) * * @return boolean True on success * * @since 1.5 */ public function onUserLogin($user, $options = []) { $instance = $this->getUser($user, $options); // If getUser returned an error, then pass it back. if ($instance instanceof \Exception) { return false; } // If the user is blocked, redirect with an error if ($instance->block == 1) { $this->getApplication()->enqueueMessage($this->getApplication()->getLanguage()->_('JERROR_NOLOGIN_BLOCKED'), 'warning'); return false; } // Authorise the user based on the group information if (!isset($options['group'])) { $options['group'] = 'USERS'; } // Check the user can login. $result = $instance->authorise($options['action']); if (!$result) { $this->getApplication()->enqueueMessage($this->getApplication()->getLanguage()->_('JERROR_LOGIN_DENIED'), 'warning'); return false; } // Mark the user as logged in $instance->guest = 0; // Load the logged in user to the application $this->getApplication()->loadIdentity($instance); $session = $this->getApplication()->getSession(); // Grab the current session ID $oldSessionId = $session->getId(); // Fork the session $session->fork(); // Register the needed session variables $session->set('user', $instance); // Update the user related fields for the Joomla sessions table if tracking session metadata. if ($this->getApplication()->get('session_metadata', true)) { $this->getApplication()->checkSession(); } $db = $this->getDatabase(); // Purge the old session $query = $db->getQuery(true) ->delete($db->quoteName('#__session')) ->where($db->quoteName('session_id') . ' = :sessionid') ->bind(':sessionid', $oldSessionId); try { $db->setQuery($query)->execute(); } catch (\RuntimeException $e) { // The old session is already invalidated, don't let this block logging in } // Hit the user last visit field $instance->setLastVisit(); // Add "user state" cookie used for reverse caching proxies like Varnish, Nginx etc. if ($this->getApplication()->isClient('site')) { $this->getApplication()->getInput()->cookie->set( 'joomla_user_state', 'logged_in', 0, $this->getApplication()->get('cookie_path', '/'), $this->getApplication()->get('cookie_domain', ''), $this->getApplication()->isHttpsForced(), true ); } return true; } /** * This method should handle any logout logic and report back to the subject * * @param array $user Holds the user data. * @param array $options Array holding options (client, ...). * * @return boolean True on success * * @since 1.5 */ public function onUserLogout($user, $options = []) { $my = Factory::getUser(); $session = Factory::getSession(); $userid = (int) $user['id']; // Make sure we're a valid user first if ($user['id'] === 0 && !$my->get('tmp_user')) { return true; } $sharedSessions = $this->getApplication()->get('shared_session', '0'); // Check to see if we're deleting the current session if ($my->id == $userid && ($sharedSessions || (!$sharedSessions && $options['clientid'] == $this->getApplication()->getClientId()))) { // Hit the user last visit field $my->setLastVisit(); // Destroy the php session for this user $session->destroy(); } // Enable / Disable Forcing logout all users with same userid, but only if session metadata is tracked $forceLogout = $this->params->get('forceLogout', 1) && $this->getApplication()->get('session_metadata', true); if ($forceLogout) { $clientId = $sharedSessions ? null : (int) $options['clientid']; UserHelper::destroyUserSessions($user['id'], false, $clientId); } // Delete "user state" cookie used for reverse caching proxies like Varnish, Nginx etc. if ($this->getApplication()->isClient('site')) { $this->getApplication()->getInput()->cookie->set('joomla_user_state', '', 1, $this->getApplication()->get('cookie_path', '/'), $this->getApplication()->get('cookie_domain', '')); } return true; } /** * Hooks on the Joomla! login event. Detects silent logins and disables the Multi-Factor * Authentication page in this case. * * Moreover, it will save the redirection URL and the Captive URL which is necessary in Joomla 4. You see, in Joomla * 4 having unified sessions turned on makes the backend login redirect you to the frontend of the site AFTER * logging in, something which would cause the Captive page to appear in the frontend and redirect you to the public * frontend homepage after successfully passing the Two Step verification process. * * @param array $options Passed by Joomla. user: a User object; responseType: string, authentication response type. * * @return void * @since 4.2.0 */ public function onUserAfterLogin(array $options): void { if (!($this->getApplication()->isClient('administrator')) && !($this->getApplication()->isClient('site'))) { return; } $this->disableMfaOnSilentLogin($options); } /** * Detect silent logins and disable MFA if the relevant com_users option is set. * * @param array $options The array of login options and login result * * @return void * @since 4.2.0 */ private function disableMfaOnSilentLogin(array $options): void { $userParams = ComponentHelper::getParams('com_users'); $doMfaOnSilentLogin = $userParams->get('mfaonsilent', 0) == 1; // Should I show MFA even on silent logins? Default: 1 (yes, show) if ($doMfaOnSilentLogin) { return; } // Make sure I have a valid user /** @var User $user */ $user = $options['user']; if (!is_object($user) || !($user instanceof User) || $user->guest) { return; } $silentResponseTypes = array_map( 'trim', explode(',', $userParams->get('silentresponses', '') ?: '') ); $silentResponseTypes = $silentResponseTypes ?: ['cookie', 'passwordless']; // Only proceed if this is not a silent login if (!in_array(strtolower($options['responseType'] ?? ''), $silentResponseTypes)) { return; } // Set the flag indicating that MFA is already checked. $this->getApplication()->getSession()->set('com_users.mfa_checked', 1); } /** * This method will return a user object * * If options['autoregister'] is true, if the user doesn't exist yet they will be created * * @param array $user Holds the user data. * @param array $options Array holding options (remember, autoregister, group). * * @return User * * @since 1.5 */ private function getUser($user, $options = []) { $instance = User::getInstance(); $id = (int) UserHelper::getUserId($user['username']); if ($id) { $instance->load($id); return $instance; } // @todo : move this out of the plugin $params = ComponentHelper::getParams('com_users'); // Read the default user group option from com_users $defaultUserGroup = $params->get('new_usertype', $params->get('guest_usergroup', 1)); $instance->id = 0; $instance->name = $user['fullname']; $instance->username = $user['username']; $instance->password_clear = $user['password_clear']; // Result should contain an email (check). $instance->email = $user['email']; $instance->groups = [$defaultUserGroup]; // If autoregister is set let's register the user $autoregister = $options['autoregister'] ?? $this->params->get('autoregister', 1); if ($autoregister) { if (!$instance->save()) { Log::add('Failed to automatically create account for user ' . $user['username'] . '.', Log::WARNING, 'error'); } } else { // No existing user and autoregister off, this is a temporary user. $instance->set('tmp_user', true); } return $instance; } } PK!b3Q user/terms/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\User\Terms\Extension\Terms; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Terms( $dispatcher, (array) PluginHelper::getPlugin('user', 'terms') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!㧁user/terms/forms/terms.xmlnu[
    PK!i_user/terms/terms.xmlnu[ plg_user_terms Joomla! Project 2018-06 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_USER_TERMS_XML_DESCRIPTION Joomla\Plugin\User\Terms forms services src language/en-GB/plg_user_terms.ini language/en-GB/plg_user_terms.sys.ini
    PK!1Ԙpp"user/terms/src/Extension/Terms.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\User\Terms\Extension; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\Actionlogs\Administrator\Model\ActionlogModel; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * An example custom terms and conditions plugin. * * @since 3.9.0 */ final class Terms extends CMSPlugin { /** * Load the language file on instantiation. * * @var boolean * * @since 3.9.0 */ protected $autoloadLanguage = true; /** * Adds additional fields to the user registration form * * @param Form $form The form to be altered. * @param mixed $data The associated data for the form. * * @return boolean * * @since 3.9.0 */ public function onContentPrepareForm(Form $form, $data) { // Check we are manipulating a valid form - we only display this on user registration form. $name = $form->getName(); if (!in_array($name, ['com_users.registration'])) { return true; } // Add the terms and conditions fields to the form. FormHelper::addFieldPrefix('Joomla\\Plugin\\User\\Terms\\Field'); FormHelper::addFormPath(JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/forms'); $form->loadFile('terms'); $termsarticle = $this->params->get('terms_article'); $termsnote = $this->params->get('terms_note'); // Push the terms and conditions article ID into the terms field. $form->setFieldAttribute('terms', 'article', $termsarticle, 'terms'); $form->setFieldAttribute('terms', 'note', $termsnote, 'terms'); } /** * Method is called before user data is stored in the database * * @param array $user Holds the old user data. * @param boolean $isNew True if a new user is stored. * @param array $data Holds the new user data. * * @return boolean * * @since 3.9.0 * @throws \InvalidArgumentException on missing required data. */ public function onUserBeforeSave($user, $isNew, $data) { // // Only check for front-end user registration if ($this->getApplication()->isClient('administrator')) { return true; } $userId = ArrayHelper::getValue($user, 'id', 0, 'int'); // User already registered, no need to check it further if ($userId > 0) { return true; } // Check that the terms is checked if required ie only in registration from frontend. $input = $this->getApplication()->getInput(); $option = $input->get('option'); $task = $input->post->get('task'); $form = $input->post->get('jform', [], 'array'); if ($option == 'com_users' && in_array($task, ['registration.register']) && empty($form['terms']['terms'])) { throw new \InvalidArgumentException($this->getApplication()->getLanguage()->_('PLG_USER_TERMS_FIELD_ERROR')); } return true; } /** * Saves user profile data * * @param array $data entered user data * @param boolean $isNew true if this is a new user * @param boolean $result true if saving the user worked * @param string $error error message * * @return void * * @since 3.9.0 */ public function onUserAfterSave($data, $isNew, $result, $error): void { if (!$isNew || !$result) { return; } $userId = ArrayHelper::getValue($data, 'id', 0, 'int'); $message = [ 'action' => 'consent', 'id' => $userId, 'title' => $data['name'], 'itemlink' => 'index.php?option=com_users&task=user.edit&id=' . $userId, 'userid' => $userId, 'username' => $data['username'], 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $userId, ]; /** @var ActionlogModel $model */ $model = $this->getApplication() ->bootComponent('com_actionlogs') ->getMVCFactory() ->createModel('Actionlog', 'Administrator'); $model->addLog([$message], 'PLG_USER_TERMS_LOGGING_CONSENT_TO_TERMS', 'plg_user_terms', $userId); } } PK!nn#user/terms/src/Field/TermsField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\User\Terms\Field; use Joomla\CMS\Factory; use Joomla\CMS\Form\Field\RadioField; use Joomla\CMS\Language\Associations; use Joomla\CMS\Language\Text; use Joomla\Component\Content\Site\Helper\RouteHelper; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Provides input for privacyterms * * @since 3.9.0 */ class TermsField extends RadioField { /** * The form field type. * * @var string * @since 3.9.0 */ protected $type = 'terms'; /** * Method to get the field input markup. * * @return string The field input markup. * * @since 3.9.0 */ protected function getInput() { // Display the message before the field echo $this->getRenderer('plugins.user.terms.message')->render($this->getLayoutData()); return parent::getInput(); } /** * Method to get the field label markup. * * @return string The field label markup. * * @since 3.9.0 */ protected function getLabel() { if ($this->hidden) { return ''; } return $this->getRenderer('plugins.user.terms.label')->render($this->getLayoutData()); } /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 3.9.4 */ protected function getLayoutData() { $data = parent::getLayoutData(); $article = false; $termsArticle = $this->element['article'] > 0 ? (int) $this->element['article'] : 0; if ($termsArticle && Factory::getApplication()->isClient('site')) { $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName(['id', 'alias', 'catid', 'language'])) ->from($db->quoteName('#__content')) ->where($db->quoteName('id') . ' = :id') ->bind(':id', $termsArticle, ParameterType::INTEGER); $db->setQuery($query); $article = $db->loadObject(); if (Associations::isEnabled()) { $termsAssociated = Associations::getAssociations('com_content', '#__content', 'com_content.item', $termsArticle); } $currentLang = Factory::getLanguage()->getTag(); if (isset($termsAssociated) && $currentLang !== $article->language && \array_key_exists($currentLang, $termsAssociated)) { $article->link = RouteHelper::getArticleRoute( $termsAssociated[$currentLang]->id, $termsAssociated[$currentLang]->catid, $termsAssociated[$currentLang]->language ); } else { $slug = $article->alias ? ($article->id . ':' . $article->alias) : $article->id; $article->link = RouteHelper::getArticleRoute($slug, $article->catid, $article->language); } } $extraData = [ 'termsnote' => !empty($this->element['note']) ? $this->element['note'] : Text::_('PLG_USER_TERMS_NOTE_FIELD_DEFAULT'), 'options' => $this->getOptions(), 'value' => (string) $this->value, 'translateLabel' => $this->translateLabel, 'translateDescription' => $this->translateDescription, 'translateHint' => $this->translateHint, 'termsArticle' => $termsArticle, 'article' => $article, ]; return array_merge($data, $extraData); } } PK!% W66$user/easyblogusers/easyblogusers.phpnu[exists()) { return false; } $this->app = JFactory::getApplication(); $this->input = $this->app->input; $this->config = EB::config(); } /** * Adds a new subscriber records * * @since 5.4.5 * @access public */ public function addSubscriber($userId, $email, $name = '') { $model = EB::model('Subscription'); $exists = $model->isSiteSubscribedUser($userId , $email); if ($exists) { $model->updateSiteSubscriptionEmail($exists, $userId, $email); return true; } $model->addSiteSubscription($email, $userId, $name); return true; } /** * Tests if EasyBlog exists * * @since 4.0 * @access public */ private function exists() { static $exists = null; if (is_null($exists)) { $file = JPATH_ADMINISTRATOR . '/components/com_easyblog/includes/easyblog.php'; $exists = JFile::exists($file); if (!$exists) { return false; } require_once($file); if (!EB::isFoundryEnabled()) { $exists = false; } } return $exists; } /** * Triggered when saving a user in Joomla * * @since 4.0 * @access public */ public function onUserAfterSave($data, $isNew, $result, $error) { if (!$this->exists()) { return false; } //j.16 $this->updateSubscriptions($data); $userId = EBArrayHelper::getValue($data, 'id', 0, 'int'); // Ensure that there is a record created for the author in the seo section if ($userId && $isNew) { // Ensure that the user has authoring rights $acl = EB::acl($userId); if ($acl->get('add_entry')) { $model = EB::model('Metas'); $model->createMeta($userId, META_TYPE_BLOGGER); // We should show the user into the author listing page immediately // If the new user has add_entry acl #1986 $table = EB::table('Profile'); $table->createDefault($userId); } if ($this->config->get('notification_autosubscribe')) { $this->addSubscriber($userId, $data['email'], $data['name']); } } // Process user subscription if ($userId && $result && isset($data['easyblogusers']) && (count($data['easyblogusers']))) { if (!empty($data['easyblogusers']['subscribe']) && $data['easyblogusers']['subscribe'] == '1') { $this->addSubscriber($userId, $data['email'], $data['name']); } } } /** * Update user subscription * * @since 5.1 * @access public */ public function updateSubscriptions($user) { $db = EB::db(); if (is_object($user)) { $user = get_object_vars($user); } if (!isset($user['id']) && empty($user['id'])) { return; } //update subscription tables. $userId = $user['id']; $userFullname = $user['name']; $userEmail = $user['email']; // user subscriptions $query = 'UPDATE `#__easyblog_subscriptions` SET'; $query .= ' `user_id` = ' . $db->Quote($userId); $query .= ', `fullname` = ' . $db->Quote($userFullname); $query .= ' WHERE `email` = ' . $db->Quote($userEmail); $query .= ' AND `user_id` = ' . $db->Quote('0'); $db->setQuery($query); $db->query(); } /** * Invoked before deleting a user * * @since 4.0 * @access public */ public function onUserBeforeDelete($user) { if (! $this->exists()) { return false; } if (is_object($user)) { $user = get_object_vars($user); } $userId = $user['id']; $newOwnerShip = $this->_getnewOwnerShip($userId); // Perform all necessary actions $this->ownerTransferCategory($userId, $newOwnerShip); $this->ownerTransferTag($userId, $newOwnerShip); $this->onwerTransferComment($userId, $newOwnerShip); $this->ownerTransferPost($userId, $newOwnerShip); $this->removeAssignedACLGroup($userId); $this->removeAdsenseSetting($userId); $this->removeFeedburnerSetting($userId); $this->removeOAuthSetting($userId); $this->removeFeaturedBlogger($userId); $this->removeTeamBlogUser($userId); $this->removeBloggerSubscription($userId); $this->removeSubscriptions($userId); $this->removeEmailNotifications($user); // Lastly, delete user from easyblog $this->removeEasyBlogUser($userId); } /** * Get new ownership for the orphan post * * @since 5.1 * @access public */ public function _getnewOwnerShip($curUserId) { // Predefined, default super admin id $user_id = '42'; $newOwnerShip = $this->config->get('main_orphanitem_ownership', $user_id); // we check if the tobe deleted user is the same user id as the saved user id in config. if ($curUserId == $newOwnerShip) { // this is no no a big no! try to get the next admin. $saUsersId = EB::getSAUsersIds(); if (count($saUsersId) > 0) { for ($i = 0; $i < count($saUsersId); $i++) { if ($saUsersId[$i] != $curUserId) { // New owner found. Let's stop here $newOwnerShip = $saUsersId[$i]; break; } } } } return $newOwnerShip; } /** * Transfer owner of the category * * @since 5.1 * @access public */ public function ownerTransferCategory($userId, $newOwnerShip) { $db = EB::db(); $query = 'UPDATE `#__easyblog_category`'; $query .= ' SET `created_by` = ' . $db->Quote($newOwnerShip); $query .= ' WHERE `created_by` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Transfer the owner of the tags * * @since 5.1 * @access public */ public function ownerTransferTag($userId, $newOwnerShip) { $db = EB::db(); $query = 'UPDATE `#__easyblog_tag`'; $query .= ' SET `created_by` = ' . $db->Quote($newOwnerShip); $query .= ' WHERE `created_by` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Transfer the owner of the blog post * * @since 5.1 * @access public */ public function ownerTransferPost($userId, $newOwnerShip) { jimport('joomla.filesystem.folder'); $db = EB::db(); $postCount = 0; $hasUserMediaFolder = false; // before we transfer the posts, we need to check if this users // has any blog posts that are currently being. $query = "select count(1) from `#__easyblog_post`"; $query .= " where `created_by` = " . $db->Quote($userId); $query .= " and `published` != " . $db->Quote(EASYBLOG_POST_BLANK); $db->setQuery($query); $postCount = $db->loadResult(); // now lets check if this user has media folder or not. $userMediaFolder = JPATH_ROOT . '/' . rtrim($this->config->get('main_image_path'), '/') . '/' . $userId; $hasUserMediaFolder = JFolder::exists($userMediaFolder); // now lets update the onwer ship $query = 'UPDATE `#__easyblog_post`'; $query .= ' SET `created_by` = ' . $db->Quote($newOwnerShip); $query .= ' WHERE `created_by` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } // now we know this user has not created any blog posts but there are images // under this user media folder. lets remove these images. if ($postCount == 0 && $hasUserMediaFolder) { @JFolder::delete($userMediaFolder); } } /** * Transfer the owner of the comments * * @since 5.1 * @access public */ public function onwerTransferComment($userId, $newOwnerShip) { $db = EB::db(); $query = 'UPDATE `#__easyblog_comment`'; $query .= ' SET `created_by` = ' . $db->Quote($newOwnerShip); $query .= ' WHERE `created_by` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Removed assigned user acl group * * @since 5.1 * @access public */ public function removeAssignedACLGroup($userId) { $db = EB::db(); $query = 'DELETE FROM `#__easyblog_acl_group`'; $query .= ' WHERE `content_id` = ' . $db->Quote($userId); $query .= ' AND `type` = ' . $db->Quote('assigned'); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Removed adsense configuration * * @since 5.1 * @access public */ public function removeAdsenseSetting($userId) { $db = EB::db(); $query = 'DELETE FROM `#__easyblog_adsense`'; $query .= ' WHERE `user_id` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Remove any feedburner configuration of the user * * @since 5.1 * @access public */ public function removeFeedburnerSetting($userId) { $db = EB::db(); $query = 'DELETE FROM `#__easyblog_feedburner`'; $query .= ' WHERE `userid` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Remove oauth settings that related to autoposting * * @since 5.1 * @access public */ public function removeOAuthSetting($userId) { $db = EB::db(); // removing oauth posts $query = 'DELETE FROM `#__easyblog_oauth_posts`'; $query .= ' WHERE `oauth_id` IN ('; $query .= ' select `id` from `#__easyblog_oauth` where `user_id` = ' . $db->Quote($userId); $query .= ')'; $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } // removing oauth $query = 'DELETE FROM `#__easyblog_oauth`'; $query .= ' WHERE `user_id` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Remove this blogger from the featured listing * * @since 5.1 * @access public */ public function removeFeaturedBlogger($userId) { $db = EB::db(); $query = 'DELETE FROM `#__easyblog_featured`'; $query .= ' WHERE `content_id` = ' . $db->Quote($userId); $query .= ' AND `type` = ' . $db->Quote('blogger'); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Remove this author from all teams * * @since 5.1 * @access public */ public function removeTeamBlogUser($userId) { $db = EB::db(); $query = 'DELETE FROM `#__easyblog_team_users`'; $query .= ' WHERE `user_id` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * When a user is deleted from the site, we should also remove all subscriptions * related to the user * * @since 5.3.3 * @access public */ public function removeSubscriptions($userId) { $db = EB::db(); $query = 'DELETE FROM `#__easyblog_subscriptions` WHERE `user_id`=' . $db->Quote($userId); $db->setQuery($query); $db->query(); } /** * When a user is deleted from the site, we should also remove all email notification * related to the user * * @since 5.4.6 * @access public */ public function removeEmailNotifications($user) { if (!isset($user['email']) && !$user['email']) { return; } $db = EB::db(); $query = 'DELETE FROM `#__easyblog_mailq` WHERE `recipient` = ' . $db->Quote($user['email']); $db->setQuery($query); $db->query(); } /** * Remove blogger subscription * * @since 5.1 * @access public */ public function removeBloggerSubscription($userId) { $db = EB::db(); $query = 'DELETE FROM `#__easyblog_subscriptions`'; $query .= ' WHERE `uid` = ' . $db->Quote($userId); $query .= ' AND `utype` = ' . $db->Quote(EBLOG_SUBSCRIPTION_BLOGGER); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Remove all the author data from easyblog table * * @since 5.1 * @access public */ public function removeEasyBlogUser($userId) { $db = EB::db(); $query = 'DELETE FROM `#__easyblog_users`'; $query .= ' WHERE `id` = ' . $db->Quote($userId); $db->setQuery($query); $db->query(); if ($db->getErrorNum()) { throw EB::exception($db->stderr(), 500); } } /** * Displays a subscribe to blog checkbox field. * * @since 3.7 * @access public */ public function onContentPrepareData($context , $data) { if (!$this->exists()) { return true; } // Check we are manipulating a valid form. if (!in_array($context, array('com_users.profile', 'com_users.user', 'com_users.registration', 'com_admin.profile'))) { return true; } return true; } /** * Displays necessary fields for EasyBlog. * * @since 3.7 * @access public */ public function onContentPrepareForm($form, $data) { if (!$this->exists()) { return true; } if (!($form instanceof JForm)) { $this->_subject->setError('JERROR_NOT_A_FORM'); return true; } if (!$this->params->get('show_subscribe', false)) { return true; } // Check we are manipulating a valid form. $name = $form->getName(); if (!in_array($name, array('com_admin.profile', 'com_users.user', 'com_users.profile', 'com_users.registration'))) { return true; } JFactory::getLanguage()->load('plg_easyblogusers' , JPATH_ROOT . '/administrator/'); // Add the registration fields to the form. JForm::addFormPath(dirname(__FILE__) . '/profiles'); $state = $form->loadFile('easyblog', false); return true; } } PK!ne$user/easyblogusers/easyblogusers.xmlnu[ User - EasyBlog Users Stack Ideas Sdn Bhd 25 April 2017 Copyright 2010 - 2017 StackIdeas. All rights reserved. GPL License support@stackideas.com https://stackideas.com 5.1.0 EasyBlog user plugin. This plugin is responsible to delete user's related records such as blog post and etc. easyblogusers.php index.html profiles en-GB.plg_user_easyblogusers.ini en-GB.plg_user_easyblogusers.sys.ini
    https://stackideas.com/joomla4compat.xml
    PK!6user/easyblogusers/index.htmlnu[PK!_H(user/easyblogusers/profiles/easyblog.xmlnu[
    PK!V&user/easyblogusers/profiles/index.htmlnu[ PK!%y!finder/tags/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Finder\Tags\Extension\Tags; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Tags( $dispatcher, (array) PluginHelper::getPlugin('finder', 'tags') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!IqHHfinder/tags/tags.xmlnu[ plg_finder_tags Joomla! Project 2013-02 (C) 2013 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_FINDER_TAGS_XML_DESCRIPTION Joomla\Plugin\Finder\Tags services src language/en-GB/plg_finder_tags.ini language/en-GB/plg_finder_tags.sys.ini PK!^ ͻ**"finder/tags/src/Extension/Tags.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Finder\Tags\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Table\Table; use Joomla\Component\Finder\Administrator\Indexer\Adapter; use Joomla\Component\Finder\Administrator\Indexer\Helper; use Joomla\Component\Finder\Administrator\Indexer\Indexer; use Joomla\Component\Finder\Administrator\Indexer\Result; use Joomla\Component\Tags\Site\Helper\RouteHelper; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\DatabaseQuery; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Finder adapter for Joomla Tag. * * @since 3.1 */ final class Tags extends Adapter { use DatabaseAwareTrait; /** * The plugin identifier. * * @var string * @since 3.1 */ protected $context = 'Tags'; /** * The extension name. * * @var string * @since 3.1 */ protected $extension = 'com_tags'; /** * The sublayout to use when rendering the results. * * @var string * @since 3.1 */ protected $layout = 'tag'; /** * The type of content that the adapter indexes. * * @var string * @since 3.1 */ protected $type_title = 'Tag'; /** * The table name. * * @var string * @since 3.1 */ protected $table = '#__tags'; /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * The field the published state is stored in. * * @var string * @since 3.1 */ protected $state_field = 'published'; /** * Method to remove the link information for items that have been deleted. * * @param string $context The context of the action being performed. * @param Table $table A Table object containing the record to be deleted * * @return void * * @since 3.1 * @throws \Exception on database error. */ public function onFinderAfterDelete($context, $table): void { if ($context === 'com_tags.tag') { $id = $table->id; } elseif ($context === 'com_finder.index') { $id = $table->link_id; } else { return; } // Remove the items. $this->remove($id); } /** * Method to determine if the access level of an item changed. * * @param string $context The context of the content passed to the plugin. * @param Table $row A Table object * @param boolean $isNew If the content has just been created * * @return void * * @since 3.1 * @throws \Exception on database error. */ public function onFinderAfterSave($context, $row, $isNew): void { // We only want to handle tags here. if ($context === 'com_tags.tag') { // Check if the access levels are different if (!$isNew && $this->old_access != $row->access) { // Process the change. $this->itemAccessChange($row); } // Reindex the item $this->reindex($row->id); } } /** * Method to reindex the link information for an item that has been saved. * This event is fired before the data is actually saved so we are going * to queue the item to be indexed later. * * @param string $context The context of the content passed to the plugin. * @param Table $row A Table object * @param boolean $isNew If the content is just about to be created * * @return boolean True on success. * * @since 3.1 * @throws \Exception on database error. */ public function onFinderBeforeSave($context, $row, $isNew) { // We only want to handle news feeds here if ($context === 'com_tags.tag') { // Query the database for the old access level if the item isn't new if (!$isNew) { $this->checkItemAccess($row); } } return true; } /** * Method to update the link information for items that have been changed * from outside the edit screen. This is fired when the item is published, * unpublished, archived, or unarchived from the list view. * * @param string $context The context for the content passed to the plugin. * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 3.1 */ public function onFinderChangeState($context, $pks, $value) { // We only want to handle tags here if ($context === 'com_tags.tag') { $this->itemStateChange($pks, $value); } // Handle when the plugin is disabled if ($context === 'com_plugins.plugin' && $value === 0) { $this->pluginDisable($pks); } } /** * Method to index an item. The item must be a Result object. * * @param Result $item The item to index as a Result object. * * @return void * * @since 3.1 * @throws \Exception on database error. */ protected function index(Result $item) { // Check if the extension is enabled if (ComponentHelper::isEnabled($this->extension) === false) { return; } $item->setLanguage(); // Initialize the item parameters. $registry = new Registry($item->params); $item->params = clone ComponentHelper::getParams('com_tags', true); $item->params->merge($registry); $item->metadata = new Registry($item->metadata); // Create a URL as identifier to recognise items again. $item->url = $this->getUrl($item->id, $this->extension, $this->layout); // Build the necessary route and path information. $item->route = RouteHelper::getComponentTagRoute($item->slug, $item->language); // Get the menu title if it exists. $title = $this->getItemMenuTitle($item->url); // Adjust the title if necessary. if (!empty($title) && $this->params->get('use_menu_title', true)) { $item->title = $title; } // Add the meta author. $item->metaauthor = $item->metadata->get('author'); // Handle the link to the metadata. $item->addInstruction(Indexer::META_CONTEXT, 'link'); $item->addInstruction(Indexer::META_CONTEXT, 'metakey'); $item->addInstruction(Indexer::META_CONTEXT, 'metadesc'); $item->addInstruction(Indexer::META_CONTEXT, 'metaauthor'); $item->addInstruction(Indexer::META_CONTEXT, 'author'); $item->addInstruction(Indexer::META_CONTEXT, 'created_by_alias'); // Add the type taxonomy data. $item->addTaxonomy('Type', 'Tag'); // Add the author taxonomy data. if (!empty($item->author) || !empty($item->created_by_alias)) { $item->addTaxonomy('Author', !empty($item->created_by_alias) ? $item->created_by_alias : $item->author); } // Add the language taxonomy data. $item->addTaxonomy('Language', $item->language); // Get content extras. Helper::getContentExtras($item); // Index the item. $this->indexer->index($item); } /** * Method to setup the indexer to be run. * * @return boolean True on success. * * @since 3.1 */ protected function setup() { return true; } /** * Method to get the SQL query used to retrieve the list of content items. * * @param mixed $query A DatabaseQuery object or null. * * @return DatabaseQuery A database object. * * @since 3.1 */ protected function getListQuery($query = null) { $db = $this->getDatabase(); // Check if we can use the supplied SQL query. $query = $query instanceof DatabaseQuery ? $query : $db->getQuery(true) ->select('a.id, a.title, a.alias, a.description AS summary') ->select('a.created_time AS start_date, a.created_user_id AS created_by') ->select('a.metakey, a.metadesc, a.metadata, a.language, a.access') ->select('a.modified_time AS modified, a.modified_user_id AS modified_by') ->select('a.published AS state, a.access, a.created_time AS start_date, a.params'); // Handle the alias CASE WHEN portion of the query $case_when_item_alias = ' CASE WHEN '; $case_when_item_alias .= $query->charLength('a.alias', '!=', '0'); $case_when_item_alias .= ' THEN '; $a_id = $query->castAsChar('a.id'); $case_when_item_alias .= $query->concatenate([$a_id, 'a.alias'], ':'); $case_when_item_alias .= ' ELSE '; $case_when_item_alias .= $a_id . ' END as slug'; $query->select($case_when_item_alias) ->from('#__tags AS a'); // Join the #__users table $query->select('u.name AS author') ->join('LEFT', '#__users AS u ON u.id = a.created_user_id'); // Exclude the ROOT item $query->where($db->quoteName('a.id') . ' > 1'); return $query; } /** * Method to get a SQL query to load the published and access states for the given tag. * * @return DatabaseQuery A database object. * * @since 3.1 */ protected function getStateQuery() { $query = $this->getDatabase()->getQuery(true); $query->select($this->getDatabase()->quoteName('a.id')) ->select($this->getDatabase()->quoteName('a.' . $this->state_field, 'state') . ', ' . $this->getDatabase()->quoteName('a.access')) ->select('NULL AS cat_state, NULL AS cat_access') ->from($this->getDatabase()->quoteName($this->table, 'a')); return $query; } /** * Method to get the query clause for getting items to update by time. * * @param string $time The modified timestamp. * * @return DatabaseQuery A database object. * * @since 3.1 */ protected function getUpdateQueryByTime($time) { // Build an SQL query based on the modified time. $query = $this->getDatabase()->getQuery(true) ->where('a.date >= ' . $this->getDatabase()->quote($time)); return $query; } } PK!߂ &finder/sppagebuilder/sppagebuilder.phpnu[id; } elseif ($context === 'com_finder.index') { $id = $table->link_id; } else { return true; } // Remove the items. return $this->remove($id); } /** * Method to determine if the access level of an item changed. */ public function onFinderAfterSave($context, $row, $isNew) { if ($context === 'com_sppagebuilder.page') { if (!$isNew && $this->old_access != $row->access) { $this->itemAccessChange($row); } $this->reindex($row->id); } return true; } /** * Method to reindex the link information for an item that has been saved. * This event is fired before the data is actually saved so we are going * to queue the item to be indexed later. */ public function onFinderBeforeSave($context, $row, $isNew) { if ($context === 'com_sppagebuilder.page') { if (!$isNew) { $this->checkItemAccess($row); } } return true; } /** * Method to update the link information for items that have been changed * from outside the edit screen. This is fired when the item is published, * unpublished, archived, or unarchived from the list view. */ public function onFinderChangeState($context, $pks, $value) { if ($context === 'com_sppagebuilder.page') { $this->itemStateChange($pks, $value); } if ($context === 'com_plugins.plugin' && $value === 0) { $this->pluginDisable($pks); } } /** * Method to index an item. The item must be a FinderIndexerResult object. */ protected function index(FinderIndexerResult $item, $format = 'html') { $item->setLanguage(); // Check if the extension is enabled if (ComponentHelper::isEnabled($this->extension) === false) { return; } // Set the item context $item->context = 'com_sppagebuilder.page'; $menuItem = self::getActiveMenu($item->id); // Set the summary and the body from page builder settings object. $item->summary = SppagebuilderHelperSite::getPrettyText($item->body); $item->body = SppagebuilderHelperSite::getPrettyText($item->body); $item->url = $this->getUrl($item->id, $this->extension, $this->layout); $link = 'index.php?option=com_sppagebuilder&view=page&id=' . $item->id; if ($item->language && $item->language !== '*' && Multilanguage::isEnabled()) { $link .= '&lang=' . $item->language; } if (isset($menuItem->id) && $menuItem->id) { $link .= '&Itemid=' . $menuItem->id; } $item->route = $link; $item->path = $item->route; if (isset($menuItem->title) && $menuItem->title) { $item->title = $menuItem->title; } // Handle the page author data. $item->addInstruction(FinderIndexer::META_CONTEXT, 'user'); // Add the type taxonomy data. $item->addTaxonomy('Type', 'Page'); // Add the language taxonomy data. $item->addTaxonomy('Language', $item->language); // Index the item. $this->indexer->index($item); } /** * Method to setup the indexer to be run. */ protected function setup() { JLoader::register('SppagebuilderRouter', JPATH_SITE . '/components/com_sppagebuilder/route.php'); return true; } /** * Method to get the SQL query used to retrieve the list of page items. */ protected function getListQuery($query = null) { $db = Factory::getDbo(); // Check if we can use the supplied SQL query. $query = $query instanceof JDatabaseQuery ? $query : $db->getQuery(true) ->select('a.id, a.view_id, a.title AS title, a.text AS body, a.created_on AS start_date') ->select('a.created_by, a.modified, a.modified_by, a.language') ->select('a.access, a.catid, a.extension, a.extension_view, a.published AS state, a.ordering') ->select('u.name') ->from('#__sppagebuilder AS a') ->join('LEFT', '#__users AS u ON u.id = a.created_by') ->where($db->quoteName('a.extension') . ' = ' . $db->quote('com_sppagebuilder')); return $query; } public static function getActiveMenu($pageId) { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select(array('title, id')); $query->from($db->quoteName('#__menu')); $query->where($db->quoteName('link') . ' LIKE '. $db->quote('%option=com_sppagebuilder&view=page&id='. $pageId .'%')); $query->where($db->quoteName('published') . ' = '. $db->quote('1')); $db->setQuery($query); $item = $db->loadObject(); return $item; } } PK!Uff&finder/sppagebuilder/sppagebuilder.xmlnu[ plg_finder_sppagebuilder JoomShaper March 2018 (C) 2010 - 2023 JoomShaper. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt support@joomshaper.com www.joomshaper.com 4.0.8 PLG_FINDER_SP_PAGEBUILDER_XML_DESCRIPTION sppagebuilder.php language/en-GB.plg_finder_sppagebuilder.ini language/en-GB.plg_finder_sppagebuilder.sys.ini PK!@'finder/categories/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Finder\Categories\Extension\Categories; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Categories( $dispatcher, (array) PluginHelper::getPlugin('finder', 'categories') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK! plg_finder_categories Joomla! Project 2011-08 (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_FINDER_CATEGORIES_XML_DESCRIPTION Joomla\Plugin\Finder\Categories services src language/en-GB/plg_finder_categories.ini language/en-GB/plg_finder_categories.sys.ini PK!)88.finder/categories/src/Extension/Categories.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Finder\Categories\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Table\Table; use Joomla\Component\Finder\Administrator\Indexer\Adapter; use Joomla\Component\Finder\Administrator\Indexer\Helper; use Joomla\Component\Finder\Administrator\Indexer\Indexer; use Joomla\Component\Finder\Administrator\Indexer\Result; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\DatabaseQuery; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Smart Search adapter for Joomla Categories. * * @since 2.5 */ final class Categories extends Adapter { use DatabaseAwareTrait; /** * The plugin identifier. * * @var string * @since 2.5 */ protected $context = 'Categories'; /** * The extension name. * * @var string * @since 2.5 */ protected $extension = 'com_categories'; /** * The sublayout to use when rendering the results. * * @var string * @since 2.5 */ protected $layout = 'category'; /** * The type of content that the adapter indexes. * * @var string * @since 2.5 */ protected $type_title = 'Category'; /** * The table name. * * @var string * @since 2.5 */ protected $table = '#__categories'; /** * The field the published state is stored in. * * @var string * @since 2.5 */ protected $state_field = 'published'; /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * Method to setup the indexer to be run. * * @return boolean True on success. * * @since 2.5 */ protected function setup() { return true; } /** * Method to remove the link information for items that have been deleted. * * @param string $context The context of the action being performed. * @param Table $table A Table object containing the record to be deleted * * @return boolean True on success. * * @since 2.5 * @throws \Exception on database error. */ public function onFinderDelete($context, $table) { if ($context === 'com_categories.category') { $id = $table->id; } elseif ($context === 'com_finder.index') { $id = $table->link_id; } else { return true; } // Remove item from the index. return $this->remove($id); } /** * Smart Search after save content method. * Reindexes the link information for a category that has been saved. * It also makes adjustments if the access level of the category has changed. * * @param string $context The context of the category passed to the plugin. * @param Table $row A Table object. * @param boolean $isNew True if the category has just been created. * * @return void * * @since 2.5 * @throws \Exception on database error. */ public function onFinderAfterSave($context, $row, $isNew): void { // We only want to handle categories here. if ($context === 'com_categories.category') { // Check if the access levels are different. if (!$isNew && $this->old_access != $row->access) { // Process the change. $this->itemAccessChange($row); } // Reindex the category item. $this->reindex($row->id); // Check if the parent access level is different. if (!$isNew && $this->old_cataccess != $row->access) { $this->categoryAccessChange($row); } } } /** * Smart Search before content save method. * This event is fired before the data is actually saved. * * @param string $context The context of the category passed to the plugin. * @param Table $row A Table object. * @param boolean $isNew True if the category is just about to be created. * * @return boolean True on success. * * @since 2.5 * @throws \Exception on database error. */ public function onFinderBeforeSave($context, $row, $isNew) { // We only want to handle categories here. if ($context === 'com_categories.category') { // Query the database for the old access level and the parent if the item isn't new. if (!$isNew) { $this->checkItemAccess($row); $this->checkCategoryAccess($row); } } return true; } /** * Method to update the link information for items that have been changed * from outside the edit screen. This is fired when the item is published, * unpublished, archived, or unarchived from the list view. * * @param string $context The context for the category passed to the plugin. * @param array $pks An array of primary key ids of the category that has changed state. * @param integer $value The value of the state that the category has been changed to. * * @return void * * @since 2.5 */ public function onFinderChangeState($context, $pks, $value) { // We only want to handle categories here. if ($context === 'com_categories.category') { /* * The category published state is tied to the parent category * published state so we need to look up all published states * before we change anything. */ foreach ($pks as $pk) { $pk = (int) $pk; $query = clone $this->getStateQuery(); $query->where($this->getDatabase()->quoteName('a.id') . ' = :plgFinderCategoriesId') ->bind(':plgFinderCategoriesId', $pk, ParameterType::INTEGER); $this->getDatabase()->setQuery($query); $item = $this->getDatabase()->loadObject(); // Translate the state. $state = null; if ($item->parent_id != 1) { $state = $item->cat_state; } $temp = $this->translateState($value, $state); // Update the item. $this->change($pk, 'state', $temp); // Reindex the item. $this->reindex($pk); } } // Handle when the plugin is disabled. if ($context === 'com_plugins.plugin' && $value === 0) { $this->pluginDisable($pks); } } /** * Method to index an item. The item must be a Result object. * * @param Result $item The item to index as a Result object. * * @return void * * @since 2.5 * @throws \Exception on database error. */ protected function index(Result $item) { // Check if the extension is enabled. if (ComponentHelper::isEnabled($this->extension) === false) { return; } // Extract the extension element $parts = explode('.', $item->extension); $extension_element = $parts[0]; // Check if the extension that owns the category is also enabled. if (ComponentHelper::isEnabled($extension_element) === false) { return; } $item->setLanguage(); $extension = ucfirst(substr($extension_element, 4)); // Initialize the item parameters. $item->params = new Registry($item->params); $item->metadata = new Registry($item->metadata); /* * Add the metadata processing instructions based on the category's * configuration parameters. */ // Add the meta author. $item->metaauthor = $item->metadata->get('author'); // Handle the link to the metadata. $item->addInstruction(Indexer::META_CONTEXT, 'link'); $item->addInstruction(Indexer::META_CONTEXT, 'metakey'); $item->addInstruction(Indexer::META_CONTEXT, 'metadesc'); $item->addInstruction(Indexer::META_CONTEXT, 'metaauthor'); $item->addInstruction(Indexer::META_CONTEXT, 'author'); // Deactivated Methods // $item->addInstruction(Indexer::META_CONTEXT, 'created_by_alias'); // Trigger the onContentPrepare event. $item->summary = Helper::prepareContent($item->summary, $item->params); // Create a URL as identifier to recognise items again. $item->url = $this->getUrl($item->id, $item->extension, $this->layout); /* * Build the necessary route information. * Need to import component route helpers dynamically, hence the reason it's handled here. */ $class = $extension . 'HelperRoute'; // Need to import component route helpers dynamically, hence the reason it's handled here. \JLoader::register($class, JPATH_SITE . '/components/' . $extension_element . '/helpers/route.php'); if (class_exists($class) && method_exists($class, 'getCategoryRoute')) { $item->route = $class::getCategoryRoute($item->id, $item->language); } else { $class = 'Joomla\\Component\\' . $extension . '\\Site\\Helper\\RouteHelper'; if (class_exists($class) && method_exists($class, 'getCategoryRoute')) { $item->route = $class::getCategoryRoute($item->id, $item->language); } else { // This category has no frontend route. return; } } // Get the menu title if it exists. $title = $this->getItemMenuTitle($item->url); // Adjust the title if necessary. if (!empty($title) && $this->params->get('use_menu_title', true)) { $item->title = $title; } // Translate the state. Categories should only be published if the parent category is published. $item->state = $this->translateState($item->state); // Add the type taxonomy data. $item->addTaxonomy('Type', 'Category'); // Add the language taxonomy data. $item->addTaxonomy('Language', $item->language); // Get content extras. Helper::getContentExtras($item); // Index the item. $this->indexer->index($item); } /** * Method to get the SQL query used to retrieve the list of content items. * * @param mixed $query A DatabaseQuery object or null. * * @return DatabaseQuery A database object. * * @since 2.5 */ protected function getListQuery($query = null) { $db = $this->getDatabase(); // Check if we can use the supplied SQL query. $query = $query instanceof DatabaseQuery ? $query : $db->getQuery(true); $query->select( $db->quoteName( [ 'a.id', 'a.title', 'a.alias', 'a.extension', 'a.metakey', 'a.metadesc', 'a.metadata', 'a.language', 'a.lft', 'a.parent_id', 'a.level', 'a.access', 'a.params', ] ) ) ->select( $db->quoteName( [ 'a.description', 'a.created_user_id', 'a.modified_time', 'a.modified_user_id', 'a.created_time', 'a.published', ], [ 'summary', 'created_by', 'modified', 'modified_by', 'start_date', 'state', ] ) ); // Handle the alias CASE WHEN portion of the query. $case_when_item_alias = ' CASE WHEN '; $case_when_item_alias .= $query->charLength($db->quoteName('a.alias'), '!=', '0'); $case_when_item_alias .= ' THEN '; $a_id = $query->castAsChar($db->quoteName('a.id')); $case_when_item_alias .= $query->concatenate([$a_id, 'a.alias'], ':'); $case_when_item_alias .= ' ELSE '; $case_when_item_alias .= $a_id . ' END AS slug'; $query->select($case_when_item_alias) ->from($db->quoteName('#__categories', 'a')) ->where($db->quoteName('a.id') . ' > 1'); return $query; } /** * Method to get a SQL query to load the published and access states for * a category and its parents. * * @return DatabaseQuery A database object. * * @since 2.5 */ protected function getStateQuery() { $query = $this->getDatabase()->getQuery(true); $query->select( $this->getDatabase()->quoteName( [ 'a.id', 'a.parent_id', 'a.access', ] ) ) ->select( $this->getDatabase()->quoteName( [ 'a.' . $this->state_field, 'c.published', 'c.access', ], [ 'state', 'cat_state', 'cat_access', ] ) ) ->from($this->getDatabase()->quoteName('#__categories', 'a')) ->join( 'INNER', $this->getDatabase()->quoteName('#__categories', 'c'), $this->getDatabase()->quoteName('c.id') . ' = ' . $this->getDatabase()->quoteName('a.parent_id') ); return $query; } } PK! finder/easyblog/easyblog.xmlnu[ Smart Search - EasyBlog Posts Stack Ideas Sdn Bhd 25 April 2017 Copyright 2010 - 2017 StackIdeas. All rights reserved. GPL License support@stackideas.com https://stackideas.com 5.1.0 This plugin indexes EasyBlog blog entries in Smart Search. easyblog.php index.html en-GB.plg_finder_easyblog.ini en-GB.plg_finder_easyblog.sys.ini https://stackideas.com/joomla4compat.xml PK!Fi""finder/easyblog/easyblog.phpnu[extension) == false) { return; } $file = JPATH_ADMINISTRATOR . '/components/com_easyblog/includes/easyblog.php'; jimport('joomla.filesystem.file'); if (!JFile::exists($file)) { return false; } require_once($file); if (!EB::isFoundryEnabled()) { return false; } return true; } /** * Delete a url from the cache * * @since 5.2.6 * @access public */ public function deleteFromCache($id) { if (!$this->exists()) { return; } $db = EB::db(); $query = array(); $query[] = 'SELECT ' . $db->qn('link_id') . ' FROM ' . $db->qn('#__finder_links'); $query[] = 'WHERE ' . $db->qn('url') . ' LIKE ' . $db->Quote('%option=com_easyblog&view=entry&id=' . $id . '%'); $query = implode(' ', $query); $db->setQuery($query); $item = $db->loadResult(); $state = $this->indexer->remove($item); return $state; } /** * Remove link from the database once a post is deleted * * @since 5.2.6 * @access public */ public function onFinderAfterDelete($context, $table) { $allowed = array('easyblog.blog', 'com_finder.index'); if (!in_array($context, $allowed)) { return true; } if ($context == 'easyblog.blog') { $id = $this->deleteFromCache($table->id); } if ($context == 'com_finder.index') { $id = $table->link_id; } return $this->remove($id); } /** * When a post's state is changed, we need to update it accordingly * * @since 5.2.6 * @access public */ public function onFinderAfterSave($context, $post, $isNew) { if (!$this->exists()) { return; } // Only process easyblog items here if ($context == 'easyblog.blog' && !$post->isBlank() && !$post->isDraft() && !$post->isPending() && !$post->isTrashed()) { $this->reindex($post->id); } if ($context == 'easyblog.blog' && $post->isTrashed()) { $this->deleteFromCache($post->id); } return true; } /** * When a post's state is changed, we need to update it accordingly * * @since 6.0.0 * @access public */ public function onFinderChangeState($context, $pks, $value) { // We only want to handle articles here. if ($context === 'easyblog.blog') { $db = EB::db(); $indexedURL = "index.php?option=com_easyblog&view=entry&id=$pks"; $query = 'UPDATE `#__finder_links` SET ' . $db->nameQuote('state') . ' = ' . $db->Quote($value); $query .= ' , ' . $db->nameQuote('published') . ' = ' . $db->Quote($value); $query .= ' WHERE ' . $db->nameQuote('url') . ' = ' . $db->Quote($indexedURL); $db->setQuery($query); $db->query(); } } /** * Indexes post on the site * * @since 5.2.6 * @access public */ protected function proxyIndex($item, $format = 'html') { if (!$this->exists() || !$item->id) { return; } // Build the necessary route and path information. $item->url = 'index.php?option=com_easyblog&view=entry&id='. $item->id; $app = JFactory::getApplication(); $item->route = EBR::_($item->url, true, null, false, false, false); if (!FH::isJoomla4()) { // Get the content path only require in Joomla 3.x $item->path = FinderIndexerHelper::getContentPath($item->route); } // If there is access defined, just set it to 2 which is special privileges. if (!$item->access || $item->access == 0) { $item->access = 1; } else if ($item->access > 0) { $item->access = 2; } // Load up the post item $post = EB::post(); $post->load($item->id); // Get the intro text of the content $item->summary = $post->getIntro(false, true, 'all', false, array('fromRss' => true)); // Get the contents $item->body = $post->getContent('entry', false); // If the post is password protected, we do not want to display the contents if ($post->isPasswordProtected()) { $item->summary = JText::_('PLG_FINDER_EASYBLOG_PASSWORD_PROTECTED'); } else { // we want to get custom fields values. $fields = $post->getCustomFields(); $fieldlib = EB::fields(); $customfields = array(); if ($fields) { foreach($fields as $field) { if ($field->group->hasValues($post)) { foreach ($field->fields as $customField) { $eachField = $fieldlib->get($customField->type); $customfields[] = $eachField->text($customField, $post); } } } $customfieldvalues = implode(' ', $customfields); $item->body = $item->body . ' ' . $customfieldvalues; } } // Add the author's meta data $item->metaauthor = !empty($item->created_by_alias) ? $item->created_by_alias : $item->author; $item->author = !empty($item->created_by_alias) ? $item->created_by_alias : $item->author; // If the post has an image, use it $image = $post->getImage('thumbnail', false, true); // If there's no image, try to scan the contents for an image to be used if (!$image && $post->isLegacy()) { $image = EB::string()->getImage($item->body); } // If we still can't locate any images, use the placeholder image if (!$image) { $image = EB::getPlaceholderImage(); } $registry = new JRegistry(); $registry->set('image', $image); $item->params = $registry; // Add the meta-data processing instructions. $item->addInstruction(FinderIndexer::META_CONTEXT, 'metakey'); $item->addInstruction(FinderIndexer::META_CONTEXT, 'metadesc'); $item->addInstruction(FinderIndexer::META_CONTEXT, 'metaauthor'); $item->addInstruction(FinderIndexer::META_CONTEXT, 'author'); // Add the type taxonomy data. $item->addTaxonomy('Type', 'EasyBlog'); // Add the author taxonomy data. if (!empty($item->author) || !empty($item->created_by_alias)) { $item->addTaxonomy('Author', !empty($item->created_by_alias) ? $item->created_by_alias : $item->author); } // Add the category taxonomy data. $item->addTaxonomy('Category', $item->category, $item->cat_state, $item->cat_access); // Add the language taxonomy data. if (empty($item->language)) $item->language = '*'; $item->addTaxonomy('Language', $item->language); // Get content extras. EBFinderHelper::getContentExtras($item); return $this->indexer->index($item); } /** * Remove any unwanted part of the url in the item link * * @since 5.2.6 * @access public */ private function removeAdminSegment($url = '') { if ($url) { $url = ltrim($url, '/'); $url = str_replace('administrator/index.php', 'index.php', $url); } return $url; } /** * This method would be invoked by Joomla's indexer * * @since 5.2.6 * @access public */ protected function setup() { if (!$this->exists()) { return false; } return true; } /** * Retrieves the sql query used to retrieve blog posts on the site * * @since 5.2.6 * @access public */ protected function getListQuery($sql = null) { $db = JFactory::getDbo(); $sql = is_a($sql, 'JDatabaseQuery') ? $sql : $db->getQuery(true); $sql->select( 'a.*, b.title AS category, u.name AS author, eu.nickname AS created_by_alias'); $sql->select('a.published AS state,a.id AS ordering'); $sql->select('b.published AS cat_state, 1 AS cat_access'); $sql->select('m.keywords AS metakay, m.description AS metadesc'); $sql->from('#__easyblog_post AS a'); // we only fetch the primary category. $sql->join('LEFT', '#__easyblog_post_category AS pc ON pc.post_id = a.id and pc.primary = 1'); $sql->join('INNER', '#__easyblog_category AS b ON b.id = pc.category_id'); $sql->join('LEFT', '#__users AS u ON u.id = a.created_by'); $sql->join('LEFT', '#__easyblog_users AS eu ON eu.id = a.created_by'); $sql->join('LEFT', '#__easyblog_meta AS m ON m.content_id = a.id and m.type = ' . $db->Quote('post')); return $sql; } } PK!6finder/easyblog/index.htmlnu[PK!򘋜$finder/content/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Finder\Content\Extension\Content; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Content( $dispatcher, (array) PluginHelper::getPlugin('finder', 'content') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!{22(finder/content/src/Extension/Content.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Finder\Content\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Table\Table; use Joomla\Component\Content\Site\Helper\RouteHelper; use Joomla\Component\Finder\Administrator\Indexer\Adapter; use Joomla\Component\Finder\Administrator\Indexer\Helper; use Joomla\Component\Finder\Administrator\Indexer\Indexer; use Joomla\Component\Finder\Administrator\Indexer\Result; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\DatabaseQuery; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Smart Search adapter for com_content. * * @since 2.5 */ final class Content extends Adapter { use DatabaseAwareTrait; /** * The plugin identifier. * * @var string * @since 2.5 */ protected $context = 'Content'; /** * The extension name. * * @var string * @since 2.5 */ protected $extension = 'com_content'; /** * The sublayout to use when rendering the results. * * @var string * @since 2.5 */ protected $layout = 'article'; /** * The type of content that the adapter indexes. * * @var string * @since 2.5 */ protected $type_title = 'Article'; /** * The table name. * * @var string * @since 2.5 */ protected $table = '#__content'; /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * Method to setup the indexer to be run. * * @return boolean True on success. * * @since 2.5 */ protected function setup() { return true; } /** * Method to update the item link information when the item category is * changed. This is fired when the item category is published or unpublished * from the list view. * * @param string $extension The extension whose category has been updated. * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ public function onFinderCategoryChangeState($extension, $pks, $value) { // Make sure we're handling com_content categories. if ($extension === 'com_content') { $this->categoryStateChange($pks, $value); } } /** * Method to remove the link information for items that have been deleted. * * @param string $context The context of the action being performed. * @param Table $table A Table object containing the record to be deleted * * @return void * * @since 2.5 * @throws \Exception on database error. */ public function onFinderAfterDelete($context, $table): void { if ($context === 'com_content.article') { $id = $table->id; } elseif ($context === 'com_finder.index') { $id = $table->link_id; } else { return; } // Remove item from the index. $this->remove($id); } /** * Smart Search after save content method. * Reindexes the link information for an article that has been saved. * It also makes adjustments if the access level of an item or the * category to which it belongs has changed. * * @param string $context The context of the content passed to the plugin. * @param Table $row A Table object. * @param boolean $isNew True if the content has just been created. * * @return void * * @since 2.5 * @throws \Exception on database error. */ public function onFinderAfterSave($context, $row, $isNew): void { // We only want to handle articles here. if ($context === 'com_content.article' || $context === 'com_content.form') { // Check if the access levels are different. if (!$isNew && $this->old_access != $row->access) { // Process the change. $this->itemAccessChange($row); } // Reindex the item. $this->reindex($row->id); } // Check for access changes in the category. if ($context === 'com_categories.category') { // Check if the access levels are different. if (!$isNew && $this->old_cataccess != $row->access) { $this->categoryAccessChange($row); } } } /** * Smart Search before content save method. * This event is fired before the data is actually saved. * * @param string $context The context of the content passed to the plugin. * @param Table $row A Table object. * @param boolean $isNew If the content is just about to be created. * * @return boolean True on success. * * @since 2.5 * @throws \Exception on database error. */ public function onFinderBeforeSave($context, $row, $isNew) { // We only want to handle articles here. if ($context === 'com_content.article' || $context === 'com_content.form') { // Query the database for the old access level if the item isn't new. if (!$isNew) { $this->checkItemAccess($row); } } // Check for access levels from the category. if ($context === 'com_categories.category') { // Query the database for the old access level if the item isn't new. if (!$isNew) { $this->checkCategoryAccess($row); } } return true; } /** * Method to update the link information for items that have been changed * from outside the edit screen. This is fired when the item is published, * unpublished, archived, or unarchived from the list view. * * @param string $context The context for the content passed to the plugin. * @param array $pks An array of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ public function onFinderChangeState($context, $pks, $value) { // We only want to handle articles here. if ($context === 'com_content.article' || $context === 'com_content.form') { $this->itemStateChange($pks, $value); } // Handle when the plugin is disabled. if ($context === 'com_plugins.plugin' && $value === 0) { $this->pluginDisable($pks); } } /** * Method to index an item. The item must be a Result object. * * @param Result $item The item to index as a Result object. * * @return void * * @since 2.5 * @throws \Exception on database error. */ protected function index(Result $item) { $item->setLanguage(); // Check if the extension is enabled. if (ComponentHelper::isEnabled($this->extension) === false) { return; } $item->context = 'com_content.article'; // Initialise the item parameters. $registry = new Registry($item->params); $item->params = clone ComponentHelper::getParams('com_content', true); $item->params->merge($registry); $item->metadata = new Registry($item->metadata); // Trigger the onContentPrepare event. $item->summary = Helper::prepareContent($item->summary, $item->params, $item); $item->body = Helper::prepareContent($item->body, $item->params, $item); // Create a URL as identifier to recognise items again. $item->url = $this->getUrl($item->id, $this->extension, $this->layout); // Build the necessary route and path information. $item->route = RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language); // Get the menu title if it exists. $title = $this->getItemMenuTitle($item->url); // Adjust the title if necessary. if (!empty($title) && $this->params->get('use_menu_title', true)) { $item->title = $title; } $images = $item->images ? json_decode($item->images) : false; // Add the image. if ($images && !empty($images->image_intro)) { $item->imageUrl = $images->image_intro; $item->imageAlt = $images->image_intro_alt ?? ''; } // Add the meta author. $item->metaauthor = $item->metadata->get('author'); // Add the metadata processing instructions. $item->addInstruction(Indexer::META_CONTEXT, 'metakey'); $item->addInstruction(Indexer::META_CONTEXT, 'metadesc'); $item->addInstruction(Indexer::META_CONTEXT, 'metaauthor'); $item->addInstruction(Indexer::META_CONTEXT, 'author'); $item->addInstruction(Indexer::META_CONTEXT, 'created_by_alias'); // Translate the state. Articles should only be published if the category is published. $item->state = $this->translateState($item->state, $item->cat_state); // Add the type taxonomy data. $item->addTaxonomy('Type', 'Article'); // Add the author taxonomy data. if (!empty($item->author) || !empty($item->created_by_alias)) { $item->addTaxonomy('Author', !empty($item->created_by_alias) ? $item->created_by_alias : $item->author, $item->state); } // Add the category taxonomy data. $categories = $this->getApplication()->bootComponent('com_content')->getCategory(['published' => false, 'access' => false]); $category = $categories->get($item->catid); // Category does not exist, stop here if (!$category) { return; } $item->addNestedTaxonomy('Category', $category, $this->translateState($category->published), $category->access, $category->language); // Add the language taxonomy data. $item->addTaxonomy('Language', $item->language); // Get content extras. Helper::getContentExtras($item); // Index the item. $this->indexer->index($item); } /** * Method to get the SQL query used to retrieve the list of content items. * * @param mixed $query A DatabaseQuery object or null. * * @return DatabaseQuery A database object. * * @since 2.5 */ protected function getListQuery($query = null) { $db = $this->getDatabase(); // Check if we can use the supplied SQL query. $query = $query instanceof DatabaseQuery ? $query : $db->getQuery(true) ->select('a.id, a.title, a.alias, a.introtext AS summary, a.fulltext AS body') ->select('a.images') ->select('a.state, a.catid, a.created AS start_date, a.created_by') ->select('a.created_by_alias, a.modified, a.modified_by, a.attribs AS params') ->select('a.metakey, a.metadesc, a.metadata, a.language, a.access, a.version, a.ordering') ->select('a.publish_up AS publish_start_date, a.publish_down AS publish_end_date') ->select('c.title AS category, c.published AS cat_state, c.access AS cat_access'); // Handle the alias CASE WHEN portion of the query $case_when_item_alias = ' CASE WHEN '; $case_when_item_alias .= $query->charLength('a.alias', '!=', '0'); $case_when_item_alias .= ' THEN '; $a_id = $query->castAsChar('a.id'); $case_when_item_alias .= $query->concatenate([$a_id, 'a.alias'], ':'); $case_when_item_alias .= ' ELSE '; $case_when_item_alias .= $a_id . ' END as slug'; $query->select($case_when_item_alias); $case_when_category_alias = ' CASE WHEN '; $case_when_category_alias .= $query->charLength('c.alias', '!=', '0'); $case_when_category_alias .= ' THEN '; $c_id = $query->castAsChar('c.id'); $case_when_category_alias .= $query->concatenate([$c_id, 'c.alias'], ':'); $case_when_category_alias .= ' ELSE '; $case_when_category_alias .= $c_id . ' END as catslug'; $query->select($case_when_category_alias) ->select('u.name AS author') ->from('#__content AS a') ->join('LEFT', '#__categories AS c ON c.id = a.catid') ->join('LEFT', '#__users AS u ON u.id = a.created_by'); return $query; } } PK!vaZZfinder/content/content.xmlnu[ plg_finder_content Joomla! Project 2011-08 (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_FINDER_CONTENT_XML_DESCRIPTION Joomla\Plugin\Finder\Content services src language/en-GB/plg_finder_content.ini language/en-GB/plg_finder_content.sys.ini PK!1î&finder/newsfeeds/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Finder\Newsfeeds\Extension\Newsfeeds; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Newsfeeds( $dispatcher, (array) PluginHelper::getPlugin('finder', 'newsfeeds') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!X6|/./.,finder/newsfeeds/src/Extension/Newsfeeds.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Finder\Newsfeeds\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Table\Table; use Joomla\Component\Finder\Administrator\Indexer\Adapter; use Joomla\Component\Finder\Administrator\Indexer\Helper; use Joomla\Component\Finder\Administrator\Indexer\Indexer; use Joomla\Component\Finder\Administrator\Indexer\Result; use Joomla\Component\Newsfeeds\Site\Helper\RouteHelper; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\DatabaseQuery; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Smart Search adapter for Joomla Newsfeeds. * * @since 2.5 */ final class Newsfeeds extends Adapter { use DatabaseAwareTrait; /** * The plugin identifier. * * @var string * @since 2.5 */ protected $context = 'Newsfeeds'; /** * The extension name. * * @var string * @since 2.5 */ protected $extension = 'com_newsfeeds'; /** * The sublayout to use when rendering the results. * * @var string * @since 2.5 */ protected $layout = 'newsfeed'; /** * The type of content that the adapter indexes. * * @var string * @since 2.5 */ protected $type_title = 'News Feed'; /** * The table name. * * @var string * @since 2.5 */ protected $table = '#__newsfeeds'; /** * The field the published state is stored in. * * @var string * @since 2.5 */ protected $state_field = 'published'; /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * Method to update the item link information when the item category is * changed. This is fired when the item category is published or unpublished * from the list view. * * @param string $extension The extension whose category has been updated. * @param array $pks An array of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ public function onFinderCategoryChangeState($extension, $pks, $value) { // Make sure we're handling com_newsfeeds categories. if ($extension === 'com_newsfeeds') { $this->categoryStateChange($pks, $value); } } /** * Method to remove the link information for items that have been deleted. * * @param string $context The context of the action being performed. * @param Table $table A Table object containing the record to be deleted. * * @return void * * @since 2.5 * @throws \Exception on database error. */ public function onFinderAfterDelete($context, $table): void { if ($context === 'com_newsfeeds.newsfeed') { $id = $table->id; } elseif ($context === 'com_finder.index') { $id = $table->link_id; } else { return; } // Remove the item from the index. $this->remove($id); } /** * Smart Search after save content method. * Reindexes the link information for a newsfeed that has been saved. * It also makes adjustments if the access level of a newsfeed item or * the category to which it belongs has changed. * * @param string $context The context of the content passed to the plugin. * @param Table $row A Table object. * @param boolean $isNew True if the content has just been created. * * @return void * * @since 2.5 * @throws \Exception on database error. */ public function onFinderAfterSave($context, $row, $isNew): void { // We only want to handle newsfeeds here. if ($context === 'com_newsfeeds.newsfeed') { // Check if the access levels are different. if (!$isNew && $this->old_access != $row->access) { // Process the change. $this->itemAccessChange($row); } // Reindex the item. $this->reindex($row->id); } // Check for access changes in the category. if ($context === 'com_categories.category') { // Check if the access levels are different. if (!$isNew && $this->old_cataccess != $row->access) { $this->categoryAccessChange($row); } } } /** * Smart Search before content save method. * This event is fired before the data is actually saved. * * @param string $context The context of the content passed to the plugin. * @param Table $row A Table object. * @param boolean $isNew True if the content is just about to be created. * * @return boolean True on success. * * @since 2.5 * @throws \Exception on database error. */ public function onFinderBeforeSave($context, $row, $isNew) { // We only want to handle newsfeeds here. if ($context === 'com_newsfeeds.newsfeed') { // Query the database for the old access level if the item isn't new. if (!$isNew) { $this->checkItemAccess($row); } } // Check for access levels from the category. if ($context === 'com_categories.category') { // Query the database for the old access level if the item isn't new. if (!$isNew) { $this->checkCategoryAccess($row); } } return true; } /** * Method to update the link information for items that have been changed * from outside the edit screen. This is fired when the item is published, * unpublished, archived, or unarchived from the list view. * * @param string $context The context for the content passed to the plugin. * @param array $pks An array of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ public function onFinderChangeState($context, $pks, $value) { // We only want to handle newsfeeds here. if ($context === 'com_newsfeeds.newsfeed') { $this->itemStateChange($pks, $value); } // Handle when the plugin is disabled. if ($context === 'com_plugins.plugin' && $value === 0) { $this->pluginDisable($pks); } } /** * Method to index an item. The item must be a Result object. * * @param Result $item The item to index as a Result object. * * @return void * * @since 2.5 * @throws \Exception on database error. */ protected function index(Result $item) { // Check if the extension is enabled. if (ComponentHelper::isEnabled($this->extension) === false) { return; } $item->setLanguage(); // Initialize the item parameters. $item->params = new Registry($item->params); $item->metadata = new Registry($item->metadata); // Create a URL as identifier to recognise items again. $item->url = $this->getUrl($item->id, $this->extension, $this->layout); // Build the necessary route and path information. $item->route = RouteHelper::getNewsfeedRoute($item->slug, $item->catslug, $item->language); /* * Add the metadata processing instructions based on the newsfeeds * configuration parameters. */ // Add the meta author. $item->metaauthor = $item->metadata->get('author'); // Handle the link to the metadata. $item->addInstruction(Indexer::META_CONTEXT, 'link'); $item->addInstruction(Indexer::META_CONTEXT, 'metakey'); $item->addInstruction(Indexer::META_CONTEXT, 'metadesc'); $item->addInstruction(Indexer::META_CONTEXT, 'metaauthor'); $item->addInstruction(Indexer::META_CONTEXT, 'author'); $item->addInstruction(Indexer::META_CONTEXT, 'created_by_alias'); // Add the type taxonomy data. $item->addTaxonomy('Type', 'News Feed'); // Add the category taxonomy data. $categories = $this->getApplication()->bootComponent('com_newsfeeds')->getCategory(['published' => false, 'access' => false]); $category = $categories->get($item->catid); // Category does not exist, stop here if (!$category) { return; } $item->addNestedTaxonomy('Category', $category, $this->translateState($category->published), $category->access, $category->language); // Add the language taxonomy data. $item->addTaxonomy('Language', $item->language); // Get content extras. Helper::getContentExtras($item); // Index the item. $this->indexer->index($item); } /** * Method to setup the indexer to be run. * * @return boolean True on success. * * @since 2.5 */ protected function setup() { return true; } /** * Method to get the SQL query used to retrieve the list of content items. * * @param mixed $query A DatabaseQuery object or null. * * @return DatabaseQuery A database object. * * @since 2.5 */ protected function getListQuery($query = null) { $db = $this->getDatabase(); // Check if we can use the supplied SQL query. $query = $query instanceof DatabaseQuery ? $query : $db->getQuery(true) ->select('a.id, a.catid, a.name AS title, a.alias, a.link AS link') ->select('a.published AS state, a.ordering, a.created AS start_date, a.params, a.access') ->select('a.publish_up AS publish_start_date, a.publish_down AS publish_end_date') ->select('a.metakey, a.metadesc, a.metadata, a.language') ->select('a.created_by, a.created_by_alias, a.modified, a.modified_by') ->select('c.title AS category, c.published AS cat_state, c.access AS cat_access'); // Handle the alias CASE WHEN portion of the query. $case_when_item_alias = ' CASE WHEN '; $case_when_item_alias .= $query->charLength('a.alias', '!=', '0'); $case_when_item_alias .= ' THEN '; $a_id = $query->castAsChar('a.id'); $case_when_item_alias .= $query->concatenate([$a_id, 'a.alias'], ':'); $case_when_item_alias .= ' ELSE '; $case_when_item_alias .= $a_id . ' END as slug'; $query->select($case_when_item_alias); $case_when_category_alias = ' CASE WHEN '; $case_when_category_alias .= $query->charLength('c.alias', '!=', '0'); $case_when_category_alias .= ' THEN '; $c_id = $query->castAsChar('c.id'); $case_when_category_alias .= $query->concatenate([$c_id, 'c.alias'], ':'); $case_when_category_alias .= ' ELSE '; $case_when_category_alias .= $c_id . ' END as catslug'; $query->select($case_when_category_alias) ->from('#__newsfeeds AS a') ->join('LEFT', '#__categories AS c ON c.id = a.catid'); return $query; } } PK!Kfffinder/newsfeeds/newsfeeds.xmlnu[ plg_finder_newsfeeds Joomla! Project 2011-08 (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_FINDER_NEWSFEEDS_XML_DESCRIPTION Joomla\Plugin\Finder\Newsfeeds services src language/en-GB/plg_finder_newsfeeds.ini language/en-GB/plg_finder_newsfeeds.sys.ini PK! '``finder/contacts/contacts.xmlnu[ plg_finder_contacts Joomla! Project 2011-08 (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 PLG_FINDER_CONTACTS_XML_DESCRIPTION Joomla\Plugin\Finder\Contacts services src language/en-GB/plg_finder_contacts.ini language/en-GB/plg_finder_contacts.sys.ini PK!Ρ%finder/contacts/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Finder\Contacts\Extension\Contacts; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Contacts( $dispatcher, (array) PluginHelper::getPlugin('finder', 'contacts') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!^277*finder/contacts/src/Extension/Contacts.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Finder\Contacts\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Table\Table; use Joomla\Component\Contact\Site\Helper\RouteHelper; use Joomla\Component\Finder\Administrator\Indexer\Adapter; use Joomla\Component\Finder\Administrator\Indexer\Helper; use Joomla\Component\Finder\Administrator\Indexer\Indexer; use Joomla\Component\Finder\Administrator\Indexer\Result; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\DatabaseQuery; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Finder adapter for Joomla Contacts. * * @since 2.5 */ final class Contacts extends Adapter { use DatabaseAwareTrait; /** * The plugin identifier. * * @var string * @since 2.5 */ protected $context = 'Contacts'; /** * The extension name. * * @var string * @since 2.5 */ protected $extension = 'com_contact'; /** * The sublayout to use when rendering the results. * * @var string * @since 2.5 */ protected $layout = 'contact'; /** * The type of content that the adapter indexes. * * @var string * @since 2.5 */ protected $type_title = 'Contact'; /** * The table name. * * @var string * @since 2.5 */ protected $table = '#__contact_details'; /** * The field the published state is stored in. * * @var string * @since 2.5 */ protected $state_field = 'published'; /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * Method to update the item link information when the item category is * changed. This is fired when the item category is published or unpublished * from the list view. * * @param string $extension The extension whose category has been updated. * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ public function onFinderCategoryChangeState($extension, $pks, $value) { // Make sure we're handling com_contact categories if ($extension === 'com_contact') { $this->categoryStateChange($pks, $value); } } /** * Method to remove the link information for items that have been deleted. * * This event will fire when contacts are deleted and when an indexed item is deleted. * * @param string $context The context of the action being performed. * @param Table $table A Table object containing the record to be deleted * * @return void * * @since 2.5 * @throws \Exception on database error. */ public function onFinderAfterDelete($context, $table): void { if ($context === 'com_contact.contact') { $id = $table->id; } elseif ($context === 'com_finder.index') { $id = $table->link_id; } else { return; } // Remove the items. $this->remove($id); } /** * Method to determine if the access level of an item changed. * * @param string $context The context of the content passed to the plugin. * @param Table $row A Table object * @param boolean $isNew If the content has just been created * * @return void * * @since 2.5 * @throws \Exception on database error. */ public function onFinderAfterSave($context, $row, $isNew): void { // We only want to handle contacts here if ($context === 'com_contact.contact') { // Check if the access levels are different if (!$isNew && $this->old_access != $row->access) { // Process the change. $this->itemAccessChange($row); } // Reindex the item $this->reindex($row->id); } // Check for access changes in the category if ($context === 'com_categories.category') { // Check if the access levels are different if (!$isNew && $this->old_cataccess != $row->access) { $this->categoryAccessChange($row); } } } /** * Method to reindex the link information for an item that has been saved. * This event is fired before the data is actually saved so we are going * to queue the item to be indexed later. * * @param string $context The context of the content passed to the plugin. * @param Table $row A Table object * @param boolean $isNew If the content is just about to be created * * @return boolean True on success. * * @since 2.5 * @throws \Exception on database error. */ public function onFinderBeforeSave($context, $row, $isNew) { // We only want to handle contacts here if ($context === 'com_contact.contact') { // Query the database for the old access level if the item isn't new if (!$isNew) { $this->checkItemAccess($row); } } // Check for access levels from the category if ($context === 'com_categories.category') { // Query the database for the old access level if the item isn't new if (!$isNew) { $this->checkCategoryAccess($row); } } return true; } /** * Method to update the link information for items that have been changed * from outside the edit screen. This is fired when the item is published, * unpublished, archived, or unarchived from the list view. * * @param string $context The context for the content passed to the plugin. * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ public function onFinderChangeState($context, $pks, $value) { // We only want to handle contacts here if ($context === 'com_contact.contact') { $this->itemStateChange($pks, $value); } // Handle when the plugin is disabled if ($context === 'com_plugins.plugin' && $value === 0) { $this->pluginDisable($pks); } } /** * Method to index an item. The item must be a Result object. * * @param Result $item The item to index as a Result object. * * @return void * * @since 2.5 * @throws \Exception on database error. */ protected function index(Result $item) { // Check if the extension is enabled if (ComponentHelper::isEnabled($this->extension) === false) { return; } $item->setLanguage(); // Initialize the item parameters. $item->params = new Registry($item->params); // Create a URL as identifier to recognise items again. $item->url = $this->getUrl($item->id, $this->extension, $this->layout); // Build the necessary route and path information. $item->route = RouteHelper::getContactRoute($item->slug, $item->catslug, $item->language); // Get the menu title if it exists. $title = $this->getItemMenuTitle($item->url); // Adjust the title if necessary. if (!empty($title) && $this->params->get('use_menu_title', true)) { $item->title = $title; } /* * Add the metadata processing instructions based on the contact * configuration parameters. */ // Handle the contact position. if ($item->params->get('show_position', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'position'); } // Handle the contact street address. if ($item->params->get('show_street_address', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'address'); } // Handle the contact city. if ($item->params->get('show_suburb', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'city'); } // Handle the contact region. if ($item->params->get('show_state', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'region'); } // Handle the contact country. if ($item->params->get('show_country', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'country'); } // Handle the contact zip code. if ($item->params->get('show_postcode', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'zip'); } // Handle the contact telephone number. if ($item->params->get('show_telephone', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'telephone'); } // Handle the contact fax number. if ($item->params->get('show_fax', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'fax'); } // Handle the contact email address. if ($item->params->get('show_email', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'email'); } // Handle the contact mobile number. if ($item->params->get('show_mobile', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'mobile'); } // Handle the contact webpage. if ($item->params->get('show_webpage', true)) { $item->addInstruction(Indexer::META_CONTEXT, 'webpage'); } // Handle the contact user name. $item->addInstruction(Indexer::META_CONTEXT, 'user'); // Add the type taxonomy data. $item->addTaxonomy('Type', 'Contact'); // Add the category taxonomy data. $categories = $this->getApplication()->bootComponent('com_contact')->getCategory(['published' => false, 'access' => false]); $category = $categories->get($item->catid); // Category does not exist, stop here if (!$category) { return; } $item->addNestedTaxonomy('Category', $category, $this->translateState($category->published), $category->access, $category->language); // Add the language taxonomy data. $item->addTaxonomy('Language', $item->language); // Add the region taxonomy data. if (!empty($item->region) && $this->params->get('tax_add_region', true)) { $item->addTaxonomy('Region', $item->region); } // Add the country taxonomy data. if (!empty($item->country) && $this->params->get('tax_add_country', true)) { $item->addTaxonomy('Country', $item->country); } // Get content extras. Helper::getContentExtras($item); // Index the item. $this->indexer->index($item); } /** * Method to setup the indexer to be run. * * @return boolean True on success. * * @since 2.5 */ protected function setup() { return true; } /** * Method to get the SQL query used to retrieve the list of content items. * * @param mixed $query A DatabaseQuery object or null. * * @return DatabaseQuery A database object. * * @since 2.5 */ protected function getListQuery($query = null) { $db = $this->getDatabase(); // Check if we can use the supplied SQL query. $query = $query instanceof DatabaseQuery ? $query : $db->getQuery(true) ->select('a.id, a.name AS title, a.alias, a.con_position AS position, a.address, a.created AS start_date') ->select('a.created_by_alias, a.modified, a.modified_by') ->select('a.metakey, a.metadesc, a.metadata, a.language') ->select('a.sortname1, a.sortname2, a.sortname3') ->select('a.publish_up AS publish_start_date, a.publish_down AS publish_end_date') ->select('a.suburb AS city, a.state AS region, a.country, a.postcode AS zip') ->select('a.telephone, a.fax, a.misc AS summary, a.email_to AS email, a.mobile') ->select('a.webpage, a.access, a.published AS state, a.ordering, a.params, a.catid') ->select('c.title AS category, c.published AS cat_state, c.access AS cat_access'); // Handle the alias CASE WHEN portion of the query $case_when_item_alias = ' CASE WHEN '; $case_when_item_alias .= $query->charLength('a.alias', '!=', '0'); $case_when_item_alias .= ' THEN '; $a_id = $query->castAsChar('a.id'); $case_when_item_alias .= $query->concatenate([$a_id, 'a.alias'], ':'); $case_when_item_alias .= ' ELSE '; $case_when_item_alias .= $a_id . ' END as slug'; $query->select($case_when_item_alias); $case_when_category_alias = ' CASE WHEN '; $case_when_category_alias .= $query->charLength('c.alias', '!=', '0'); $case_when_category_alias .= ' THEN '; $c_id = $query->castAsChar('c.id'); $case_when_category_alias .= $query->concatenate([$c_id, 'c.alias'], ':'); $case_when_category_alias .= ' ELSE '; $case_when_category_alias .= $c_id . ' END as catslug'; $query->select($case_when_category_alias) ->select('u.name') ->from('#__contact_details AS a') ->join('LEFT', '#__categories AS c ON c.id = a.catid') ->join('LEFT', '#__users AS u ON u.id = a.user_id'); return $query; } } PK!? ??)workflow/publishing/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Workflow\Publishing\Extension\Publishing; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Publishing( $dispatcher, (array) PluginHelper::getPlugin('workflow', 'publishing') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!O*$workflow/publishing/forms/action.xmlnu[
    PK!QA<A<0workflow/publishing/src/Extension/Publishing.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Workflow\Publishing\Extension; use Joomla\CMS\Event\Table\BeforeStoreEvent; use Joomla\CMS\Event\View\DisplayEvent; use Joomla\CMS\Event\Workflow\WorkflowFunctionalityUsedEvent; use Joomla\CMS\Event\Workflow\WorkflowTransitionEvent; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\DatabaseModelInterface; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Table\ContentHistory; use Joomla\CMS\Table\TableInterface; use Joomla\CMS\Workflow\WorkflowPluginTrait; use Joomla\CMS\Workflow\WorkflowServiceInterface; use Joomla\Event\EventInterface; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; use Joomla\String\Inflector; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Workflow Publishing Plugin * * @since 4.0.0 */ final class Publishing extends CMSPlugin implements SubscriberInterface { use WorkflowPluginTrait; /** * Load the language file on instantiation. * * @var boolean * @since 4.0.0 */ protected $autoloadLanguage = true; /** * The name of the supported name to check against * * @var string * @since 4.0.0 */ protected $supportFunctionality = 'core.state'; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.0.0 */ public static function getSubscribedEvents(): array { return [ 'onAfterDisplay' => 'onAfterDisplay', 'onContentBeforeChangeState' => 'onContentBeforeChangeState', 'onContentBeforeSave' => 'onContentBeforeSave', 'onContentPrepareForm' => 'onContentPrepareForm', 'onContentVersioningPrepareTable' => 'onContentVersioningPrepareTable', 'onTableBeforeStore' => 'onTableBeforeStore', 'onWorkflowAfterTransition' => 'onWorkflowAfterTransition', 'onWorkflowBeforeTransition' => 'onWorkflowBeforeTransition', 'onWorkflowFunctionalityUsed' => 'onWorkflowFunctionalityUsed', ]; } /** * The form event. * * @param EventInterface $event The event * * @since 4.0.0 */ public function onContentPrepareForm(EventInterface $event) { [$form, $data] = array_values($event->getArguments()); $context = $form->getName(); // Extend the transition form if ($context === 'com_workflow.transition') { $this->enhanceTransitionForm($form, $data); return; } $this->enhanceItemForm($form, $data); } /** * Add different parameter options to the transition view, we need when executing the transition * * @param Form $form The form * @param stdClass $data The data * * @return boolean * * @since 4.0.0 */ protected function enhanceTransitionForm(Form $form, $data) { $workflow = $this->enhanceWorkflowTransitionForm($form, $data); if (!$workflow) { return true; } $form->setFieldAttribute('publishing', 'extension', $workflow->extension, 'options'); return true; } /** * Disable certain fields in the item form view, when we want to take over this function in the transition * Check also for the workflow implementation and if the field exists * * @param Form $form The form * @param stdClass $data The data * * @return boolean * * @since 4.0.0 */ protected function enhanceItemForm(Form $form, $data) { $context = $form->getName(); if (!$this->isSupported($context)) { return true; } $parts = explode('.', $context); $component = $this->getApplication()->bootComponent($parts[0]); $modelName = $component->getModelName($context); $table = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]) ->getTable(); $fieldname = $table->getColumnAlias('published'); $options = $form->getField($fieldname)->options; $value = $data->$fieldname ?? $form->getValue($fieldname, null, 0); $text = '-'; $textclass = 'body'; switch ($value) { case 1: $textclass = 'success'; break; case 0: case -2: $textclass = 'danger'; } if (!empty($options)) { foreach ($options as $option) { if ($option->value == $value) { $text = $option->text; break; } } } $form->setFieldAttribute($fieldname, 'type', 'spacer'); $label = '' . htmlentities($text, ENT_COMPAT, 'UTF-8') . ''; $form->setFieldAttribute($fieldname, 'label', Text::sprintf('PLG_WORKFLOW_PUBLISHING_PUBLISHED', $label)); return true; } /** * Manipulate the generic list view * * @param DisplayEvent $event * * @since 4.0.0 */ public function onAfterDisplay(DisplayEvent $event) { if (!$this->getApplication()->isClient('administrator')) { return; } $component = $event->getArgument('extensionName'); $section = $event->getArgument('section'); // We need the single model context for checking for workflow $singularsection = Inflector::singularize($section); if (!$this->isSupported($component . '.' . $singularsection)) { return true; } // That's the hard coded list from the AdminController publish method => change, when it's make dynamic in the future $states = [ 'publish', 'unpublish', 'archive', 'trash', 'report', ]; $js = " document.addEventListener('DOMContentLoaded', function() { var dropdown = document.getElementById('toolbar-status-group'); if (!dropdown) { return; } " . json_encode($states) . ".forEach((action) => { var button = document.getElementById('status-group-children-' + action); if (button) { button.classList.add('d-none'); } }); }); "; $this->getApplication()->getDocument()->addScriptDeclaration($js); return true; } /** * Check if we can execute the transition * * @param WorkflowTransitionEvent $event * * @return boolean * * @since 4.0.0 */ public function onWorkflowBeforeTransition(WorkflowTransitionEvent $event) { $context = $event->getArgument('extension'); $transition = $event->getArgument('transition'); $pks = $event->getArgument('pks'); if (!$this->isSupported($context) || !is_numeric($transition->options->get('publishing'))) { return true; } $value = $transition->options->get('publishing'); if (!is_numeric($value)) { return true; } /** * Here it becomes tricky. We would like to use the component models publish method, so we will * Execute the normal "onContentBeforeChangeState" plugins. But they could cancel the execution, * So we have to precheck and cancel the whole transition stuff if not allowed. */ $this->getApplication()->set('plgWorkflowPublishing.' . $context, $pks); $result = $this->getApplication()->triggerEvent('onContentBeforeChangeState', [ $context, $pks, $value, ]); // Release allowed pks, the job is done $this->getApplication()->set('plgWorkflowPublishing.' . $context, []); if (in_array(false, $result, true)) { $event->setStopTransition(); return false; } return true; } /** * Change State of an item. Used to disable state change * * @param WorkflowTransitionEvent $event * * @return boolean * * @since 4.0.0 */ public function onWorkflowAfterTransition(WorkflowTransitionEvent $event) { $context = $event->getArgument('extension'); $extensionName = $event->getArgument('extensionName'); $transition = $event->getArgument('transition'); $pks = $event->getArgument('pks'); if (!$this->isSupported($context)) { return true; } $component = $this->getApplication()->bootComponent($extensionName); $value = $transition->options->get('publishing'); if (!is_numeric($value)) { return; } $options = [ 'ignore_request' => true, // We already have triggered onContentBeforeChangeState, so use our own 'event_before_change_state' => 'onWorkflowBeforeChangeState', ]; $modelName = $component->getModelName($context); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), $options); $model->publish($pks, $value); } /** * Change State of an item. Used to disable state change * * @param EventInterface $event * * @return boolean * * @throws \Exception * @since 4.0.0 */ public function onContentBeforeChangeState(EventInterface $event) { [$form, $pks] = array_values($event->getArguments()); if (!$this->isSupported($context)) { return true; } // We have allowed the pks, so we're the one who triggered // With onWorkflowBeforeTransition => free pass if ($this->getApplication()->get('plgWorkflowPublishing.' . $context) === $pks) { return true; } throw new \Exception($this->getApplication()->getLanguage()->_('PLG_WORKFLOW_PUBLISHING_CHANGE_STATE_NOT_ALLOWED')); } /** * The save event. * * @param EventInterface $event * * @return boolean * * @since 4.0.0 */ public function onContentBeforeSave(EventInterface $event) { /** @var TableInterface $table */ [$context, $table, $isNew, $data] = array_values($event->getArguments()); if (!$this->isSupported($context)) { return true; } $keyName = $table->getColumnAlias('published'); // Check for the old value $article = clone $table; $article->load($table->id); /** * We don't allow the change of the state when we use the workflow * As we're setting the field to disabled, no value should be there at all */ if (isset($data[$keyName])) { $this->getApplication()->enqueueMessage($this->getApplication()->getLanguage()->_('PLG_WORKFLOW_PUBLISHING_CHANGE_STATE_NOT_ALLOWED'), 'error'); return false; } return true; } /** * We remove the publishing field from the versioning * * @param EventInterface $event * * @return boolean * * @since 4.0.0 */ public function onContentVersioningPrepareTable(EventInterface $event) { $subject = $event->getArgument('subject'); $context = $event->getArgument('extension'); if (!$this->isSupported($context)) { return true; } $parts = explode('.', $context); $component = $this->getApplication()->bootComponent($parts[0]); $modelName = $component->getModelName($context); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]); $table = $model->getTable(); $subject->ignoreChanges[] = $table->getColumnAlias('published'); } /** * Pre-processor for $table->store($updateNulls) * * @param BeforeStoreEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableBeforeStore(BeforeStoreEvent $event) { $subject = $event->getArgument('subject'); if (!($subject instanceof ContentHistory)) { return; } $parts = explode('.', $subject->item_id); $typeAlias = $parts[0] . (isset($parts[1]) ? '.' . $parts[1] : ''); if (!$this->isSupported($typeAlias)) { return; } $component = $this->getApplication()->bootComponent($parts[0]); $modelName = $component->getModelName($typeAlias); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]); $table = $model->getTable(); $field = $table->getColumnAlias('published'); $versionData = new Registry($subject->version_data); $versionData->remove($field); $subject->version_data = $versionData->toString(); } /** * Check if the current plugin should execute workflow related activities * * @param string $context * * @return boolean * * @since 4.0.0 */ protected function isSupported($context) { if (!$this->checkAllowedAndForbiddenlist($context) || !$this->checkExtensionSupport($context, $this->supportFunctionality)) { return false; } $parts = explode('.', $context); // We need at least the extension + view for loading the table fields if (count($parts) < 2) { return false; } $component = $this->getApplication()->bootComponent($parts[0]); if ( !$component instanceof WorkflowServiceInterface || !$component->isWorkflowActive($context) || !$component->supportFunctionality($this->supportFunctionality, $context) ) { return false; } $modelName = $component->getModelName($context); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]); if (!$model instanceof DatabaseModelInterface || !method_exists($model, 'publish')) { return false; } $table = $model->getTable(); if (!$table instanceof TableInterface || !$table->hasField('published')) { return false; } return true; } /** * If plugin supports the functionality we set the used variable * * @param WorkflowFunctionalityUsedEvent $event * * @since 4.0.0 */ public function onWorkflowFunctionalityUsed(WorkflowFunctionalityUsedEvent $event) { $functionality = $event->getArgument('functionality'); if ($functionality !== 'core.state') { return; } $event->setUsed(); } } PK!!|/"workflow/publishing/publishing.xmlnu[ plg_workflow_publishing Joomla! Project 2020-03 (C) 2020 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.0.0 PLG_WORKFLOW_PUBLISHING_XML_DESCRIPTION Joomla\Plugin\Workflow\Publishing forms services src language/en-GB/plg_workflow_publishing.ini language/en-GB/plg_workflow_publishing.sys.ini
    PK!ƨ ::(workflow/featuring/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Workflow\Featuring\Extension\Featuring; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Featuring( $dispatcher, (array) PluginHelper::getPlugin('workflow', 'featuring') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!} workflow/featuring/featuring.xmlnu[ plg_workflow_featuring Joomla! Project 2020-03 (C) 2020 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.0.0 PLG_WORKFLOW_FEATURING_XML_DESCRIPTION Joomla\Plugin\Workflow\Featuring forms services src language/en-GB/plg_workflow_featuring.ini language/en-GB/plg_workflow_featuring.sys.ini
    PK!  #workflow/featuring/forms/action.xmlnu[
    PK!س)s<s<.workflow/featuring/src/Extension/Featuring.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Workflow\Featuring\Extension; use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Event\Table\BeforeStoreEvent; use Joomla\CMS\Event\View\DisplayEvent; use Joomla\CMS\Event\Workflow\WorkflowFunctionalityUsedEvent; use Joomla\CMS\Event\Workflow\WorkflowTransitionEvent; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\DatabaseModelInterface; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Table\ContentHistory; use Joomla\CMS\Table\TableInterface; use Joomla\CMS\Workflow\WorkflowPluginTrait; use Joomla\CMS\Workflow\WorkflowServiceInterface; use Joomla\Component\Content\Administrator\Event\Model\FeatureEvent; use Joomla\Event\EventInterface; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; use Joomla\String\Inflector; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Workflow Featuring Plugin * * @since 4.0.0 */ final class Featuring extends CMSPlugin implements SubscriberInterface { use WorkflowPluginTrait; /** * Load the language file on instantiation. * * @var boolean * @since 4.0.0 */ protected $autoloadLanguage = true; /** * The name of the supported functionality to check against * * @var string * @since 4.0.0 */ protected $supportFunctionality = 'core.featured'; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.0.0 */ public static function getSubscribedEvents(): array { return [ 'onAfterDisplay' => 'onAfterDisplay', 'onContentBeforeChangeFeatured' => 'onContentBeforeChangeFeatured', 'onContentBeforeSave' => 'onContentBeforeSave', 'onContentPrepareForm' => 'onContentPrepareForm', 'onContentVersioningPrepareTable' => 'onContentVersioningPrepareTable', 'onTableBeforeStore' => 'onTableBeforeStore', 'onWorkflowAfterTransition' => 'onWorkflowAfterTransition', 'onWorkflowBeforeTransition' => 'onWorkflowBeforeTransition', 'onWorkflowFunctionalityUsed' => 'onWorkflowFunctionalityUsed', ]; } /** * The form event. * * @param EventInterface $event The event * * @since 4.0.0 */ public function onContentPrepareForm(EventInterface $event) { [$form, $data] = array_values($event->getArguments()); $context = $form->getName(); // Extend the transition form if ($context === 'com_workflow.transition') { $this->enhanceWorkflowTransitionForm($form, $data); return; } $this->enhanceItemForm($form, $data); } /** * Disable certain fields in the item form view, when we want to take over this function in the transition * Check also for the workflow implementation and if the field exists * * @param Form $form The form * @param stdClass $data The data * * @return boolean * * @since 4.0.0 */ protected function enhanceItemForm(Form $form, $data) { $context = $form->getName(); if (!$this->isSupported($context)) { return true; } $parts = explode('.', $context); $component = $this->getApplication()->bootComponent($parts[0]); $modelName = $component->getModelName($context); $table = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]) ->getTable(); $fieldname = $table->getColumnAlias('featured'); $options = $form->getField($fieldname)->options; $value = $data->$fieldname ?? $form->getValue($fieldname, null, 0); $text = '-'; $textclass = 'body'; switch ($value) { case 1: $textclass = 'success'; break; case 0: case -2: $textclass = 'danger'; } if (!empty($options)) { foreach ($options as $option) { if ($option->value == $value) { $text = $option->text; break; } } } $form->setFieldAttribute($fieldname, 'type', 'spacer'); $label = '' . htmlentities($text, ENT_COMPAT, 'UTF-8') . ''; $form->setFieldAttribute( $fieldname, 'label', Text::sprintf('PLG_WORKFLOW_FEATURING_FEATURED', $label) ); return true; } /** * Manipulate the generic list view * * @param DisplayEvent $event * * @since 4.0.0 */ public function onAfterDisplay(DisplayEvent $event) { if (!$this->getApplication()->isClient('administrator')) { return; } $component = $event->getArgument('extensionName'); $section = $event->getArgument('section'); // We need the single model context for checking for workflow $singularsection = Inflector::singularize($section); if (!$this->isSupported($component . '.' . $singularsection)) { return true; } // List of related batch functions we need to hide $states = [ 'featured', 'unfeatured', ]; $js = " document.addEventListener('DOMContentLoaded', function() { var dropdown = document.getElementById('toolbar-status-group'); if (!dropdown) { return; } " . json_encode($states) . ".forEach((action) => { var button = document.getElementById('status-group-children-' + action); if (button) { button.classList.add('d-none'); } }); }); "; $this->getApplication()->getDocument()->addScriptDeclaration($js); return true; } /** * Check if we can execute the transition * * @param WorkflowTransitionEvent $event * * @return boolean * * @since 4.0.0 */ public function onWorkflowBeforeTransition(WorkflowTransitionEvent $event) { $context = $event->getArgument('extension'); $transition = $event->getArgument('transition'); $pks = $event->getArgument('pks'); if (!$this->isSupported($context) || !is_numeric($transition->options->get('featuring'))) { return true; } $value = $transition->options->get('featuring'); if (!is_numeric($value)) { return true; } /** * Here it becomes tricky. We would like to use the component models featured method, so we will * Execute the normal "onContentBeforeChangeFeatured" plugins. But they could cancel the execution, * So we have to precheck and cancel the whole transition stuff if not allowed. */ $this->getApplication()->set('plgWorkflowFeaturing.' . $context, $pks); // Trigger the change state event. $eventResult = $this->getApplication()->getDispatcher()->dispatch( 'onContentBeforeChangeFeatured', AbstractEvent::create( 'onContentBeforeChangeFeatured', [ 'eventClass' => 'Joomla\Component\Content\Administrator\Event\Model\FeatureEvent', 'subject' => $this, 'extension' => $context, 'pks' => $pks, 'value' => $value, 'abort' => false, 'abortReason' => '', ] ) ); // Release allowed pks, the job is done $this->getApplication()->set('plgWorkflowFeaturing.' . $context, []); if ($eventResult->getArgument('abort')) { $event->setStopTransition(); return false; } return true; } /** * Change Feature State of an item. Used to disable feature state change * * @param WorkflowTransitionEvent $event * * @return void * * @since 4.0.0 */ public function onWorkflowAfterTransition(WorkflowTransitionEvent $event): void { $context = $event->getArgument('extension'); $extensionName = $event->getArgument('extensionName'); $transition = $event->getArgument('transition'); $pks = $event->getArgument('pks'); if (!$this->isSupported($context)) { return; } $component = $this->getApplication()->bootComponent($extensionName); $value = $transition->options->get('featuring'); if (!is_numeric($value)) { return; } $options = [ 'ignore_request' => true, // We already have triggered onContentBeforeChangeFeatured, so use our own 'event_before_change_featured' => 'onWorkflowBeforeChangeFeatured', ]; $modelName = $component->getModelName($context); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), $options); $model->featured($pks, $value); } /** * Change Feature State of an item. Used to disable Feature state change * * @param FeatureEvent $event * * @return boolean * * @throws Exception * @since 4.0.0 */ public function onContentBeforeChangeFeatured(FeatureEvent $event) { $extension = $event->getArgument('extension'); $pks = $event->getArgument('pks'); if (!$this->isSupported($extension)) { return true; } // We have allowed the pks, so we're the one who triggered // With onWorkflowBeforeTransition => free pass if ($this->getApplication()->get('plgWorkflowFeaturing.' . $extension) === $pks) { return true; } $event->setAbort('PLG_WORKFLOW_FEATURING_CHANGE_STATE_NOT_ALLOWED'); } /** * The save event. * * @param EventInterface $event * * @return boolean * * @since 4.0.0 */ public function onContentBeforeSave(EventInterface $event) { /** @var TableInterface $table */ [$context, $table, $isNew, $data] = array_values($event->getArguments()); if (!$this->isSupported($context)) { return true; } $keyName = $table->getColumnAlias('featured'); // Check for the old value $article = clone $table; $article->load($table->id); /** * We don't allow the change of the feature state when we use the workflow * As we're setting the field to disabled, no value should be there at all */ if (isset($data[$keyName])) { $this->getApplication()->enqueueMessage( $this->getApplication()->getLanguage()->_('PLG_WORKFLOW_FEATURING_CHANGE_STATE_NOT_ALLOWED'), 'error' ); return false; } return true; } /** * We remove the featured field from the versioning * * @param EventInterface $event * * @return boolean * * @since 4.0.0 */ public function onContentVersioningPrepareTable(EventInterface $event) { $subject = $event->getArgument('subject'); $context = $event->getArgument('extension'); if (!$this->isSupported($context)) { return true; } $parts = explode('.', $context); $component = $this->getApplication()->bootComponent($parts[0]); $modelName = $component->getModelName($context); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]); $table = $model->getTable(); $subject->ignoreChanges[] = $table->getColumnAlias('featured'); } /** * Pre-processor for $table->store($updateNulls) * * @param BeforeStoreEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableBeforeStore(BeforeStoreEvent $event) { $subject = $event->getArgument('subject'); if (!($subject instanceof ContentHistory)) { return; } $parts = explode('.', $subject->item_id); $typeAlias = $parts[0] . (isset($parts[1]) ? '.' . $parts[1] : ''); if (!$this->isSupported($typeAlias)) { return; } $component = $this->getApplication()->bootComponent($parts[0]); $modelName = $component->getModelName($typeAlias); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]); $table = $model->getTable(); $field = $table->getColumnAlias('featured'); $versionData = new Registry($subject->version_data); $versionData->remove($field); $subject->version_data = $versionData->toString(); } /** * Check if the current plugin should execute workflow related activities * * @param string $context * * @return boolean * * @since 4.0.0 */ protected function isSupported($context) { if (!$this->checkAllowedAndForbiddenlist($context) || !$this->checkExtensionSupport($context, $this->supportFunctionality)) { return false; } $parts = explode('.', $context); // We need at least the extension + view for loading the table fields if (count($parts) < 2) { return false; } $component = $this->getApplication()->bootComponent($parts[0]); if ( !$component instanceof WorkflowServiceInterface || !$component->isWorkflowActive($context) || !$component->supportFunctionality($this->supportFunctionality, $context) ) { return false; } $modelName = $component->getModelName($context); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]); if (!$model instanceof DatabaseModelInterface || !method_exists($model, 'featured')) { return false; } $table = $model->getTable(); if (!$table instanceof TableInterface || !$table->hasField('featured')) { return false; } return true; } /** * If plugin supports the functionality we set the used variable * * @param WorkflowFunctionalityUsedEvent $event * * @since 4.0.0 */ public function onWorkflowFunctionalityUsed(WorkflowFunctionalityUsedEvent $event) { $functionality = $event->getArgument('functionality'); if ($functionality !== 'core.featured') { return; } $event->setUsed(); } } PK!49h+workflow/notification/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Language\LanguageFactoryInterface; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\User\UserFactoryInterface; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Workflow\Notification\Extension\Notification; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $plugin = new Notification( $container->get(DispatcherInterface::class), (array) PluginHelper::getPlugin('workflow', 'notification'), $container->get(LanguageFactoryInterface::class) ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); $plugin->setUserFactory($container->get(UserFactoryInterface::class)); return $plugin; } ); } }; PK!ūC|&workflow/notification/notification.xmlnu[ plg_workflow_notification Joomla! Project 2020-05 (C) 2020 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.0.0 PLG_WORKFLOW_NOTIFICATION_XML_DESCRIPTION Joomla\Plugin\Workflow\Notification forms services src language/en-GB/plg_workflow_notification.ini language/en-GB/plg_workflow_notification.sys.ini
    PK!&workflow/notification/forms/action.xmlnu[
    PK!b+b+4workflow/notification/src/Extension/Notification.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Workflow\Notification\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Event\Workflow\WorkflowTransitionEvent; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\LanguageFactoryInterface; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\User\UserFactoryAwareTrait; use Joomla\CMS\Workflow\WorkflowPluginTrait; use Joomla\CMS\Workflow\WorkflowServiceInterface; use Joomla\Database\DatabaseAwareTrait; use Joomla\Event\DispatcherInterface; use Joomla\Event\EventInterface; use Joomla\Event\SubscriberInterface; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Workflow Notification Plugin * * @since 4.0.0 */ final class Notification extends CMSPlugin implements SubscriberInterface { use WorkflowPluginTrait; use DatabaseAwareTrait; use UserFactoryAwareTrait; /** * Load the language file on instantiation. * * @var boolean * @since 4.0.0 */ protected $autoloadLanguage = true; /** * The language factory. * * @var LanguageFactoryInterface * @since 4.4.0 */ private $languageFactory; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.0.0 */ public static function getSubscribedEvents(): array { return [ 'onContentPrepareForm' => 'onContentPrepareForm', 'onWorkflowAfterTransition' => 'onWorkflowAfterTransition', ]; } /** * Constructor. * * @param DispatcherInterface $dispatcher The dispatcher * @param array $config An optional associative array of configuration settings * @param LanguageFactoryInterface $languageFactory The language factory * * @since 4.2.0 */ public function __construct(DispatcherInterface $dispatcher, array $config, LanguageFactoryInterface $languageFactory) { parent::__construct($dispatcher, $config); $this->languageFactory = $languageFactory; } /** * The form event. * * @param Form $form The form * @param stdClass $data The data * * @return boolean * * @since 4.0.0 */ public function onContentPrepareForm(EventInterface $event) { [$form, $data] = array_values($event->getArguments()); $context = $form->getName(); // Extend the transition form if ($context === 'com_workflow.transition') { $this->enhanceWorkflowTransitionForm($form, $data); } return true; } /** * Send a Notification to defined users a transition is performed * * @param WorkflowTransitionEvent $event The workflow event being processed. * * @return void * * @since 4.0.0 */ public function onWorkflowAfterTransition(WorkflowTransitionEvent $event) { $context = $event->getArgument('extension'); $extensionName = $event->getArgument('extensionName'); $transition = $event->getArgument('transition'); $pks = $event->getArgument('pks'); if (!$this->isSupported($context)) { return; } $component = $this->getApplication()->bootComponent($extensionName); // Check if send-mail is active if (empty($transition->options['notification_send_mail'])) { return; } // ID of the items whose state has changed. $pks = ArrayHelper::toInteger($pks); if (empty($pks)) { return; } // Get UserIds of Receivers $userIds = $this->getUsersFromGroup($transition); // The active user $user = $this->getApplication()->getIdentity(); // Prepare Language for messages $defaultLanguage = ComponentHelper::getParams('com_languages')->get('administrator'); $debug = $this->getApplication()->get('debug_lang'); $modelName = $component->getModelName($context); $model = $component->getMVCFactory()->createModel($modelName, $this->getApplication()->getName(), ['ignore_request' => true]); // Don't send the notification to the active user $key = array_search($user->id, $userIds); if (is_int($key)) { unset($userIds[$key]); } // Remove users with locked input box from the list of receivers if (!empty($userIds)) { $userIds = $this->removeLocked($userIds); } // If there are no receivers, stop here if (empty($userIds)) { $this->getApplication()->enqueueMessage($this->getApplication()->getLanguage()->_('PLG_WORKFLOW_NOTIFICATION_NO_RECEIVER'), 'error'); return; } // Get the model for private messages $model_message = $this->getApplication()->bootComponent('com_messages') ->getMVCFactory()->createModel('Message', 'Administrator'); // Get the title of the stage $model_stage = $this->getApplication()->bootComponent('com_workflow') ->getMVCFactory()->createModel('Stage', 'Administrator'); $toStage = $model_stage->getItem($transition->to_stage_id)->title; // Get the name of the transition $model_transition = $this->getApplication()->bootComponent('com_workflow') ->getMVCFactory()->createModel('Transition', 'Administrator'); $transitionName = $model_transition->getItem($transition->id)->title; $hasGetItem = method_exists($model, 'getItem'); foreach ($pks as $pk) { // Get the title of the item which has changed, unknown as fallback $title = $this->getApplication()->getLanguage()->_('PLG_WORKFLOW_NOTIFICATION_NO_TITLE'); if ($hasGetItem) { $item = $model->getItem($pk); $title = !empty($item->title) ? $item->title : $title; } // Send Email to receivers foreach ($userIds as $user_id) { $receiver = $this->getUserFactory()->loadUserById($user_id); if ($receiver->authorise('core.manage', 'com_messages')) { // Load language for messaging $lang = $this->languageFactory->createLanguage($user->getParam('admin_language', $defaultLanguage), $debug); $lang->load('plg_workflow_notification'); $messageText = sprintf( $lang->_('PLG_WORKFLOW_NOTIFICATION_ON_TRANSITION_MSG'), $title, $lang->_($transitionName), $user->name, $lang->_($toStage) ); if (!empty($transition->options['notification_text'])) { $messageText .= '
    ' . htmlspecialchars($lang->_($transition->options['notification_text'])); } $message = [ 'id' => 0, 'user_id_to' => $receiver->id, 'subject' => sprintf($lang->_('PLG_WORKFLOW_NOTIFICATION_ON_TRANSITION_SUBJECT'), $title), 'message' => $messageText, ]; $model_message->save($message); } } } $this->getApplication()->enqueueMessage($this->getApplication()->getLanguage()->_('PLG_WORKFLOW_NOTIFICATION_SENT'), 'message'); } /** * Get user_ids of receivers * * @param object $data Object containing data about the transition * * @return array $userIds The receivers * * @since 4.0.0 */ private function getUsersFromGroup($data): array { $users = []; // Single userIds if (!empty($data->options['notification_receivers'])) { $users = ArrayHelper::toInteger($data->options['notification_receivers']); } // Usergroups $groups = []; if (!empty($data->options['notification_groups'])) { $groups = ArrayHelper::toInteger($data->options['notification_groups']); } $users2 = []; if (!empty($groups)) { // UserIds from usergroups $model = $this->getApplication()->bootComponent('com_users') ->getMVCFactory()->createModel('Users', 'Administrator', ['ignore_request' => true]); $model->setState('list.select', 'id'); $model->setState('filter.groups', $groups); $model->setState('filter.state', 0); // Ids from usergroups $groupUsers = $model->getItems(); $users2 = ArrayHelper::getColumn($groupUsers, 'id'); } // Merge userIds from individual entries and userIDs from groups return array_unique(array_merge($users, $users2)); } /** * Check if the current plugin should execute workflow related activities * * @param string $context * * @return boolean * * @since 4.0.0 */ protected function isSupported($context) { if (!$this->checkAllowedAndForbiddenlist($context)) { return false; } $parts = explode('.', $context); // We need at least the extension + view for loading the table fields if (count($parts) < 2) { return false; } $component = $this->getApplication()->bootComponent($parts[0]); if (!$component instanceof WorkflowServiceInterface || !$component->isWorkflowActive($context)) { return false; } return true; } /** * Remove receivers who have locked their message inputbox * * @param array $userIds The userIds which must be checked * * @return array users with active message input box * * @since 4.0.0 */ private function removeLocked(array $userIds): array { if (empty($userIds)) { return []; } $db = $this->getDatabase(); // Check for locked inboxes would be better to have _cdf settings in the user_object or a filter in users model $query = $db->getQuery(true); $query->select($db->quoteName('user_id')) ->from($db->quoteName('#__messages_cfg')) ->whereIn($db->quoteName('user_id'), $userIds) ->where($db->quoteName('cfg_name') . ' = ' . $db->quote('locked')) ->where($db->quoteName('cfg_value') . ' = 1'); $locked = $db->setQuery($query)->loadColumn(); return array_diff($userIds, $locked); } } PK!V index.htmlnu[ PK!b%%editors/jce/jce.phpnu[ $this->params->get('profile_id', 0), 'plugin' => $this->params->get('plugin', '') ); $signature = md5(serialize($config)); if (empty(self::$instances[$signature])) { // load base file require_once JPATH_ADMINISTRATOR . '/components/com_jce/includes/base.php'; // create editor self::$instances[$signature] = new WFEditor($config); } return self::$instances[$signature]; } /** * Method to handle the onInit event. * - Initializes the JCE WYSIWYG Editor. * * @param $toString Return javascript and css as a string * * @return string JavaScript Initialization string * * @since 1.5 */ public function onInit() { if (!ComponentHelper::isEnabled('com_jce')) { return false; } $language = Factory::getLanguage(); $document = Factory::getDocument(); $language->load('plg_editors_jce', JPATH_ADMINISTRATOR); $language->load('com_jce', JPATH_ADMINISTRATOR); $editor = $this->getEditorInstance(); $editor->init(); foreach ($editor->getScripts() as $script) { $document->addScript($script); } foreach ($editor->getStyleSheets() as $style) { $document->addStylesheet($style); } $document->addScriptDeclaration(implode("\n", $editor->getScriptDeclaration())); } /** * JCE WYSIWYG Editor - get the editor content. * * @vars string The name of the editor */ public function onGetContent($editor) { return $this->onSave($editor); } /** * JCE WYSIWYG Editor - set the editor content. * * @vars string The name of the editor */ public function onSetContent($editor, $html) { return "WFEditor.setContent('" . $editor . "','" . $html . "');"; } /** * JCE WYSIWYG Editor - copy editor content to form field. * * @vars string The name of the editor */ public function onSave($editor) { return "WFEditor.getContent('" . $editor . "');"; } /** * JCE WYSIWYG Editor - Display the editor area. * * @param string $name The name of the editor area. * @param string $content The content of the field. * @param string $width The width of the editor area. * @param string $height The height of the editor area. * @param int $col The number of columns for the editor area. * @param int $row The number of rows for the editor area. * @param boolean $buttons True and the editor buttons will be displayed. * @param string $id An optional ID for the textarea. If not supplied the name is used. * @param string $asset The object asset * @param object $author The author. * @param array $params Associative array of editor parameters. * * @return string */ public function onDisplay($name, $content, $width, $height, $col, $row, $buttons = true, $id = null, $asset = null, $author = null, $params = array()) { if (empty($id)) { $id = $name; } // Only add "px" to width and height if they are not given as a percentage if (is_numeric($width)) { $width .= 'px'; } if (is_numeric($height)) { $height .= 'px'; } if (empty($id)) { $id = $name; } // Data object for the layout $textarea = new stdClass; $textarea->name = $name; $textarea->id = $id; $textarea->class = 'mce_editable wf-editor'; $textarea->cols = $col; $textarea->rows = $row; $textarea->width = $width; $textarea->height = $height; $textarea->content = $content; $classes = version_compare(JVERSION, '4', 'ge') ? ' mb-2 joomla4' : ''; // Render Editor markup $html = '
    '; $html .= '
    '; $html .= LayoutHelper::render('editor.textarea', $textarea, __DIR__ . '/layouts'); $html .= '
    '; if (!ComponentHelper::isEnabled('com_jce')) { return $html; } $editor = $this->getEditorInstance(); // no profile assigned or available if (!$editor->hasProfile()) { return $html; } if (!$editor->hasPlugin('joomla')) { $html .= $this->displayButtons($id, $buttons, $asset, $author); } else { $list = $this->getXtdButtonsList($id, $buttons, $asset, $author); if (!empty($list)) { $options = array( 'joomla_xtd_buttons' => $list, ); Factory::getDocument()->addScriptOptions('plg_editor_jce', $options, true); } // render empty container for dynamic buttons $html .= LayoutHelper::render('joomla.editors.buttons', array()); } return $html; } public function onGetInsertMethod($name) { } private function getXtdButtonsList($name, $buttons, $asset, $author) { $list = array(); $excluded = array('readmore', 'pagebreak', 'image'); if (!is_array($buttons)) { $buttons = !$buttons ? false : $excluded; } else { $buttons = array_merge($buttons, $excluded); } $buttons = $this->getXtdButtons($name, $buttons, $asset, $author); if (!empty($buttons)) { foreach ($buttons as $i => $button) { if ($button->get('name')) { // Set some vars $icon = 'none icon-' . $button->get('icon', $button->get('name')); $name = 'button-' . $i . '-' . str_replace(' ', '-', $button->get('text')); $title = $button->get('text'); $onclick = $button->get('onclick', ''); if ($button->get('link') !== '#') { $href = JUri::base() . $button->get('link'); } else { $href = ''; } $list[] = array( 'name' => $name, 'title' => $title, 'icon' => $icon, 'href' => $href, 'onclick' => $onclick, 'svg' => $button->get('iconSVG'), 'options' => $button->get('options', array()) ); } } } return $list; } private function getXtdButtons($name, $buttons, $asset, $author) { $xtdbuttons = array(); if (is_array($buttons) || (is_bool($buttons) && $buttons)) { $buttonsEvent = new Joomla\Event\Event( 'getButtons', [ 'editor' => $name, 'buttons' => $buttons, ] ); if (method_exists($this, 'getDispatcher')) { $buttonsResult = $this->getDispatcher()->dispatch('getButtons', $buttonsEvent); $xtdbuttons = $buttonsResult['result']; } else { $xtdbuttons = $this->_subject->getButtons($name, $buttons, $asset, $author); } } return $xtdbuttons; } private function displayButtons($name, $buttons, $asset, $author) { $buttons = $this->getXtdButtons($name, $buttons, $asset, $author); if (!empty($buttons)) { // fix some legacy buttons array_walk($buttons, function ($button) { $cls = $button->get('class', ''); if (empty($cls) || strpos($cls, 'btn') === false) { $cls .= ' btn'; $button->set('class', trim($cls)); } }); return LayoutHelper::render('joomla.editors.buttons', $buttons); } } } PK!<=//editors/jce/jce.xmlnu[ plg_editors_jce 2.9.33 18-01-2023 Ryan Demmer info@joomlacontenteditor.net http://www.joomlacontenteditor.net Copyright (C) 2006 - 2022 Ryan Demmer. All rights reserved GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html WF_EDITOR_PLUGIN_DESC jce.php layouts icons en-GB.plg_editors_jce.ini en-GB.plg_editors_jce.sys.ini PK!{,t'editors/jce/layouts/editor/textarea.phpnu[ PK!i'editors/tinymce/tinymce.xmlnu[ plg_editors_tinymce 5.10.7 2005-08 Tiny Technologies, Inc N/A https://www.tiny.cloud Tiny Technologies, Inc LGPL PLG_TINY_XML_DESCRIPTION Joomla\Plugin\Editors\TinyMCE forms services src tinymce language/en-GB/plg_editors_tinymce.ini language/en-GB/plg_editors_tinymce.sys.ini
    PK!t0%editors/tinymce/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Editors\TinyMCE\Extension\TinyMCE; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new TinyMCE( $dispatcher, (array) PluginHelper::getPlugin('editors', 'tinymce') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!wV!V!$editors/tinymce/forms/setoptions.xmlnu[
    PK!_;OMM7editors/tinymce/src/PluginTraits/ActiveSiteTemplate.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\PluginTraits; use Joomla\CMS\Language\Text; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Gets the active Site template style. * * @since 4.1.0 */ trait ActiveSiteTemplate { /** * Helper function to get the active Site template style. * * @return object * * @since 4.1.0 */ protected function getActiveSiteTemplate() { $db = $this->getDatabase(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__template_styles')) ->where( [ $db->quoteName('client_id') . ' = 0', $db->quoteName('home') . ' = ' . $db->quote('1'), ] ); $db->setQuery($query); try { return $db->loadObject(); } catch (\RuntimeException $e) { $this->getApplication()->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); return new \stdClass(); } } } PK!g4E2editors/tinymce/src/PluginTraits/GlobalFilters.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\PluginTraits; use Joomla\CMS\Access\Access; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Filter\InputFilter; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Handles the Joomla filters for the TinyMCE editor. * * @since 4.1.0 */ trait GlobalFilters { /** * Get the global text filters to arbitrary text as per settings for current user groups * @param User $user The user object * * @return InputFilter * * @since 4.1.0 */ protected static function getGlobalFilters($user) { // Filter settings $config = ComponentHelper::getParams('com_config'); $userGroups = Access::getGroupsByUser($user->get('id')); $filters = $config->get('filters'); $forbiddenListTags = []; $forbiddenListAttributes = []; $customListTags = []; $customListAttributes = []; $allowedListTags = []; $allowedListAttributes = []; $allowedList = false; $forbiddenList = false; $customList = false; $unfiltered = false; /** * Cycle through each of the user groups the user is in. * Remember they are included in the public group as well. */ foreach ($userGroups as $groupId) { // May have added a group but not saved the filters. if (!isset($filters->$groupId)) { continue; } // Each group the user is in could have different filtering properties. $filterData = $filters->$groupId; $filterType = strtoupper($filterData->filter_type); if ($filterType === 'NH') { // Maximum HTML filtering. } elseif ($filterType === 'NONE') { // No HTML filtering. $unfiltered = true; } else { /** * Forbidden or allowed lists. * Preprocess the tags and attributes. */ $tags = explode(',', $filterData->filter_tags); $attributes = explode(',', $filterData->filter_attributes); $tempTags = []; $tempAttributes = []; foreach ($tags as $tag) { $tag = trim($tag); if ($tag) { $tempTags[] = $tag; } } foreach ($attributes as $attribute) { $attribute = trim($attribute); if ($attribute) { $tempAttributes[] = $attribute; } } /** * Collect the list of forbidden or allowed tags and attributes. * Each list is cumulative. * "BL" is deprecated in Joomla! 4, will be removed in Joomla! 5 */ if (in_array($filterType, ['BL', 'FL'])) { $forbiddenList = true; $forbiddenListTags = array_merge($forbiddenListTags, $tempTags); $forbiddenListAttributes = array_merge($forbiddenListAttributes, $tempAttributes); } elseif (in_array($filterType, ['CBL', 'CFL'])) { // "CBL" is deprecated in Joomla! 4, will be removed in Joomla! 5 // Only set to true if Tags or Attributes were added if ($tempTags || $tempAttributes) { $customList = true; $customListTags = array_merge($customListTags, $tempTags); $customListAttributes = array_merge($customListAttributes, $tempAttributes); } } elseif (in_array($filterType, ['WL', 'AL'])) { // "WL" is deprecated in Joomla! 4, will be removed in Joomla! 5 $allowedList = true; $allowedListTags = array_merge($allowedListTags, $tempTags); $allowedListAttributes = array_merge($allowedListAttributes, $tempAttributes); } } } // Remove duplicates before processing (because the forbidden list uses both sets of arrays). $forbiddenListTags = array_unique($forbiddenListTags); $forbiddenListAttributes = array_unique($forbiddenListAttributes); $customListTags = array_unique($customListTags); $customListAttributes = array_unique($customListAttributes); $allowedListTags = array_unique($allowedListTags); $allowedListAttributes = array_unique($allowedListAttributes); // Unfiltered assumes first priority. if ($unfiltered) { // Dont apply filtering. return false; } else { // Custom forbidden list precedes Default forbidden list. if ($customList) { $filter = InputFilter::getInstance([], [], 1, 1); // Override filter's default forbidden tags and attributes if ($customListTags) { $filter->blockedTags = $customListTags; } if ($customListAttributes) { $filter->blockedAttributes = $customListAttributes; } } elseif ($forbiddenList) { // Forbidden list takes second precedence. // Remove the allowed tags and attributes from the forbidden list. $forbiddenListTags = array_diff($forbiddenListTags, $allowedListTags); $forbiddenListAttributes = array_diff($forbiddenListAttributes, $allowedListAttributes); $filter = InputFilter::getInstance($forbiddenListTags, $forbiddenListAttributes, 1, 1); // Remove allowed tags from filter's default forbidden list if ($allowedListTags) { $filter->blockedTags = array_diff($filter->blockedTags, $allowedListTags); } // Remove allowed attributes from filter's default forbidden list if ($allowedListAttributes) { $filter->blockedAttributes = array_diff($filter->blockedAttributes, $allowedListAttributes); } } elseif ($allowedList) { // Allowed list take third precedence. // Turn off XSS auto clean $filter = InputFilter::getInstance($allowedListTags, $allowedListAttributes, 0, 0, 0); } else { // No HTML takes last place. $filter = InputFilter::getInstance(); } return $filter; } } } PK!5y y 3editors/tinymce/src/PluginTraits/ToolbarPresets.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\PluginTraits; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * The ToolbarPresets trait holds the default presets for the toolbar. * * @since 4.1.0 */ trait ToolbarPresets { /** * Return toolbar presets * * @return array * * @since 4.1.0 */ public static function getToolbarPreset() { return [ 'simple' => [ 'menu' => [], 'toolbar1' => [ 'bold', 'underline', 'strikethrough', '|', 'undo', 'redo', '|', 'bullist', 'numlist', '|', 'pastetext', 'jxtdbuttons', ], 'toolbar2' => [], ], 'medium' => [ 'menu' => ['edit', 'insert', 'view', 'format', 'table', 'tools', 'help'], 'toolbar1' => [ 'bold', 'italic', 'underline', 'strikethrough', '|', 'alignleft', 'aligncenter', 'alignright', 'alignjustify', '|', 'formatselect', '|', 'bullist', 'numlist', '|', 'outdent', 'indent', '|', 'undo', 'redo', '|', 'link', 'unlink', 'anchor', 'code', '|', 'hr', 'table', '|', 'subscript', 'superscript', '|', 'charmap', 'pastetext', 'preview', 'jxtdbuttons', ], 'toolbar2' => [], ], 'advanced' => [ 'menu' => ['edit', 'insert', 'view', 'format', 'table', 'tools', 'help'], 'toolbar1' => [ 'bold', 'italic', 'underline', 'strikethrough', '|', 'alignleft', 'aligncenter', 'alignright', 'alignjustify', '|', 'lineheight', '|', 'styleselect', '|', 'formatselect', 'fontselect', 'fontsizeselect', '|', 'searchreplace', '|', 'bullist', 'numlist', '|', 'outdent', 'indent', '|', 'undo', 'redo', '|', 'link', 'unlink', 'anchor', 'image', '|', 'code', '|', 'forecolor', 'backcolor', '|', 'fullscreen', '|', 'table', '|', 'subscript', 'superscript', '|', 'charmap', 'emoticons', 'media', 'hr', 'ltr', 'rtl', '|', 'cut', 'copy', 'paste', 'pastetext', '|', 'visualchars', 'visualblocks', 'nonbreaking', 'blockquote', 'template', '|', 'print', 'preview', 'codesample', 'insertdatetime', 'removeformat', 'jxtdbuttons', 'language', ], 'toolbar2' => [], ], ]; } } PK! 1Z1Z1editors/tinymce/src/PluginTraits/DisplayTrait.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\PluginTraits; use Joomla\CMS\Filesystem\Folder; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Session\Session; use Joomla\CMS\Uri\Uri; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Handles the onDisplay event for the TinyMCE editor. * * @since 4.1.0 */ trait DisplayTrait { use GlobalFilters; use KnownButtons; use ResolveFiles; use ToolbarPresets; use XTDButtons; /** * Display the editor area. * * @param string $name The name of the editor area. * @param string $content The content of the field. * @param string $width The width of the editor area. * @param string $height The height of the editor area. * @param int $col The number of columns for the editor area. * @param int $row The number of rows for the editor area. * @param boolean $buttons True and the editor buttons will be displayed. * @param string $id An optional ID for the textarea. If not supplied the name is used. * @param string $asset The object asset * @param object $author The author. * @param array $params Associative array of editor parameters. * * @return string */ public function onDisplay( $name, $content, $width, $height, $col, $row, $buttons = true, $id = null, $asset = null, $author = null, $params = [] ) { $id = empty($id) ? $name : $id; $user = $this->getApplication()->getIdentity(); $language = $this->getApplication()->getLanguage(); $doc = $this->getApplication()->getDocument(); $id = preg_replace('/(\s|[^A-Za-z0-9_])+/', '_', $id); $nameGroup = explode('[', preg_replace('/\[\]|\]/', '', $name)); $fieldName = end($nameGroup); $scriptOptions = []; $externalPlugins = []; $options = $doc->getScriptOptions('plg_editor_tinymce'); $theme = 'silver'; // Data object for the layout $textarea = new \stdClass(); $textarea->name = $name; $textarea->id = $id; $textarea->class = 'mce_editable joomla-editor-tinymce'; $textarea->cols = $col; $textarea->rows = $row; $textarea->width = is_numeric($width) ? $width . 'px' : $width; $textarea->height = is_numeric($height) ? $height . 'px' : $height; $textarea->content = $content; $textarea->readonly = !empty($params['readonly']); // Render Editor markup $editor = '
    '; $editor .= LayoutHelper::render('joomla.tinymce.textarea', $textarea); $editor .= !$this->getApplication()->client->mobile ? LayoutHelper::render('joomla.tinymce.togglebutton') : ''; $editor .= '
    '; // Prepare the instance specific options if (empty($options['tinyMCE'][$fieldName])) { $options['tinyMCE'][$fieldName] = []; } // Width and height if ($width && empty($options['tinyMCE'][$fieldName]['width'])) { $options['tinyMCE'][$fieldName]['width'] = $width; } if ($height && empty($options['tinyMCE'][$fieldName]['height'])) { $options['tinyMCE'][$fieldName]['height'] = $height; } // Set editor to readonly mode if (!empty($params['readonly'])) { $options['tinyMCE'][$fieldName]['readonly'] = 1; } // The ext-buttons if (empty($options['tinyMCE'][$fieldName]['joomlaExtButtons'])) { $btns = $this->tinyButtons($id, $buttons); $options['tinyMCE'][$fieldName]['joomlaMergeDefaults'] = true; $options['tinyMCE'][$fieldName]['joomlaExtButtons'] = $btns; } $doc->addScriptOptions('plg_editor_tinymce', $options, false); // Setup Default (common) options for the Editor script // Check whether we already have them if (!empty($options['tinyMCE']['default'])) { return $editor; } $ugroups = array_combine($user->getAuthorisedGroups(), $user->getAuthorisedGroups()); // Prepare the parameters $levelParams = new Registry(); $extraOptions = new \stdClass(); $toolbarParams = new \stdClass(); $extraOptionsAll = (array) $this->params->get('configuration.setoptions', []); $toolbarParamsAll = (array) $this->params->get('configuration.toolbars', []); // Sort the array in reverse, so the items with lowest access level goes first krsort($extraOptionsAll); // Get configuration depend from User group foreach ($extraOptionsAll as $set => $val) { $val = (object) $val; $val->access = empty($val->access) ? [] : $val->access; // Check whether User in one of allowed group foreach ($val->access as $group) { if (isset($ugroups[$group])) { $extraOptions = $val; $toolbarParams = (object) $toolbarParamsAll[$set]; } } } // load external plugins if (isset($extraOptions->external_plugins) && $extraOptions->external_plugins) { foreach (json_decode(json_encode($extraOptions->external_plugins), true) as $external) { // get the path for readability $path = $external['path']; // if we have a name and path, add it to the list if ($external['name'] != '' && $path != '') { $externalPlugins[$external['name']] = substr($path, 0, 1) == '/' ? Uri::root() . substr($path, 1) : $path; } } } // Merge the params $levelParams->loadObject($toolbarParams); $levelParams->loadObject($extraOptions); // Set the selected skin $skin = $levelParams->get($this->getApplication()->isClient('administrator') ? 'skin_admin' : 'skin', 'oxide'); // Check that selected skin exists. $skin = Folder::exists(JPATH_ROOT . '/media/vendor/tinymce/skins/ui/' . $skin) ? $skin : 'oxide'; if (!$levelParams->get('lang_mode', 1)) { // Admin selected language $langPrefix = $levelParams->get('lang_code', 'en'); } else { // Reflect the current language if (file_exists(JPATH_ROOT . '/media/vendor/tinymce/langs/' . $language->getTag() . '.js')) { $langPrefix = $language->getTag(); } elseif (file_exists(JPATH_ROOT . '/media/vendor/tinymce/langs/' . substr($language->getTag(), 0, strpos($language->getTag(), '-')) . '.js')) { $langPrefix = substr($language->getTag(), 0, strpos($language->getTag(), '-')); } else { $langPrefix = 'en'; } } $use_content_css = $levelParams->get('content_css', 1); $content_css_custom = $levelParams->get('content_css_custom', ''); $content_css = null; // Loading of css file for 'styles' dropdown if ($content_css_custom) { /** * If URL, just pass it to $content_css * else, assume it is a file name in the current template folder */ $content_css = strpos($content_css_custom, 'http') !== false ? $content_css_custom : $this->includeRelativeFiles('css', $content_css_custom); } else { // Process when use_content_css is Yes and no custom file given $content_css = $use_content_css ? $this->includeRelativeFiles('css', 'editor' . (JDEBUG ? '' : '.min') . '.css') : $content_css; } $ignore_filter = false; // Text filtering if ($levelParams->get('use_config_textfilters', 0)) { // Use filters from com_config $filter = static::getGlobalFilters($user); $ignore_filter = $filter === false; $blockedTags = !empty($filter->blockedTags) ? $filter->blockedTags : []; $blockedAttributes = !empty($filter->blockedAttributes) ? $filter->blockedAttributes : []; $tagArray = !empty($filter->tagsArray) ? $filter->tagsArray : []; $attrArray = !empty($filter->attrArray) ? $filter->attrArray : []; $invalid_elements = implode(',', array_merge($blockedTags, $blockedAttributes, $tagArray, $attrArray)); // Valid elements are all entries listed as allowed in com_config, which are now missing in the filter blocked properties $default_filter = InputFilter::getInstance(); $valid_elements = implode(',', array_diff($default_filter->blockedTags, $blockedTags)); $extended_elements = ''; } else { // Use filters from TinyMCE params $invalid_elements = trim($levelParams->get('invalid_elements', 'script,applet,iframe')); $extended_elements = trim($levelParams->get('extended_elements', '')); $valid_elements = trim($levelParams->get('valid_elements', '')); } // The param is true for vertical resizing only, false or both $resizing = (bool) $levelParams->get('resizing', true); $resize_horizontal = (bool) $levelParams->get('resize_horizontal', true); if ($resizing && $resize_horizontal) { $resizing = 'both'; } // Set of always available plugins $plugins = [ 'autolink', 'lists', 'importcss', 'quickbars', ]; // Allowed elements $elements = [ 'hr[id|title|alt|class|width|size|noshade]', ]; $elements = $extended_elements ? array_merge($elements, explode(',', $extended_elements)) : $elements; // Prepare the toolbar/menubar $knownButtons = static::getKnownButtons(); // Check if there no value at all if (!$levelParams->get('menu') && !$levelParams->get('toolbar1') && !$levelParams->get('toolbar2')) { // Get from preset $presets = static::getToolbarPreset(); /** * Predefine group as: * Set 0: for Administrator, Editor, Super Users (4,7,8) * Set 1: for Registered, Manager (2,6), all else are public */ switch (true) { case isset($ugroups[4]) || isset($ugroups[7]) || isset($ugroups[8]): $preset = $presets['advanced']; break; case isset($ugroups[2]) || isset($ugroups[6]): $preset = $presets['medium']; break; default: $preset = $presets['simple']; } $levelParams->loadArray($preset); } $menubar = (array) $levelParams->get('menu', []); $toolbar1 = (array) $levelParams->get('toolbar1', []); $toolbar2 = (array) $levelParams->get('toolbar2', []); // Make an easy way to check which button is enabled $allButtons = array_merge($toolbar1, $toolbar2); $allButtons = array_combine($allButtons, $allButtons); // Check for button-specific plugins foreach ($allButtons as $btnName) { if (!empty($knownButtons[$btnName]['plugin'])) { $plugins[] = $knownButtons[$btnName]['plugin']; } } // Template $templates = []; if (!empty($allButtons['template'])) { // Do we have a custom content_template_path $template_path = $levelParams->get('content_template_path'); $template_path = $template_path ? '/templates/' . $template_path : '/media/vendor/tinymce/templates'; $filepaths = Folder::exists(JPATH_ROOT . $template_path) ? Folder::files(JPATH_ROOT . $template_path, '\.(html|txt)$', false, true) : []; foreach ($filepaths as $filepath) { $fileinfo = pathinfo($filepath); $filename = $fileinfo['filename']; $full_filename = $fileinfo['basename']; if ($filename === 'index') { continue; } $title = $filename; $title_upper = strtoupper($filename); $description = ' '; if ($language->hasKey('PLG_TINY_TEMPLATE_' . $title_upper . '_TITLE')) { $title = Text::_('PLG_TINY_TEMPLATE_' . $title_upper . '_TITLE'); } if ($language->hasKey('PLG_TINY_TEMPLATE_' . $title_upper . '_DESC')) { $description = Text::_('PLG_TINY_TEMPLATE_' . $title_upper . '_DESC'); } $templates[] = [ 'title' => $title, 'description' => $description, 'url' => Uri::root(true) . $template_path . '/' . $full_filename, ]; } } // Check for extra plugins, from the setoptions form foreach (['wordcount' => 1, 'advlist' => 1, 'autosave' => 1, 'textpattern' => 0] as $pName => $def) { if ($levelParams->get($pName, $def)) { $plugins[] = $pName; } } // Use CodeMirror in the code view instead of plain text to provide syntax highlighting if ($levelParams->get('sourcecode', 1)) { $externalPlugins['highlightPlus'] = HTMLHelper::_('script', 'plg_editors_tinymce/plugins/highlighter/plugin-es5.min.js', ['relative' => true, 'version' => 'auto', 'pathOnly' => true]); } $dragdrop = $levelParams->get('drag_drop', 1); if ($dragdrop && $user->authorise('core.create', 'com_media')) { $externalPlugins['jdragndrop'] = HTMLHelper::_('script', 'plg_editors_tinymce/plugins/dragdrop/plugin.min.js', ['relative' => true, 'version' => 'auto', 'pathOnly' => true]); $uploadUrl = Uri::base(false) . 'index.php?option=com_media&format=json&url=1&task=api.files'; $uploadUrl = $this->getApplication()->isClient('site') ? htmlentities($uploadUrl, ENT_NOQUOTES, 'UTF-8', false) : $uploadUrl; Text::script('PLG_TINY_ERR_UNSUPPORTEDBROWSER'); Text::script('ERROR'); Text::script('PLG_TINY_DND_ADDITIONALDATA'); Text::script('PLG_TINY_DND_ALTTEXT'); Text::script('PLG_TINY_DND_LAZYLOADED'); Text::script('PLG_TINY_DND_EMPTY_ALT'); $scriptOptions['parentUploadFolder'] = $levelParams->get('path', ''); $scriptOptions['csrfToken'] = Session::getFormToken(); $scriptOptions['uploadUri'] = $uploadUrl; // @TODO have a way to select the adapter, similar to $levelParams->get('path', ''); $scriptOptions['comMediaAdapter'] = 'local-images:'; } // Convert pt to px in dropdown $scriptOptions['fontsize_formats'] = '8px 10px 12px 14px 18px 24px 36px'; // select the languages for the "language of parts" menu if (isset($extraOptions->content_languages) && $extraOptions->content_languages) { foreach (json_decode(json_encode($extraOptions->content_languages), true) as $content_language) { // if we have a language name and a language code then add to the menu if ($content_language['content_language_name'] != '' && $content_language['content_language_code'] != '') { $ctemp[] = ['title' => $content_language['content_language_name'], 'code' => $content_language['content_language_code']]; } } if (isset($ctemp)) { $scriptOptions['content_langs'] = array_merge($ctemp); } } // User custom plugins and buttons $custom_plugin = trim($levelParams->get('custom_plugin', '')); $custom_button = trim($levelParams->get('custom_button', '')); if ($custom_plugin) { $plugins = array_merge($plugins, explode(strpos($custom_plugin, ',') !== false ? ',' : ' ', $custom_plugin)); } if ($custom_button) { $toolbar1 = array_merge($toolbar1, explode(strpos($custom_button, ',') !== false ? ',' : ' ', $custom_button)); } // Merge the two toolbars for backwards compatibility $toolbar = array_merge($toolbar1, $toolbar2); // Build the final options set $scriptOptions = array_merge( $scriptOptions, [ 'deprecation_warnings' => JDEBUG ? true : false, 'suffix' => JDEBUG ? '' : '.min', 'baseURL' => Uri::root(true) . '/media/vendor/tinymce', 'directionality' => $language->isRtl() ? 'rtl' : 'ltr', 'language' => $langPrefix, 'autosave_restore_when_empty' => false, 'skin' => $skin, 'theme' => $theme, 'schema' => 'html5', // Prevent cursor from getting stuck in blocks when nested or at end of document. 'end_container_on_empty_block' => true, // Toolbars 'menubar' => empty($menubar) ? false : implode(' ', array_unique($menubar)), 'toolbar' => empty($toolbar) ? null : 'jxtdbuttons ' . implode(' ', $toolbar), 'plugins' => implode(',', array_unique($plugins)), // Quickbars 'quickbars_image_toolbar' => false, 'quickbars_insert_toolbar' => false, 'quickbars_selection_toolbar' => 'bold italic underline | H2 H3 | link blockquote', // Cleanup/Output 'browser_spellcheck' => true, 'entity_encoding' => $levelParams->get('entity_encoding', 'raw'), 'verify_html' => !$ignore_filter, 'paste_as_text' => (bool) $levelParams->get('paste_as_text', false), 'valid_elements' => $valid_elements, 'extended_valid_elements' => implode(',', $elements), 'invalid_elements' => $invalid_elements, // URL 'relative_urls' => (bool) $levelParams->get('relative_urls', true), 'remove_script_host' => false, // Drag and drop Images always FALSE, reverting this allows for inlining the images 'paste_data_images' => false, // Layout 'content_css' => $content_css, 'document_base_url' => Uri::root(true) . '/', 'image_caption' => true, 'importcss_append' => true, 'height' => $this->params->get('html_height', '550px'), 'width' => $this->params->get('html_width', ''), 'elementpath' => (bool) $levelParams->get('element_path', true), 'resize' => $resizing, 'templates' => $templates, 'external_plugins' => empty($externalPlugins) ? null : $externalPlugins, 'contextmenu' => (bool) $levelParams->get('contextmenu', true) ? null : false, 'toolbar_sticky' => true, 'toolbar_mode' => $levelParams->get('toolbar_mode', 'sliding'), // Image plugin options 'a11y_advanced_options' => true, 'image_advtab' => (bool) $levelParams->get('image_advtab', false), 'image_title' => true, // Drag and drop specific 'dndEnabled' => $dragdrop, // Disable TinyMCE Branding 'branding' => false, // Specify the attributes to be used when previewing a style. This prevents white text on a white background making the preview invisible. 'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform background-color border border-radius outline text-shadow', ] ); if ($levelParams->get('newlines')) { // Break $scriptOptions['force_br_newlines'] = true; $scriptOptions['forced_root_block'] = ''; } else { // Paragraph $scriptOptions['force_br_newlines'] = false; $scriptOptions['forced_root_block'] = 'p'; } $scriptOptions['rel_list'] = [ ['title' => 'None', 'value' => ''], ['title' => 'Alternate', 'value' => 'alternate'], ['title' => 'Author', 'value' => 'author'], ['title' => 'Bookmark', 'value' => 'bookmark'], ['title' => 'Help', 'value' => 'help'], ['title' => 'License', 'value' => 'license'], ['title' => 'Lightbox', 'value' => 'lightbox'], ['title' => 'Next', 'value' => 'next'], ['title' => 'No Follow', 'value' => 'nofollow'], ['title' => 'No Referrer', 'value' => 'noreferrer'], ['title' => 'Prefetch', 'value' => 'prefetch'], ['title' => 'Prev', 'value' => 'prev'], ['title' => 'Search', 'value' => 'search'], ['title' => 'Tag', 'value' => 'tag'], ]; $scriptOptions['style_formats'] = [ [ 'title' => Text::_('PLG_TINY_MENU_CONTAINER'), 'items' => [ ['title' => 'article', 'block' => 'article', 'wrapper' => true, 'merge_siblings' => false], ['title' => 'aside', 'block' => 'aside', 'wrapper' => true, 'merge_siblings' => false], ['title' => 'section', 'block' => 'section', 'wrapper' => true, 'merge_siblings' => false], ], ], ]; $scriptOptions['style_formats_merge'] = true; $options['tinyMCE']['default'] = $scriptOptions; $doc->addScriptOptions('plg_editor_tinymce', $options); return $editor; } } PK!p /editors/tinymce/src/PluginTraits/XTDButtons.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\PluginTraits; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Uri\Uri; use Joomla\Event\Event; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Resolves the XTD Buttons for the current TinyMCE editor. * * @since 4.1.0 */ trait XTDButtons { /** * Get the XTD buttons and render them inside tinyMCE * * @param string $name the id of the editor field * @param string $excluded the buttons that should be hidden * * @return array|void * * @since 4.1.0 */ private function tinyButtons($name, $excluded) { // Get the available buttons $buttonsEvent = new Event( 'getButtons', [ 'editor' => $name, 'buttons' => $excluded, ] ); $buttonsResult = $this->getDispatcher()->dispatch('getButtons', $buttonsEvent); $buttons = $buttonsResult['result']; if (is_array($buttons) || (is_bool($buttons) && $buttons)) { Text::script('PLG_TINY_CORE_BUTTONS'); // Init the arrays for the buttons $btnsNames = []; // Build the script foreach ($buttons as $i => $button) { $button->id = $name . '_' . $button->name . '_modal'; echo LayoutHelper::render('joomla.editors.buttons.modal', $button); if ($button->get('name')) { $coreButton = []; $coreButton['name'] = $button->get('text'); $coreButton['href'] = $button->get('link') !== '#' ? Uri::base() . $button->get('link') : null; $coreButton['id'] = $name . '_' . $button->name; $coreButton['icon'] = $button->get('icon'); $coreButton['click'] = $button->get('onclick') ?: null; $coreButton['iconSVG'] = $button->get('iconSVG'); // The array with the toolbar buttons $btnsNames[] = $coreButton; } } sort($btnsNames); return ['names' => $btnsNames]; } } } PK!~|1editors/tinymce/src/PluginTraits/KnownButtons.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\PluginTraits; use Joomla\CMS\Language\Text; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Returns a list of known TinyMCE buttons. * * @since 4.1.0 */ trait KnownButtons { /** * Return list of known TinyMCE buttons * @see https://www.tiny.cloud/docs/demo/full-featured/ * @see https://www.tiny.cloud/apps/#core-plugins * * @return array * * @since 4.1.0 */ public static function getKnownButtons() { return [ // General buttons '|' => ['label' => Text::_('PLG_TINY_TOOLBAR_BUTTON_SEPARATOR'), 'text' => '|'], 'undo' => ['label' => 'Undo'], 'redo' => ['label' => 'Redo'], 'bold' => ['label' => 'Bold'], 'italic' => ['label' => 'Italic'], 'underline' => ['label' => 'Underline'], 'strikethrough' => ['label' => 'Strikethrough'], 'styleselect' => ['label' => Text::_('PLG_TINY_TOOLBAR_BUTTON_STYLESELECT'), 'text' => 'Formats'], 'formatselect' => ['label' => Text::_('PLG_TINY_TOOLBAR_BUTTON_FORMATSELECT'), 'text' => 'Paragraph'], 'fontselect' => ['label' => Text::_('PLG_TINY_TOOLBAR_BUTTON_FONTSELECT'), 'text' => 'Font Family'], 'fontsizeselect' => ['label' => Text::_('PLG_TINY_TOOLBAR_BUTTON_FONTSIZESELECT'), 'text' => 'Font Sizes'], 'alignleft' => ['label' => 'Align left'], 'aligncenter' => ['label' => 'Align center'], 'alignright' => ['label' => 'Align right'], 'alignjustify' => ['label' => 'Justify'], 'lineheight' => ['label' => 'Line height'], 'outdent' => ['label' => 'Decrease indent'], 'indent' => ['label' => 'Increase indent'], 'forecolor' => ['label' => 'Text colour'], 'backcolor' => ['label' => 'Background text colour'], 'bullist' => ['label' => 'Bullet list'], 'numlist' => ['label' => 'Numbered list'], 'link' => ['label' => 'Insert/edit link', 'plugin' => 'link'], 'unlink' => ['label' => 'Remove link', 'plugin' => 'link'], 'subscript' => ['label' => 'Subscript'], 'superscript' => ['label' => 'Superscript'], 'blockquote' => ['label' => 'Blockquote'], 'cut' => ['label' => 'Cut'], 'copy' => ['label' => 'Copy'], 'paste' => ['label' => 'Paste', 'plugin' => 'paste'], 'pastetext' => ['label' => 'Paste as text', 'plugin' => 'paste'], 'removeformat' => ['label' => 'Clear formatting'], 'language' => ['label' => 'Language'], // Buttons from the plugins 'anchor' => ['label' => 'Anchor', 'plugin' => 'anchor'], 'hr' => ['label' => 'Horizontal line', 'plugin' => 'hr'], 'ltr' => ['label' => 'Left to right', 'plugin' => 'directionality'], 'rtl' => ['label' => 'Right to left', 'plugin' => 'directionality'], 'code' => ['label' => 'Source code', 'plugin' => 'code'], 'codesample' => ['label' => 'Insert/Edit code sample', 'plugin' => 'codesample'], 'table' => ['label' => 'Table', 'plugin' => 'table'], 'charmap' => ['label' => 'Special character', 'plugin' => 'charmap'], 'visualchars' => ['label' => 'Show invisible characters', 'plugin' => 'visualchars'], 'visualblocks' => ['label' => 'Show blocks', 'plugin' => 'visualblocks'], 'nonbreaking' => ['label' => 'Nonbreaking space', 'plugin' => 'nonbreaking'], 'emoticons' => ['label' => 'Emoticons', 'plugin' => 'emoticons'], 'media' => ['label' => 'Insert/edit video', 'plugin' => 'media'], 'image' => ['label' => 'Insert/edit image', 'plugin' => 'image'], 'pagebreak' => ['label' => 'Page break', 'plugin' => 'pagebreak'], 'print' => ['label' => 'Print', 'plugin' => 'print'], 'preview' => ['label' => 'Preview', 'plugin' => 'preview'], 'fullscreen' => ['label' => 'Fullscreen', 'plugin' => 'fullscreen'], 'template' => ['label' => 'Insert template', 'plugin' => 'template'], 'searchreplace' => ['label' => 'Find and replace', 'plugin' => 'searchreplace'], 'insertdatetime' => ['label' => 'Insert date/time', 'plugin' => 'insertdatetime'], 'help' => ['label' => 'Help', 'plugin' => 'help'], ]; } } PK!Mq7 1editors/tinymce/src/PluginTraits/ResolveFiles.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\PluginTraits; use Joomla\CMS\Filesystem\File; use Joomla\CMS\Uri\Uri; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Handles the editor.css files. * * @since 4.1.0 */ trait ResolveFiles { use ActiveSiteTemplate; /** * Compute the file paths to be included * * @param string $folder Folder name to search in (i.e. images, css, js). * @param string $file Path to file. * * @return array files to be included. * * @since 4.1.0 */ protected function includeRelativeFiles($folder, $file) { $fallback = Uri::root(true) . '/media/system/css/editor' . (JDEBUG ? '' : '.min') . '.css'; $template = $this->getActiveSiteTemplate(); if (!(array) $template) { return $fallback; } // Extract extension and strip the file $file = File::stripExt($file) . '.' . File::getExt($file); $templaPath = $template->inheritable || (isset($template->parent) && $template->parent !== '') ? JPATH_ROOT . '/media/templates/site' : JPATH_ROOT . '/templates'; if (isset($template->parent) && $template->parent !== '') { $found = static::resolveFileUrl("$templaPath/$template->template/$folder/$file"); if (empty($found)) { $found = static::resolveFileUrl("$templaPath/$template->parent/$folder/$file"); } } else { $found = static::resolveFileUrl("$templaPath/$template->template/$folder/$file"); } if (empty($found)) { return $fallback; } return $found; } /** * Method that searches if file exists in given path and returns the relative path. * If a minified version exists it will be preferred. * * @param string $path The actual path of the file * * @return string The relative path of the file * * @since 4.1.0 */ protected static function resolveFileUrl($path = '') { $position = strrpos($path, '.min.'); // We are handling a name.min.ext file: if ($position !== false) { $minifiedPath = $path; $nonMinifiedPath = substr_replace($path, '', $position, 4); if (JDEBUG && is_file($nonMinifiedPath)) { return Uri::root(true) . str_replace(JPATH_ROOT, '', $nonMinifiedPath); } if (is_file($minifiedPath)) { return Uri::root(true) . str_replace(JPATH_ROOT, '', $minifiedPath); } if (is_file($nonMinifiedPath)) { return Uri::root(true) . str_replace(JPATH_ROOT, '', $nonMinifiedPath); } return ''; } $minifiedPath = pathinfo($path, PATHINFO_DIRNAME) . '/' . pathinfo($path, PATHINFO_FILENAME) . '.min.' . pathinfo($path, PATHINFO_EXTENSION); if (JDEBUG && is_file($path)) { return Uri::root(true) . str_replace(JPATH_ROOT, '', $path); } if (is_file($minifiedPath)) { return Uri::root(true) . str_replace(JPATH_ROOT, '', $minifiedPath); } return ''; } } PK!P )editors/tinymce/src/Extension/TinyMCE.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Database\DatabaseAwareTrait; use Joomla\Plugin\Editors\TinyMCE\PluginTraits\DisplayTrait; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * TinyMCE Editor Plugin * * @since 1.5 */ final class TinyMCE extends CMSPlugin { use DisplayTrait; use DatabaseAwareTrait; /** * Load the language file on instantiation. * * @var boolean * @since 3.1 */ protected $autoloadLanguage = true; /** * Initializes the Editor. * * @return void * * @since 1.5 */ public function onInit() { } } PK!'  -editors/tinymce/src/Field/UploaddirsField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\Field; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Form\Field\FolderlistField; use Joomla\CMS\HTML\HTMLHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Generates the list of directories available for drag and drop upload. * * @package Joomla.Plugin * @subpackage Editors.tinymce * @since 3.7.0 */ class UploaddirsField extends FolderlistField { protected $type = 'uploaddirs'; /** * Method to attach a JForm object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see \Joomla\CMS\Form\FormField::setup() * @since 3.7.0 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $return = parent::setup($element, $value, $group); // Get the path in which to search for file options. $this->directory = JPATH_ROOT . '/' . ComponentHelper::getParams('com_media')->get('image_path'); $this->recursive = true; $this->hideDefault = true; return $return; } /** * Method to get the directories options. * * @return array The dirs option objects. * * @since 3.7.0 */ public function getOptions() { return parent::getOptions(); } /** * Method to get the field input markup for the list of directories. * * @return string The field input markup. * * @since 3.7.0 */ protected function getInput() { $html = []; // Get the field options. $options = (array) $this->getOptions(); // Reset the non selected value to null if ($options[0]->value === '-1') { $options[0]->value = ''; } // Create a regular list. $html[] = HTMLHelper::_('select.genericlist', $options, $this->name, 'class="form-select"', 'value', 'text', $this->value, $this->id); return implode($html); } } PK!1editors/tinymce/src/Field/TinymcebuilderField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\Field; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormField; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Plugin\Editors\TinyMCE\Extension\TinyMCE; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Form Field class for the TinyMCE editor. * * @package Joomla.Plugin * @subpackage Editors.tinymce * @since 3.7.0 */ class TinymcebuilderField extends FormField { /** * The form field type. * * @var string * @since 3.7.0 */ protected $type = 'tinymcebuilder'; /** * Name of the layout being used to render the field * * @var string * @since 3.7.0 */ protected $layout = 'plugins.editors.tinymce.field.tinymcebuilder'; /** * The prepared layout data * * @var array * @since 3.7.0 */ protected $layoutData = []; /** * Method to get the data to be passed to the layout for rendering. * * @return array * * @since 3.7.0 */ protected function getLayoutData() { if (!empty($this->layoutData)) { return $this->layoutData; } $data = parent::getLayoutData(); $paramsAll = (object) $this->form->getValue('params'); $setsAmount = empty($paramsAll->sets_amount) ? 3 : $paramsAll->sets_amount; if (empty($data['value'])) { $data['value'] = []; } $menus = [ 'edit' => ['label' => 'Edit'], 'insert' => ['label' => 'Insert'], 'view' => ['label' => 'View'], 'format' => ['label' => 'Format'], 'table' => ['label' => 'Table'], 'tools' => ['label' => 'Tools'], 'help' => ['label' => 'Help'], ]; $data['menus'] = $menus; $data['menubarSource'] = array_keys($menus); $data['buttons'] = TinyMCE::getKnownButtons(); $data['buttonsSource'] = array_keys($data['buttons']); $data['toolbarPreset'] = TinyMCE::getToolbarPreset(); $data['setsAmount'] = $setsAmount; // Get array of sets names for ($i = 0; $i < $setsAmount; $i++) { $data['setsNames'][$i] = Text::sprintf('PLG_TINY_SET_TITLE', $i); } // Prepare the forms for each set $setsForms = []; $formsource = JPATH_PLUGINS . '/editors/tinymce/forms/setoptions.xml'; // Preload an old params for B/C $setParams = new \stdClass(); if (!empty($paramsAll->html_width) && empty($paramsAll->configuration['setoptions'])) { $plugin = PluginHelper::getPlugin('editors', 'tinymce'); Factory::getApplication()->enqueueMessage(Text::sprintf('PLG_TINY_LEGACY_WARNING', '#'), 'warning'); if (\is_object($plugin) && !empty($plugin->params)) { $setParams = (object) json_decode($plugin->params); } } // Collect already used groups $groupsInUse = []; // Prepare the Set forms, for the set options foreach (array_keys($data['setsNames']) as $num) { $formname = 'set.form.' . $num; $control = $this->name . '[setoptions][' . $num . ']'; $setsForms[$num] = Form::getInstance($formname, $formsource, ['control' => $control]); // Check whether we already have saved values or it first time or even old params if (empty($this->value['setoptions'][$num])) { $formValues = $setParams; /* * Predefine group: * Set 0: for Administrator, Editor, Super Users (4,7,8) * Set 1: for Registered, Manager (2,6), all else are public */ $formValues->access = !$num ? [4, 7, 8] : ($num === 1 ? [2, 6] : []); // Assign Public to the new Set, but only when it not in use already if (empty($formValues->access) && !\in_array(1, $groupsInUse)) { $formValues->access = [1]; } } else { $formValues = (object) $this->value['setoptions'][$num]; } // Collect already used groups if (!empty($formValues->access)) { $groupsInUse = array_merge($groupsInUse, $formValues->access); } // Bind the values $setsForms[$num]->bind($formValues); } $data['setsForms'] = $setsForms; // Check for TinyMCE language file $language = Factory::getLanguage(); $languageFile1 = 'media/vendor/tinymce/langs/' . $language->getTag() . (JDEBUG ? '.js' : '.min.js'); $languageFile2 = 'media/vendor/tinymce/langs/' . substr($language->getTag(), 0, strpos($language->getTag(), '-')) . (JDEBUG ? '.js' : '.min.js'); $data['languageFile'] = ''; if (file_exists(JPATH_ROOT . '/' . $languageFile1)) { $data['languageFile'] = $languageFile1; } elseif (file_exists(JPATH_ROOT . '/' . $languageFile2)) { $data['languageFile'] = $languageFile2; } $this->layoutData = $data; return $data; } } PK!v v 0editors/tinymce/src/Field/TemplateslistField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\TinyMCE\Field; use Joomla\CMS\Form\Field\FolderlistField; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Generates the list of directories available for template snippets. * * @since 4.1.0 */ class TemplatesListField extends FolderlistField { protected $type = 'templatesList'; /** * Method to attach a JForm object to the field. * * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for the field. * For example if the field has name="foo" and the group value is set to "bar" then the * full field name would end up being "bar[foo]". * * @return boolean True on success. * * @see \Joomla\CMS\Form\FormField::setup() * @since 4.1.0 */ public function setup(\SimpleXMLElement $element, $value, $group = null) { $return = parent::setup($element, $value, $group); // Set some defaults. $this->recursive = true; $this->hideDefault = true; $this->exclude = 'system'; $this->hideNone = true; return $return; } /** * Method to get the directories options. * * @return array The dirs option objects. * * @since 4.1.0 */ public function getOptions() { $def = new \stdClass(); $def->value = ''; $def->text = Text::_('JOPTION_DO_NOT_USE'); $options = [0 => $def]; $directories = [JPATH_ROOT . '/templates', JPATH_ROOT . '/media/templates/site']; foreach ($directories as $directory) { $this->directory = $directory; $options = array_merge($options, parent::getOptions()); } return $options; } /** * Method to get the field input markup for the list of directories. * * @return string The field input markup. * * @since 4.1.0 */ protected function getInput() { return HTMLHelper::_( 'select.genericlist', (array) $this->getOptions(), $this->name, 'class="form-select"', 'value', 'text', $this->value, $this->id ); } } PK!o77(editors/codemirror/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Editors\CodeMirror\Extension\Codemirror; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Codemirror( $dispatcher, (array) PluginHelper::getPlugin('editors', 'codemirror') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!uWW8editors/codemirror/layouts/editors/codemirror/styles.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ // No direct access defined('_JEXEC') or die; use Joomla\CMS\Factory; $params = $displayData->params; $fontFamily = $displayData->fontFamily ?? 'monospace'; $fontSize = $params->get('fontSize', 13) . 'px;'; $lineHeight = $params->get('lineHeight', 1.2) . 'em;'; // Set the active line color. $color = $params->get('activeLineColor', '#a4c2eb'); $r = hexdec($color[1] . $color[2]); $g = hexdec($color[3] . $color[4]); $b = hexdec($color[5] . $color[6]); $activeLineColor = 'rgba(' . $r . ', ' . $g . ', ' . $b . ', .5)'; // Set the color for matched tags. $color = $params->get('highlightMatchColor', '#fa542f'); $r = hexdec($color[1] . $color[2]); $g = hexdec($color[3] . $color[4]); $b = hexdec($color[5] . $color[6]); $highlightMatchColor = 'rgba(' . $r . ', ' . $g . ', ' . $b . ', .5)'; /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */ $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); $wa->registerAndUseStyle('plg_editors_codemirror', 'plg_editors_codemirror/codemirror.css'); $wa->addInlineStyle( << * @license GNU General Public License version 2 or later; see LICENSE.txt */ // No direct access defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; $options = $displayData->options; $params = $displayData->params; $name = $displayData->name; $id = $displayData->id; $cols = $displayData->cols; $rows = $displayData->rows; $content = $displayData->content; $extJS = JDEBUG ? '.js' : '.min.js'; $modifier = $params->get('fullScreenMod', []) ? implode(' + ', $params->get('fullScreenMod', [])) . ' + ' : ''; $basePath = $displayData->basePath; $modePath = $displayData->modePath; $modPath = 'mod-path="' . Uri::root() . $modePath . $extJS . '"'; $fskeys = $params->get('fullScreenMod', []); $fskeys[] = $params->get('fullScreen', 'F10'); $fullScreenCombo = implode('-', $fskeys); $fsCombo = 'fs-combo=' . json_encode($fullScreenCombo); $option = 'options=\'' . json_encode($options) . '\''; $mediaVersion = Factory::getDocument()->getMediaVersion(); $editor = 'editor="' . ltrim(HTMLHelper::_('script', $basePath . 'lib/codemirror' . $extJS, ['version' => 'auto', 'pathOnly' => true]), '/') . '?' . $mediaVersion . '"'; $addons = 'addons="' . ltrim(HTMLHelper::_('script', $basePath . 'lib/addons' . $extJS, ['version' => 'auto', 'pathOnly' => true]), '/') . '?' . $mediaVersion . '"'; // Remove the fullscreen message and option if readonly not null. if (isset($options->readOnly)) { $fsCombo = ''; } Factory::getDocument()->getWebAssetManager() ->registerAndUseStyle('codemirror.lib.main', $basePath . 'lib/codemirror.css') ->registerAndUseStyle('codemirror.lib.addons', $basePath . 'lib/addons.css', [], [], ['codemirror.lib.main']) ->registerScript( 'webcomponent.editor-codemirror-es5', 'plg_editors_codemirror/joomla-editor-codemirror-es5.min.js', ['dependencies' => ['wcpolyfill']], ['defer' => true, 'nomodule' => true], ['wcpolyfill'] ) ->registerAndUseScript( 'webcomponent.editor-codemirror', 'plg_editors_codemirror/joomla-editor-codemirror.min.js', [], ['type' => 'module'], ['webcomponent.editor-codemirror-es5'] ); ?> > ', $content, ''; ?>

    buttons; ?> PK! P%P%!editors/codemirror/codemirror.xmlnu[ plg_editors_codemirror 5.65.15 28 March 2011 Marijn Haverbeke marijnh@gmail.com https://codemirror.net/ Copyright (C) 2014 - 2021 by Marijn Haverbeke <marijnh@gmail.com> and others MIT license: https://codemirror.net/LICENSE PLG_CODEMIRROR_XML_DESCRIPTION Joomla\Plugin\Editors\CodeMirror fonts.json layouts services src language/en-GB/plg_editors_codemirror.ini language/en-GB/plg_editors_codemirror.sys.ini
    [].forEach.call(document.getElementsByClassName('hello'), function (el) {el.innerHtml = 'Hello World';});

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam a ornare lectus, quis semper urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus interdum metus id elit rutrum sollicitudin. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam in fermentum risus, id facilisis nulla. Phasellus gravida erat sed ullamcorper accumsan. Donec blandit sem eget sem congue, a varius sapien semper.

    Integer euismod tempor convallis. Nullam porttitor et ex ac fringilla. Quisque facilisis est ac erat condimentum malesuada. Aenean commodo quam odio, tincidunt ultricies mauris suscipit et.

    • Vivamus ultrices ligula a odio lacinia pellentesque.
    • Curabitur iaculis arcu pharetra, mollis turpis id, commodo erat.
    • Etiam consequat enim quis faucibus interdum.
    • Morbi in ipsum pulvinar, eleifend lorem sit amet, euismod magna.
    • Donec consectetur lacus vitae eros euismod porta.
    ]]>
    PK!J editors/codemirror/fonts.jsonnu[{ "anonymous_pro": { "name": "Anonymous Pro", "url": "https://fonts.googleapis.com/css?family=Anonymous+Pro", "css": "'Anonymous Pro', monospace" }, "cousine": { "name": "Cousine", "url": "https://fonts.googleapis.com/css?family=Cousine", "css": "Cousine, monospace" }, "cutive_mono": { "name": "Cutive Mono", "url": "https://fonts.googleapis.com/css?family=Cutive+Mono", "css": "'Cutive Mono', monospace" }, "droid_sans_mono": { "name": "Droid Sans Mono", "url": "https://fonts.googleapis.com/css?family=Droid+Sans+Mono", "css": "'Droid Sans Mono', monospace" }, "fira_mono": { "name": "Fira Mono", "url": "https://fonts.googleapis.com/css?family=Fira+Mono", "css": "'Fira Mono', monospace" }, "ibm_plex_mono": { "name": "IBM Plex Mono", "url": "https://fonts.googleapis.com/css?family=IBM+Plex+Mono", "css": "'IBM Plex Mono', monospace;" }, "inconsolata": { "name": "Inconsolata", "url": "https://fonts.googleapis.com/css?family=Inconsolata", "css": "Inconsolata, monospace" }, "lekton": { "name": "Lekton", "url": "https://fonts.googleapis.com/css?family=Lekton", "css": "Lekton, monospace" }, "nanum_gothic_coding": { "name": "Nanum Gothic Coding", "url": "https://fonts.googleapis.com/css?family=Nanum+Gothic+Coding", "css": "'Nanum Gothic Coding', monospace" }, "nova_mono": { "name": "Nova Mono", "url": "https://fonts.googleapis.com/css?family=Nova+Mono", "css": "'Nova Mono', monospace" }, "overpass_mono": { "name": "Overpass Mono", "url": "https://fonts.googleapis.com/css?family=Overpass+Mono", "css": "'Overpass Mono', monospace" }, "oxygen_mono": { "name": "Oxygen Mono", "url": "https://fonts.googleapis.com/css?family=Oxygen+Mono", "css": "'Oxygen Mono', monospace" }, "press_start_2p": { "name": "Press Start 2P", "url": "https://fonts.googleapis.com/css?family=Press+Start+2P", "css": "'Press Start 2P', monospace" }, "pt_mono": { "name": "PT Mono", "url": "https://fonts.googleapis.com/css?family=PT+Mono", "css": "'PT Mono', monospace" }, "roboto_mono": { "name": "Roboto Mono", "url": "https://fonts.googleapis.com/css?family=Roboto+Mono", "css": "'Roboto Mono', monospace" }, "rubik_mono_one": { "name": "Rubik Mono One", "url": "https://fonts.googleapis.com/css?family=Rubik+Mono+One", "css": "'Rubik Mono One', monospace" }, "share_tech_mono": { "name": "Share Tech Mono", "url": "https://fonts.googleapis.com/css?family=Share+Tech+Mono", "css": "'Share Tech Mono', monospace" }, "source_code_pro": { "name": "Source Code Pro", "url": "https://fonts.googleapis.com/css?family=Source+Code+Pro", "css": "'Source Code Pro', monospace" }, "space_mono": { "name": "Space Mono", "url": "https://fonts.googleapis.com/css?family=Space+Mono", "css": "'Space Mono', monospace" }, "ubuntu_mono": { "name": "Ubuntu Mono", "url": "https://fonts.googleapis.com/css?family=Ubuntu+Mono", "css": "'Ubuntu Mono', monospace" }, "vt323": { "name": "VT323", "url": "https://fonts.googleapis.com/css?family=VT323", "css": "'VT323', monospace" } } PK!zj3u)u)/editors/codemirror/src/Extension/Codemirror.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\CodeMirror\Extension; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Event\Event; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * CodeMirror Editor Plugin. * * @since 1.6 */ final class Codemirror extends CMSPlugin { /** * Affects constructor behavior. If true, language files will be loaded automatically. * * @var boolean * @since 3.1.4 */ protected $autoloadLanguage = true; /** * Mapping of syntax to CodeMirror modes. * * @var array */ protected $modeAlias = []; /** * Base path for editor assets. * * @var string * * @since 4.0.0 */ protected $basePath = 'media/vendor/codemirror/'; /** * Base path for editor modes. * * @var string * * @since 4.0.0 */ protected $modePath = 'media/vendor/codemirror/mode/%N/%N'; /** * Initialises the Editor. * * @return void */ public function onInit() { static $done = false; // Do this only once. if ($done) { return; } $done = true; // Most likely need this later $doc = $this->getApplication()->getDocument(); // Codemirror shall have its own group of plugins to modify and extend its behavior PluginHelper::importPlugin('editors_codemirror'); // At this point, params can be modified by a plugin before going to the layout renderer. $this->getApplication()->triggerEvent('onCodeMirrorBeforeInit', [&$this->params, &$this->basePath, &$this->modePath]); $displayData = (object) ['params' => $this->params]; $font = $this->params->get('fontFamily', '0'); $fontInfo = $this->getFontInfo($font); if (isset($fontInfo)) { if (isset($fontInfo->url)) { $doc->addStyleSheet($fontInfo->url); } if (isset($fontInfo->css)) { $displayData->fontFamily = $fontInfo->css . '!important'; } } // We need to do output buffering here because layouts may actually 'echo' things which we do not want. ob_start(); LayoutHelper::render('editors.codemirror.styles', $displayData, JPATH_PLUGINS . '/editors/codemirror/layouts'); ob_end_clean(); $this->getApplication()->triggerEvent('onCodeMirrorAfterInit', [&$this->params, &$this->basePath, &$this->modePath]); } /** * Display the editor area. * * @param string $name The control name. * @param string $content The contents of the text area. * @param string $width The width of the text area (px or %). * @param string $height The height of the text area (px or %). * @param int $col The number of columns for the textarea. * @param int $row The number of rows for the textarea. * @param boolean $buttons True and the editor buttons will be displayed. * @param string $id An optional ID for the textarea (note: since 1.6). If not supplied the name is used. * @param string $asset Not used. * @param object $author Not used. * @param array $params Associative array of editor parameters. * * @return string HTML */ public function onDisplay( $name, $content, $width, $height, $col, $row, $buttons = true, $id = null, $asset = null, $author = null, $params = [] ) { // True if a CodeMirror already has autofocus. Prevent multiple autofocuses. static $autofocused; $id = empty($id) ? $name : $id; // Must pass the field id to the buttons in this editor. $buttons = $this->displayButtons($id, $buttons, $asset, $author); // Only add "px" to width and height if they are not given as a percentage. $width .= is_numeric($width) ? 'px' : ''; $height .= is_numeric($height) ? 'px' : ''; // Options for the CodeMirror constructor. $options = new \stdClass(); $keyMapUrl = ''; // Is field readonly? if (!empty($params['readonly'])) { $options->readOnly = 'nocursor'; } // Should we focus on the editor on load? if (!$autofocused) { $options->autofocus = isset($params['autofocus']) ? (bool) $params['autofocus'] : false; $autofocused = $options->autofocus; } // Set autorefresh to true - fixes issue when editor is not loaded in a focused tab $options->autoRefresh = true; $options->lineWrapping = (bool) $this->params->get('lineWrapping', 1); // Add styling to the active line. $options->styleActiveLine = (bool) $this->params->get('activeLine', 1); // Do we highlight selection matches? if ($this->params->get('selectionMatches', 1)) { $options->highlightSelectionMatches = [ 'showToken' => true, 'annotateScrollbar' => true, ]; } // Do we use line numbering? if ($options->lineNumbers = (bool) $this->params->get('lineNumbers', 1)) { $options->gutters[] = 'CodeMirror-linenumbers'; } // Do we use code folding? if ($options->foldGutter = (bool) $this->params->get('codeFolding', 1)) { $options->gutters[] = 'CodeMirror-foldgutter'; } // Do we use a marker gutter? if ($options->markerGutter = (bool) $this->params->get('markerGutter', $this->params->get('marker-gutter', 1))) { $options->gutters[] = 'CodeMirror-markergutter'; } // Load the syntax mode. $syntax = !empty($params['syntax']) ? $params['syntax'] : $this->params->get('syntax', 'html'); $options->mode = $this->modeAlias[$syntax] ?? $syntax; // Load the theme if specified. if ($theme = $this->params->get('theme')) { $options->theme = $theme; $this->getApplication()->getDocument()->getWebAssetManager() ->registerAndUseStyle('codemirror.theme', $this->basePath . 'theme/' . $theme . '.css'); } // Special options for tagged modes (xml/html). if (in_array($options->mode, ['xml', 'html', 'php'])) { // Autogenerate closing tags (html/xml only). $options->autoCloseTags = (bool) $this->params->get('autoCloseTags', 1); // Highlight the matching tag when the cursor is in a tag (html/xml only). $options->matchTags = (bool) $this->params->get('matchTags', 1); } // Special options for non-tagged modes. if (!in_array($options->mode, ['xml', 'html'])) { // Autogenerate closing brackets. $options->autoCloseBrackets = (bool) $this->params->get('autoCloseBrackets', 1); // Highlight the matching bracket. $options->matchBrackets = (bool) $this->params->get('matchBrackets', 1); } $options->scrollbarStyle = $this->params->get('scrollbarStyle', 'native'); // KeyMap settings. $options->keyMap = $this->params->get('keyMap', false); // Support for older settings. if ($options->keyMap === false) { $options->keyMap = $this->params->get('vimKeyBinding', 0) ? 'vim' : 'default'; } if ($options->keyMap !== 'default') { $keyMapUrl = HTMLHelper::_('script', $this->basePath . 'keymap/' . $options->keyMap . '.min.js', ['relative' => false, 'pathOnly' => true]); $keyMapUrl .= '?' . $this->getApplication()->getDocument()->getMediaVersion(); } $options->keyMapUrl = $keyMapUrl; $displayData = (object) [ 'options' => $options, 'params' => $this->params, 'name' => $name, 'id' => $id, 'cols' => $col, 'rows' => $row, 'content' => $content, 'buttons' => $buttons, 'basePath' => $this->basePath, 'modePath' => $this->modePath, ]; // At this point, displayData can be modified by a plugin before going to the layout renderer. $results = $this->getApplication()->triggerEvent('onCodeMirrorBeforeDisplay', [&$displayData]); $results[] = LayoutHelper::render('editors.codemirror.element', $displayData, JPATH_PLUGINS . '/editors/codemirror/layouts'); foreach ($this->getApplication()->triggerEvent('onCodeMirrorAfterDisplay', [&$displayData]) as $result) { $results[] = $result; } return implode("\n", $results); } /** * Displays the editor buttons. * * @param string $name Button name. * @param mixed $buttons [array with button objects | boolean true to display buttons] * @param mixed $asset Unused. * @param mixed $author Unused. * * @return string|void */ protected function displayButtons($name, $buttons, $asset, $author) { if (is_array($buttons) || (is_bool($buttons) && $buttons)) { $buttonsEvent = new Event( 'getButtons', [ 'editor' => $name, 'buttons' => $buttons, ] ); $buttonsResult = $this->getDispatcher()->dispatch('getButtons', $buttonsEvent); $buttons = $buttonsResult['result']; return LayoutHelper::render('joomla.editors.buttons', $buttons); } } /** * Gets font info from the json data file * * @param string $font A key from the $fonts array. * * @return object */ protected function getFontInfo($font) { static $fonts; if (!$fonts) { $fonts = json_decode(file_get_contents(JPATH_PLUGINS . '/editors/codemirror/fonts.json'), true); } return isset($fonts[$font]) ? (object) $fonts[$font] : null; } } PK!CC+editors/codemirror/src/Field/FontsField.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\CodeMirror\Field; use Joomla\CMS\Form\Field\ListField; use Joomla\CMS\HTML\HTMLHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Supports an HTML select list of fonts * * @package Joomla.Plugin * @subpackage Editors.codemirror * @since 3.4 */ class FontsField extends ListField { /** * The form field type. * * @var string * @since 3.4 */ protected $type = 'Fonts'; /** * Method to get the list of fonts field options. * * @return array The field option objects. * * @since 3.4 */ protected function getOptions() { $fonts = json_decode(file_get_contents(JPATH_PLUGINS . '/editors/codemirror/fonts.json')); $options = []; foreach ($fonts as $key => $info) { $options[] = HTMLHelper::_('select.option', $key, $info->name); } // Merge any additional options in the XML definition. return array_merge(parent::getOptions(), $options); } } PK!7"editors/none/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Editors\None\Extension\None; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.3.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new None( $dispatcher, (array) PluginHelper::getPlugin('editors', 'none') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!HtNnJJ#editors/none/src/Extension/None.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Editors\None\Extension; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\Event; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Plain Textarea Editor Plugin * * @since 1.5 */ final class None extends CMSPlugin { /** * Display the editor area. * * @param string $name The control name. * @param string $content The contents of the text area. * @param string $width The width of the text area (px or %). * @param string $height The height of the text area (px or %). * @param integer $col The number of columns for the textarea. * @param integer $row The number of rows for the textarea. * @param boolean $buttons True and the editor buttons will be displayed. * @param string $id An optional ID for the textarea (note: since 1.6). If not supplied the name is used. * @param string $asset The object asset * @param object $author The author. * @param array $params Associative array of editor parameters. * * @return string */ public function onDisplay( $name, $content, $width, $height, $col, $row, $buttons = true, $id = null, $asset = null, $author = null, $params = [] ) { if (empty($id)) { $id = $name; } // Only add "px" to width and height if they are not given as a percentage if (is_numeric($width)) { $width .= 'px'; } if (is_numeric($height)) { $height .= 'px'; } $readonly = !empty($params['readonly']) ? ' readonly disabled' : ''; $this->getApplication()->getDocument()->getWebAssetManager() ->registerAndUseScript( 'webcomponent.editor-none', 'plg_editors_none/joomla-editor-none.min.js', [], ['type' => 'module'] ); return '' . '' . '' . $this->displayButtons($id, $buttons, $asset, $author); } /** * Displays the editor buttons. * * @param string $name The control name. * @param mixed $buttons [array with button objects | boolean true to display buttons] * @param string $asset The object asset * @param object $author The author. * * @return void|string HTML */ private function displayButtons($name, $buttons, $asset, $author) { if (is_array($buttons) || (is_bool($buttons) && $buttons)) { $buttonsEvent = new Event( 'getButtons', [ 'editor' => $name, 'buttons' => $buttons, ] ); $buttonsResult = $this->getDispatcher()->dispatch('getButtons', $buttonsEvent); $buttons = $buttonsResult['result']; return LayoutHelper::render('joomla.editors.buttons', $buttons); } } } PK!wFFeditors/none/none.xmlnu[ plg_editors_none 3.0.0 2005-09 Joomla! Project admin@joomla.org www.joomla.org (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt PLG_NONE_XML_DESCRIPTION Joomla\Plugin\Editors\None services src language/en-GB/plg_editors_none.ini language/en-GB/plg_editors_none.sys.ini PK!?yyinstaller/override/override.xmlnu[ plg_installer_override Joomla! Project 2018-06 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.0.0 PLG_INSTALLER_OVERRIDE_PLUGIN_XML_DESCRIPTION Joomla\Plugin\Installer\Override services src language/en-GB/plg_installer_override.ini language/en-GB/plg_installer_override.sys.ini PK!c;(installer/override/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Installer\Override\Extension\Override; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Override( $dispatcher, (array) PluginHelper::getPlugin('installer', 'override') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK! * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Installer\Override\Extension; use Joomla\CMS\Date\Date; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Override Plugin * * @since 4.0.0 */ final class Override extends CMSPlugin { use DatabaseAwareTrait; /** * Load the language file on instantiation. * * @var boolean * * @since 4.0.0 */ protected $autoloadLanguage = true; /** * Method to get com_templates model instance. * * @param string $name The model name. Optional * @param string $prefix The class prefix. Optional * * @return \Joomla\Component\Templates\Administrator\Model\TemplateModel * * @since 4.0.0 * * @throws \Exception */ public function getModel($name = 'Template', $prefix = 'Administrator') { /** @var \Joomla\Component\Templates\Administrator\Extension\TemplatesComponent $templateProvider */ $templateProvider = $this->getApplication()->bootComponent('com_templates'); /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ $model = $templateProvider->getMVCFactory()->createModel($name, $prefix); return $model; } /** * Purges session array. * * @return void * * @since 4.0.0 */ public function purge() { // Delete stored session value. $session = $this->getApplication()->getSession(); $session->remove('override.beforeEventFiles'); $session->remove('override.afterEventFiles'); } /** * Method to store files before event. * * @return void * * @since 4.0.0 */ public function storeBeforeEventFiles() { // Delete stored session value. $this->purge(); // Get list and store in session. $list = $this->getOverrideCoreList(); $this->getApplication()->getSession()->set('override.beforeEventFiles', $list); } /** * Method to store files after event. * * @return void * * @since 4.0.0 */ public function storeAfterEventFiles() { // Get list and store in session. $list = $this->getOverrideCoreList(); $this->getApplication()->getSession()->set('override.afterEventFiles', $list); } /** * Method to prepare changed or updated core file. * * @param string $action The name of the action. * * @return array A list of changed files. * * @since 4.0.0 */ public function getUpdatedFiles($action) { $session = $this->getApplication()->getSession(); $after = $session->get('override.afterEventFiles'); $before = $session->get('override.beforeEventFiles'); $result = []; if (!is_array($after) || !is_array($before)) { return $result; } $size1 = count($after); $size2 = count($before); if ($size1 === $size2) { for ($i = 0; $i < $size1; $i++) { if ($after[$i]->coreFile !== $before[$i]->coreFile) { $after[$i]->action = $action; $result[] = $after[$i]; } } } return $result; } /** * Method to get core list of override files. * * @return array The list of core files. * * @since 4.0.0 */ public function getOverrideCoreList() { try { /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $templateModel */ $templateModel = $this->getModel(); } catch (\Exception $e) { return []; } return $templateModel->getCoreList(); } /** * Last process of this plugin. * * @param array $result Result array. * * @return void * * @since 4.0.0 */ public function finalize($result) { $num = count($result); $link = 'index.php?option=com_templates&view=templates'; if ($num != 0) { $this->getApplication()->enqueueMessage(Text::plural('PLG_INSTALLER_OVERRIDE_N_FILE_UPDATED', $num, $link), 'notice'); $this->saveOverrides($result); } // Delete stored session value. $this->purge(); } /** * Event before extension update. * * @return void * * @since 4.0.0 */ public function onExtensionBeforeUpdate() { $this->storeBeforeEventFiles(); } /** * Event after extension update. * * @return void * * @since 4.0.0 */ public function onExtensionAfterUpdate() { $this->storeAfterEventFiles(); $result = $this->getUpdatedFiles('Extension Update'); $this->finalize($result); } /** * Event before joomla update. * * @return void * * @since 4.0.0 */ public function onJoomlaBeforeUpdate() { $this->storeBeforeEventFiles(); } /** * Event after joomla update. * * @return void * * @since 4.0.0 */ public function onJoomlaAfterUpdate() { $this->storeAfterEventFiles(); $result = $this->getUpdatedFiles('Joomla Update'); $this->finalize($result); } /** * Event before install. * * @return void * * @since 4.0.0 */ public function onInstallerBeforeInstaller() { $this->storeBeforeEventFiles(); } /** * Event after install. * * @return void * * @since 4.0.0 */ public function onInstallerAfterInstaller() { $this->storeAfterEventFiles(); $result = $this->getUpdatedFiles('Extension Install'); $this->finalize($result); } /** * Check for existing id. * * @param string $id Hash id of file. * @param integer $exid Extension id of file. * * @return boolean True/False * * @since 4.0.0 */ public function load($id, $exid) { $db = $this->getDatabase(); // Create a new query object. $query = $db->getQuery(true); $query ->select($db->quoteName('hash_id')) ->from($db->quoteName('#__template_overrides')) ->where($db->quoteName('hash_id') . ' = :id') ->where($db->quoteName('extension_id') . ' = :exid') ->bind(':id', $id) ->bind(':exid', $exid, ParameterType::INTEGER); $db->setQuery($query); $results = $db->loadObjectList(); if (count($results) === 1) { return true; } return false; } /** * Save the updated files. * * @param array $pks Updated files. * * @return void * * @since 4.0.0 * @throws \Joomla\Database\Exception\ExecutionFailureException|\Joomla\Database\Exception\ConnectionFailureException */ private function saveOverrides($pks) { // Insert columns. $columns = [ 'template', 'hash_id', 'action', 'created_date', 'modified_date', 'extension_id', 'state', 'client_id', ]; $db = $this->getDatabase(); // Create an insert query. $insertQuery = $db->getQuery(true) ->insert($db->quoteName('#__template_overrides')) ->columns($db->quoteName($columns)); foreach ($pks as $pk) { $date = new Date('now'); $createdDate = $date->toSql(); if (empty($pk->coreFile)) { $modifiedDate = null; } else { $modifiedDate = $createdDate; } if ($this->load($pk->id, $pk->extension_id)) { $updateQuery = $db->getQuery(true) ->update($db->quoteName('#__template_overrides')) ->set( [ $db->quoteName('modified_date') . ' = :modifiedDate', $db->quoteName('action') . ' = :pkAction', $db->quoteName('state') . ' = 0', ] ) ->where($db->quoteName('hash_id') . ' = :pkId') ->where($db->quoteName('extension_id') . ' = :exId') ->bind(':modifiedDate', $modifiedDate) ->bind(':pkAction', $pk->action) ->bind(':pkId', $pk->id) ->bind(':exId', $pk->extension_id, ParameterType::INTEGER); // Set the query using our newly populated query object and execute it. $db->setQuery($updateQuery); $db->execute(); continue; } // Insert values, preserve order $bindArray = $insertQuery->bindArray( [ $pk->template, $pk->id, $pk->action, $createdDate, $modifiedDate, ], ParameterType::STRING ); $bindArray = array_merge( $bindArray, $insertQuery->bindArray( [ $pk->extension_id, 0, (int) $pk->client, ], ParameterType::INTEGER ) ); $insertQuery->values(implode(',', $bindArray)); } if (!empty($bindArray)) { $db->setQuery($insertQuery); $db->execute(); } } } PK!pKLL/installer/folderinstaller/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Installer\Folder\Extension\FolderInstaller; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new FolderInstaller( $dispatcher, (array) PluginHelper::getPlugin('installer', 'folderinstaller') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!Mţ-installer/folderinstaller/folderinstaller.xmlnu[ plg_installer_folderinstaller Joomla! Project 2016-05 (C) 2016 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.6.0 PLG_INSTALLER_FOLDERINSTALLER_PLUGIN_XML_DESCRIPTION Joomla\Plugin\Installer\Folder services src tmpl language/en-GB/plg_installer_folderinstaller.ini language/en-GB/plg_installer_folderinstaller.sys.ini PK!ؼi*installer/folderinstaller/tmpl/default.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; /** @var PlgInstallerFolderInstaller $this */ Text::script('PLG_INSTALLER_FOLDERINSTALLER_NO_INSTALL_PATH'); $this->getApplication()->getDocument()->getWebAssetManager() ->registerAndUseScript( 'plg_installer_folderinstaller.folderinstaller', 'plg_installer_folderinstaller/folderinstaller.js', [], ['defer' => true], ['core'] ); ?>
    PK!c;installer/folderinstaller/src/Extension/FolderInstaller.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Installer\Folder\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * FolderInstaller Plugin. * * @since 3.6.0 */ final class FolderInstaller extends CMSPlugin { /** * Application object. * * @var \Joomla\CMS\Application\CMSApplication * @since 4.0.0 * @deprecated 6.0 Is needed for template overrides, use getApplication instead */ protected $app; /** * Textfield or Form of the Plugin. * * @return array Returns an array with the tab information * * @since 3.6.0 */ public function onInstallerAddInstallationTab() { // Load language files $this->loadLanguage(); $tab = []; $tab['name'] = 'folder'; $tab['label'] = $this->getApplication()->getLanguage()->_('PLG_INSTALLER_FOLDERINSTALLER_TEXT'); // Render the input ob_start(); include PluginHelper::getLayoutPath('installer', 'folderinstaller'); $tab['content'] = ob_get_clean(); return $tab; } } PK!9QQ0installer/packageinstaller/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Installer\Package\Extension\PackageInstaller; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new PackageInstaller( $dispatcher, (array) PluginHelper::getPlugin('installer', 'packageinstaller') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!L//installer/packageinstaller/packageinstaller.xmlnu[ plg_installer_packageinstaller Joomla! Project 2016-05 (C) 2016 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.6.0 PLG_INSTALLER_PACKAGEINSTALLER_PLUGIN_XML_DESCRIPTION Joomla\Plugin\Installer\Package services src tmpl language/en-GB/plg_installer_packageinstaller.ini language/en-GB/plg_installer_packageinstaller.sys.ini PK!:+installer/packageinstaller/tmpl/default.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Filesystem\FilesystemHelper; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\Plugin\Installer\Package\Extension\PackageInstaller; /** @var PackageInstaller $this */ HTMLHelper::_('form.csrf'); Text::script('PLG_INSTALLER_PACKAGEINSTALLER_NO_PACKAGE'); Text::script('PLG_INSTALLER_PACKAGEINSTALLER_UPLOAD_ERROR_UNKNOWN'); Text::script('PLG_INSTALLER_PACKAGEINSTALLER_UPLOAD_ERROR_EMPTY'); Text::script('COM_INSTALLER_MSG_WARNINGS_UPLOADFILETOOBIG'); $this->getApplication()->getDocument()->getWebAssetManager() ->registerAndUseScript( 'plg_installer_packageinstaller.packageinstaller', 'plg_installer_packageinstaller/packageinstaller.js', [], ['defer' => true], ['core'] ); $return = $this->getApplication()->getInput()->getBase64('return'); $maxSizeBytes = FilesystemHelper::fileUploadMaxSize(false); $maxSize = HTMLHelper::_('number.bytes', $maxSizeBytes); ?>

    0%

    PK!|%`=installer/packageinstaller/src/Extension/PackageInstaller.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Installer\Package\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * PackageInstaller Plugin. * * @since 3.6.0 */ final class PackageInstaller extends CMSPlugin { /** * Application object * * @var \Joomla\CMS\Application\CMSApplication * @since 4.0.0 * @deprecated 6.0 Is needed for template overrides, use getApplication instead */ protected $app; /** * Textfield or Form of the Plugin. * * @return array Returns an array with the tab information * * @since 3.6.0 */ public function onInstallerAddInstallationTab() { // Load language files $this->loadLanguage(); $tab = []; $tab['name'] = 'package'; $tab['label'] = $this->getApplication()->getLanguage()->_('PLG_INSTALLER_PACKAGEINSTALLER_UPLOAD_PACKAGE_FILE'); // Render the input ob_start(); include PluginHelper::getLayoutPath('installer', 'packageinstaller'); $tab['content'] = ob_get_clean(); return $tab; } } PK!ddT T installer/jce/jce.phpnu[ value format) * * @return bool true if credentials have been added to request or not our business, false otherwise (credentials not set by user) * * @since 3.0 */ public function onInstallerBeforePackageDownload(&$url, &$headers) { $app = JFactory::getApplication(); $uri = JUri::getInstance($url); $host = $uri->getHost(); if ($host !== 'www.joomlacontenteditor.net') { return true; } // Get the subscription key JLoader::import('joomla.application.component.helper'); $component = JComponentHelper::getComponent('com_jce'); // load plugin language for warning messages JFactory::getLanguage()->load('plg_installer_jce', JPATH_ADMINISTRATOR); // check if the key has already been set via the dlid field $dlid = $uri->getVar('key', ''); // check the component params, fallback to the dlid $key = $component->params->get('updates_key', $dlid); // if no key is set... if (empty($key)) { // if we are attempting to update JCE Pro, display a notice message if (strpos($url, 'pkg_jce_pro') !== false) { $app->enqueueMessage(JText::_('PLG_INSTALLER_JCE_KEY_WARNING'), 'notice'); } return true; } // Append the subscription key to the download URL $uri->setVar('key', $key); // create the url string $url = $uri->toString(); // check validity of the key and display a message if it is invalid / expired try { $tmpUri = clone $uri; $tmpUri->setVar('task', 'update.validate'); $tmpUri->delVar('file'); $tmpUrl = $tmpUri->toString(); $response = JHttpFactory::getHttp()->get($tmpUrl, array()); } catch (RuntimeException $exception) {} // invalid key, display a notice message if (403 == $response->code) { $app->enqueueMessage(JText::_('PLG_INSTALLER_JCE_KEY_INVALID'), 'notice'); } return true; } } PK!2Cinstaller/jce/jce.xmlnu[ plg_installer_jce 2.9.33 18-01-2023 Ryan Demmer info@joomlacontenteditor.net http://www.joomlacontenteditor.net Copyright (C) 2006 - 2022 Ryan Demmer. All rights reserved GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html PLG_INSTALLER_JCE_XML_DESCRIPTION jce.php en-GB.plg_installer_jce.ini en-GB.plg_installer_jce.sys.ini PK!V''installer/easyblog/easyblog.xmlnu[ Installer - EasyBlog 5.2.0 9 January 2018 Stack Ideas Sdn Bhd support@stackideas.com https://stackideas.com Copyright 2009 - 2015 Stack Ideas Sdn Bhd. All rights reserved. GPL License v2 Perform updates for EasyBlog easyblog.php https://stackideas.com/joomla4compat.xml PK!FMH H installer/easyblog/easyblog.phpnu[exists() || stristr($url, 'https://services.stackideas.com/updater/easyblog') === false) { return true; } // Get user's subscription key $config = EB::config(); $key = $config->get('main_apikey'); if (!$key) { $app->enqueueMessage('Your setup contains an invalid api key. EasyBlog will not be updated now. If the problem still persists, please get in touch with the support team at https://stackideas.com/forums', 'error'); return true; } $uri = new JURI($url); $domain = str_ireplace(array('http://', 'https://'), '', rtrim(JURI::root(), '/')); $localVersion = EB::getLocalVersion(); $latestVersion = $uri->getVar('to'); $uri = new JURI($url); $uri->setVar('from', $localVersion); $uri->setVar('key', $key); $uri->setVar('domain', $domain); $url = $uri->toString(); // Check to see if the single click updater can be used to update to this version $verifyUrl = 'https://services.stackideas.com/updater/easyblog?layout=upgradeable&from=' . $localVersion . '&to=' . $latestVersion . '&domain=' . $domain . '&key=' . $key; try { $response = JHttpFactory::getHttp()->get($verifyUrl); } catch (\RuntimeException $exception) { } $result = json_decode($response->body); if ($result->code == 400) { $url = rtrim(JURI::root(), '/') . '/administrator/index.php?option=com_easyblog'; EB::info()->set($result->error, 'error'); return $app->redirect($url); } return true; } } PK!i==,installer/urlinstaller/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Installer\Url\Extension\UrlInstaller; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new UrlInstaller( $dispatcher, (array) PluginHelper::getPlugin('installer', 'urlinstaller') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!$y/'installer/urlinstaller/tmpl/default.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; use Joomla\Plugin\Installer\Url\Extension\UrlInstaller; /** @var UrlInstaller $this */ $this->getApplication()->getDocument()->getWebAssetManager() ->registerAndUseScript('plg_installer_urlinstaller.urlinstaller', 'plg_installer_urlinstaller/urlinstaller.js', [], ['defer' => true], ['core']); ?>
    PK!rdˏ'installer/urlinstaller/urlinstaller.xmlnu[ plg_installer_urlinstaller Joomla! Project 2016-05 (C) 2016 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.6.0 PLG_INSTALLER_URLINSTALLER_PLUGIN_XML_DESCRIPTION Joomla\Plugin\Installer\Url services src tmpl language/en-GB/plg_installer_urlinstaller.ini language/en-GB/plg_installer_urlinstaller.sys.ini PK!5installer/urlinstaller/src/Extension/UrlInstaller.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Installer\Url\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * UrlFolderInstaller Plugin. * * @since 3.6.0 */ final class UrlInstaller extends CMSPlugin { /** * Application object. * * @var \Joomla\CMS\Application\CMSApplication * @since 4.0.0 * @deprecated 6.0 Is needed for template overrides, use getApplication instead */ protected $app; /** * Textfield or Form of the Plugin. * * @return array Returns an array with the tab information * * @since 3.6.0 */ public function onInstallerAddInstallationTab() { // Load language files $this->loadLanguage(); $tab = []; $tab['name'] = 'url'; $tab['label'] = $this->getApplication()->getLanguage()->_('PLG_INSTALLER_URLINSTALLER_TEXT'); // Render the input ob_start(); include PluginHelper::getLayoutPath('installer', 'urlinstaller'); $tab['content'] = ob_get_clean(); return $tab; } } PK!p& ==,installer/webinstaller/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Installer\Web\Extension\WebInstaller; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new WebInstaller( $dispatcher, (array) PluginHelper::getPlugin('installer', 'webinstaller') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!2 'installer/webinstaller/tmpl/default.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Language\Text; /** @var PlgInstallerWebinstaller $this */ $dir = $this->isRTL() ? ' dir="ltr"' : ''; Text::script('JSEARCH_FILTER_CLEAR'); Text::script('PLG_INSTALLER_WEBINSTALLER_INSTALL_WEB_LOADING_ERROR'); ?>

    PK!kmB5installer/webinstaller/src/Extension/WebInstaller.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Installer\Web\Extension; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Form\Rule\UrlRule; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Updater\Update; use Joomla\CMS\Uri\Uri; use Joomla\CMS\Version; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Support for the "Install from Web" tab * * @since 3.2 */ final class WebInstaller extends CMSPlugin { /** * The URL for the remote server. * * @var string * @since 4.0.0 */ public const REMOTE_URL = 'https://appscdn.joomla.org/webapps/'; /** * The application object. * * @var CMSApplication * @since 4.0.0 * @deprecated 6.0 Is needed for template overrides, use getApplication instead */ protected $app; /** * The URL to install from * * @var string|null * @since 4.0.0 */ private $installfrom = null; /** * Flag if the document is in a RTL direction * * @var integer|null * @since 4.0.0 */ private $rtl = null; /** * Event listener for the `onInstallerAddInstallationTab` event. * * @return array Returns an array with the tab information * * @since 4.0.0 */ public function onInstallerAddInstallationTab() { // Load language files $this->loadLanguage(); $installfrom = $this->getInstallFrom(); $doc = $this->getApplication()->getDocument(); $lang = $this->getApplication()->getLanguage(); // Push language strings to the JavaScript store Text::script('PLG_INSTALLER_WEBINSTALLER_CANNOT_INSTALL_EXTENSION_IN_PLUGIN'); Text::script('PLG_INSTALLER_WEBINSTALLER_REDIRECT_TO_EXTERNAL_SITE_TO_INSTALL'); $doc->getWebAssetManager() ->registerAndUseStyle('plg_installer_webinstaller.client', 'plg_installer_webinstaller/client.min.css') ->registerAndUseScript( 'plg_installer_webinstaller.client', 'plg_installer_webinstaller/client.min.js', [], ['type' => 'module'], ['core'] ); $devLevel = Version::PATCH_VERSION; if (!empty(Version::EXTRA_VERSION)) { $devLevel .= '-' . Version::EXTRA_VERSION; } $doc->addScriptOptions( 'plg_installer_webinstaller', [ 'base_url' => addslashes(self::REMOTE_URL), 'installat_url' => base64_encode(Uri::current() . '?option=com_installer&view=install'), 'installfrom_url' => addslashes($installfrom), 'product' => base64_encode(Version::PRODUCT), 'release' => base64_encode(Version::MAJOR_VERSION . '.' . Version::MINOR_VERSION), 'dev_level' => base64_encode($devLevel), 'installfromon' => $installfrom ? 1 : 0, 'language' => base64_encode($lang->getTag()), 'installFrom' => $installfrom != '' ? 4 : 5, ] ); $tab = [ 'name' => 'web', 'label' => $lang->_('PLG_INSTALLER_WEBINSTALLER_TAB_LABEL'), ]; // Render the input ob_start(); include PluginHelper::getLayoutPath('installer', 'webinstaller'); $tab['content'] = ob_get_clean(); $tab['content'] = '' . $tab['label'] . '' . $tab['content']; return $tab; } /** * Internal check to determine if the output is in a RTL direction * * @return integer * * @since 3.2 */ private function isRTL() { if ($this->rtl === null) { $this->rtl = strtolower($this->getApplication()->getDocument()->getDirection()) === 'rtl' ? 1 : 0; } return $this->rtl; } /** * Get the install from URL * * @return string * * @since 3.2 */ private function getInstallFrom() { if ($this->installfrom === null) { $installfrom = base64_decode($this->getApplication()->getInput()->getBase64('installfrom', '')); $field = new \SimpleXMLElement(''); if ((new UrlRule())->test($field, $installfrom) && preg_match('/\.xml\s*$/', $installfrom)) { $update = new Update(); $update->loadFromXml($installfrom); $package_url = trim($update->get('downloadurl', false)->_data); if ($package_url) { $installfrom = $package_url; } } $this->installfrom = $installfrom; } return $this->installfrom; } } PK!e{j4'installer/webinstaller/webinstaller.xmlnu[ plg_installer_webinstaller Joomla! Project 2017-04 (C) 2018 Open Source Matters, Inc. https://www.gnu.org/licenses/gpl-2.0.html GNU/GPL admin@joomla.org www.joomla.org 4.0.0 PLG_INSTALLER_WEBINSTALLER_XML_DESCRIPTION Joomla\Plugin\Installer\Web services src tmpl language/en-GB/plg_installer_webinstaller.ini language/en-GB/plg_installer_webinstaller.sys.ini PK!n~~multifactorauth/totp/totp.xmlnu[ plg_multifactorauth_totp Joomla! Project 2013-08 (C) 2013 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.2.0 PLG_MULTIFACTORAUTH_TOTP_XML_DESCRIPTION Joomla\Plugin\Multifactorauth\Totp services src language/en-GB/plg_multifactorauth_totp.ini language/en-GB/plg_multifactorauth_totp.sys.ini PK!H?D*multifactorauth/totp/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') || die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\User\UserFactoryInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Multifactorauth\Totp\Extension\Totp; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.2.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $config = (array) PluginHelper::getPlugin('multifactorauth', 'totp'); $subject = $container->get(DispatcherInterface::class); $plugin = new Totp($subject, $config); $plugin->setApplication(Factory::getApplication()); $plugin->setUserFactory($container->get(UserFactoryInterface::class)); return $plugin; } ); } }; PK!B88+multifactorauth/totp/src/Extension/Totp.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Multifactorauth\Totp\Extension; use Joomla\CMS\Encrypt\Totp as TotpHelper; use Joomla\CMS\Event\MultiFactor\Captive; use Joomla\CMS\Event\MultiFactor\GetMethod; use Joomla\CMS\Event\MultiFactor\GetSetup; use Joomla\CMS\Event\MultiFactor\SaveSetup; use Joomla\CMS\Event\MultiFactor\Validate; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\User; use Joomla\CMS\User\UserFactoryAwareTrait; use Joomla\Component\Users\Administrator\DataShape\CaptiveRenderOptions; use Joomla\Component\Users\Administrator\DataShape\MethodDescriptor; use Joomla\Component\Users\Administrator\DataShape\SetupRenderOptions; use Joomla\Component\Users\Administrator\Table\MfaTable; use Joomla\Event\SubscriberInterface; use Joomla\Input\Input; use RuntimeException; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! Multi-factor Authentication using Google Authenticator TOTP Plugin * * @since 3.2 */ class Totp extends CMSPlugin implements SubscriberInterface { use UserFactoryAwareTrait; /** * Affects constructor behavior. If true, language files will be loaded automatically. * * @var boolean * @since 3.2 */ protected $autoloadLanguage = true; /** * The MFA Method name handled by this plugin * * @var string * @since 4.2.0 */ private $mfaMethodName = 'totp'; /** * Should I try to detect and register legacy event listeners, i.e. methods which accept unwrapped arguments? While * this maintains a great degree of backwards compatibility to Joomla! 3.x-style plugins it is much slower. You are * advised to implement your plugins using proper Listeners, methods accepting an AbstractEvent as their sole * parameter, for best performance. Also bear in mind that Joomla! 5.x onwards will only allow proper listeners, * removing support for legacy Listeners. * * @var boolean * @since 4.2.0 * * @deprecated 4.3 will be removed in 6.0 * Implement your plugin methods accepting an AbstractEvent object * Example: * onEventTriggerName(AbstractEvent $event) { * $context = $event->getArgument(...); * } */ protected $allowLegacyListeners = false; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.2.0 */ public static function getSubscribedEvents(): array { return [ 'onUserMultifactorGetMethod' => 'onUserMultifactorGetMethod', 'onUserMultifactorCaptive' => 'onUserMultifactorCaptive', 'onUserMultifactorGetSetup' => 'onUserMultifactorGetSetup', 'onUserMultifactorSaveSetup' => 'onUserMultifactorSaveSetup', 'onUserMultifactorValidate' => 'onUserMultifactorValidate', ]; } /** * Gets the identity of this MFA Method * * @param GetMethod $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorGetMethod(GetMethod $event): void { $event->addResult( new MethodDescriptor( [ 'name' => $this->mfaMethodName, 'display' => Text::_('PLG_MULTIFACTORAUTH_TOTP_METHOD_TITLE'), 'shortinfo' => Text::_('PLG_MULTIFACTORAUTH_TOTP_SHORTINFO'), 'image' => 'media/plg_multifactorauth_totp/images/totp.svg', ] ) ); } /** * Returns the information which allows Joomla to render the Captive MFA page. This is the page * which appears right after you log in and asks you to validate your login with MFA. * * @param Captive $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorCaptive(Captive $event): void { /** * @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method !== $this->mfaMethodName) { return; } $event->addResult( new CaptiveRenderOptions( [ // Custom HTML to display above the MFA form 'pre_message' => Text::_('PLG_MULTIFACTORAUTH_TOTP_CAPTIVE_PROMPT'), // How to render the MFA code field. "input" (HTML input element) or "custom" (custom HTML) 'field_type' => 'input', // The type attribute for the HTML input box. Typically "text" or "password". Use any HTML5 input type. 'input_type' => 'text', // The attributes for the HTML input box. 'input_attributes' => [ 'pattern' => "{0,9}", 'maxlength' => "6", 'inputmode' => "numeric", ], // Placeholder text for the HTML input box. Leave empty if you don't need it. 'placeholder' => '', // Label to show above the HTML input box. Leave empty if you don't need it. 'label' => Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_LABEL'), // Custom HTML. Only used when field_type = custom. 'html' => '', // Custom HTML to display below the MFA form 'post_message' => '', ] ) ); } /** * Returns the information which allows Joomla to render the MFA setup page. This is the page * which allows the user to add or modify a MFA Method for their user account. If the record * does not correspond to your plugin return an empty array. * * @param GetSetup $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorGetSetup(GetSetup $event): void { /** * @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method !== $this->mfaMethodName) { return; } $totp = new TotpHelper(); // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $key = $options['key'] ?? ''; $session = $this->getApplication()->getSession(); $isConfigured = !empty($key); // If there's a key in the session use that instead. $sessionKey = $session->get('com_users.totp.key', null); if (!empty($sessionKey)) { $key = $sessionKey; } // If there's still no key in the options, generate one and save it in the session if (empty($key)) { $key = $totp->generateSecret(); $session->set('com_users.totp.key', $key); } // Generate a QR code for the key $user = $this->getUserFactory()->loadUserById($record->user_id); $hostname = Uri::getInstance()->toString(['host']); $otpURL = sprintf("otpauth://totp/%s@%s?secret=%s", $user->username, $hostname, $key); $document = $this->getApplication()->getDocument(); $wam = $document->getWebAssetManager(); $document->addScriptOptions('plg_multifactorauth_totp.totp.qr', $otpURL); $wam->getRegistry()->addExtensionRegistryFile('plg_multifactorauth_totp'); $wam->useScript('plg_multifactorauth_totp.setup'); $event->addResult( new SetupRenderOptions( [ 'default_title' => Text::_('PLG_MULTIFACTORAUTH_TOTP_METHOD_TITLE'), 'pre_message' => Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_INSTRUCTIONS'), 'table_heading' => Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_TABLE_HEADING'), 'tabular_data' => [ '' => Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_TABLE_SUBHEAD'), Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_TABLE_KEY') => $key, Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_TABLE_QR') => "", Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_TABLE_LINK') => Text::sprintf('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_TABLE_LINK_TEXT', $otpURL) . '
    ' . Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_TABLE_LINK_NOTE') . '', ], 'hidden_data' => [ 'key' => $key, ], 'input_type' => $isConfigured ? 'hidden' : 'text', 'input_attributes' => [ 'pattern' => "{0,9}", 'maxlength' => "6", 'inputmode' => "numeric", ], 'input_value' => '', 'placeholder' => Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_SETUP_PLACEHOLDER'), 'label' => Text::_('PLG_MULTIFACTORAUTH_TOTP_LBL_LABEL'), ] ) ); } /** * Parse the input from the MFA setup page and return the configuration information to be saved to the database. If * the information is invalid throw a RuntimeException to signal the need to display the editor page again. The * message of the exception will be displayed to the user. If the record does not correspond to your plugin return * an empty array. * * @param SaveSetup $event The event we are handling * * @return void The configuration data to save to the database * @since 4.2.0 */ public function onUserMultifactorSaveSetup(SaveSetup $event): void { /** * @var MfaTable $record The record currently selected by the user. * @var Input $input The user input you are going to take into account. */ $record = $event['record']; $input = $event['input']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $optionsKey = $options['key'] ?? ''; $key = $optionsKey; $session = $this->getApplication()->getSession(); // If there is no key in the options fetch one from the session if (empty($key)) { $key = $session->get('com_users.totp.key', null); } // If there is still no key in the options throw an error if (empty($key)) { throw new \RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'), 403); } /** * If the code is empty but the key already existed in $options someone is simply changing the title / default * Method status. We can allow this and stop checking anything else now. */ $code = $input->getInt('code'); if (empty($code) && !empty($optionsKey)) { $event->addResult($options); return; } // In any other case validate the submitted code $totp = new TotpHelper(); $isValid = $totp->checkCode($key, $code); if (!$isValid) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_TOTP_ERR_VALIDATIONFAILED'), 500); } // The code is valid. Unset the key from the session. $session->set('com_users.totp.key', null); // Return the configuration to be serialized $event->addResult( [ 'key' => $key, ] ); } /** * Validates the Multi-factor Authentication code submitted by the user in the Multi-Factor * Authentication page. If the record does not correspond to your plugin return FALSE. * * @param Validate $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorValidate(Validate $event): void { /** * @var MfaTable $record The MFA Method's record you're validating against * @var User $user The user record * @var string $code The submitted code */ $record = $event['record']; $user = $event['user']; $code = $event['code']; // Make sure we are actually meant to handle this Method if ($record->method !== $this->mfaMethodName) { $event->addResult(false); return; } // Double check the MFA Method is for the correct user if ($user->id != $record->user_id) { $event->addResult(false); return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $key = $options['key'] ?? ''; // If there is no key in the options throw an error if (empty($key)) { $event->addResult(false); return; } // Check the MFA code for validity $event->addResult((new TotpHelper())->checkCode($key, $code)); } /** * Decodes the options from a record into an options object. * * @param MfaTable $record The record to decode options for * * @return array * @since 4.2.0 */ private function decodeRecordOptions(MfaTable $record): array { $options = [ 'key' => '', ]; if (!empty($record->options)) { $recordOptions = $record->options; $options = array_merge($options, $recordOptions); } return $options; } } PK! Өmultifactorauth/email/email.xmlnu[ plg_multifactorauth_email Joomla! Project 2022-05 (C) 2022 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.2.0 PLG_MULTIFACTORAUTH_EMAIL_XML_DESCRIPTION Joomla\Plugin\Multifactorauth\Email services src language/en-GB/plg_multifactorauth_email.ini language/en-GB/plg_multifactorauth_email.sys.ini
    PK!Pp+multifactorauth/email/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') || die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\User\UserFactoryInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Multifactorauth\Email\Extension\Email; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.2.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $config = (array) PluginHelper::getPlugin('multifactorauth', 'email'); $subject = $container->get(DispatcherInterface::class); $plugin = new Email($subject, $config); $plugin->setApplication(Factory::getApplication()); $plugin->setUserFactory($container->get(UserFactoryInterface::class)); return $plugin; } ); } }; PK!SS-multifactorauth/email/src/Extension/Email.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Multifactorauth\Email\Extension; use Exception; use Joomla\CMS\Encrypt\Totp; use Joomla\CMS\Event\MultiFactor\BeforeDisplayMethods; use Joomla\CMS\Event\MultiFactor\Captive; use Joomla\CMS\Event\MultiFactor\GetMethod; use Joomla\CMS\Event\MultiFactor\GetSetup; use Joomla\CMS\Event\MultiFactor\SaveSetup; use Joomla\CMS\Event\MultiFactor\Validate; use Joomla\CMS\Factory; use Joomla\CMS\Input\Input; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\CMS\Mail\Exception\MailDisabledException; use Joomla\CMS\Mail\MailTemplate; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\User; use Joomla\CMS\User\UserFactoryAwareTrait; use Joomla\Component\Users\Administrator\DataShape\CaptiveRenderOptions; use Joomla\Component\Users\Administrator\DataShape\MethodDescriptor; use Joomla\Component\Users\Administrator\DataShape\SetupRenderOptions; use Joomla\Component\Users\Administrator\Helper\Mfa as MfaHelper; use Joomla\Component\Users\Administrator\Table\MfaTable; use Joomla\Event\SubscriberInterface; use PHPMailer\PHPMailer\Exception as phpMailerException; use RuntimeException; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! Multi-factor Authentication using a Validation Code sent by Email. * * Requires entering a 6-digit code sent to the user through email. These codes change automatically * on a frequency set in the plugin options (30 seconds to 5 minutes, default 2 minutes). * * @since 4.2.0 */ class Email extends CMSPlugin implements SubscriberInterface { use UserFactoryAwareTrait; /** * Generated OTP length. Constant: 6 numeric digits. * * @since 4.2.0 */ private const CODE_LENGTH = 6; /** * Length of the secret key used for generating the OTPs. Constant: 20 characters. * * @since 4.2.0 */ private const SECRET_KEY_LENGTH = 20; /** * Should I try to detect and register legacy event listeners, i.e. methods which accept unwrapped arguments? While * this maintains a great degree of backwards compatibility to Joomla! 3.x-style plugins it is much slower. You are * advised to implement your plugins using proper Listeners, methods accepting an AbstractEvent as their sole * parameter, for best performance. Also bear in mind that Joomla! 5.x onwards will only allow proper listeners, * removing support for legacy Listeners. * * @var boolean * @since 4.2.0 * * @deprecated 4.3 will be removed in 6.0 * Implement your plugin methods accepting an AbstractEvent object * Example: * onEventTriggerName(AbstractEvent $event) { * $context = $event->getArgument(...); * } */ protected $allowLegacyListeners = false; /** * Autoload this plugin's language files * * @var boolean * @since 4.2.0 */ protected $autoloadLanguage = true; /** * The MFA Method name handled by this plugin * * @var string * @since 4.2.0 */ private $mfaMethodName = 'email'; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.2.0 */ public static function getSubscribedEvents(): array { return [ 'onUserMultifactorGetMethod' => 'onUserMultifactorGetMethod', 'onUserMultifactorCaptive' => 'onUserMultifactorCaptive', 'onUserMultifactorGetSetup' => 'onUserMultifactorGetSetup', 'onUserMultifactorSaveSetup' => 'onUserMultifactorSaveSetup', 'onUserMultifactorValidate' => 'onUserMultifactorValidate', 'onUserMultifactorBeforeDisplayMethods' => 'onUserMultifactorBeforeDisplayMethods', ]; } /** * Gets the identity of this MFA Method * * @param GetMethod $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorGetMethod(GetMethod $event): void { $event->addResult( new MethodDescriptor( [ 'name' => $this->mfaMethodName, 'display' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_DISPLAYEDAS'), 'shortinfo' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_SHORTINFO'), 'image' => 'media/plg_multifactorauth_email/images/email.svg', ] ) ); } /** * Returns the information which allows Joomla to render the Captive MFA page. This is the page * which appears right after you log in and asks you to validate your login with MFA. * * @param Captive $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorCaptive(Captive $event): void { /** * @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $key = $options['key'] ?? ''; // Send an email message with a new code and ask the user to enter it. $user = $this->getUserFactory()->loadUserById($record->user_id); try { $this->sendCode($key, $user); } catch (\Exception $e) { return; } $event->addResult( new CaptiveRenderOptions( [ // Custom HTML to display above the MFA form 'pre_message' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_PRE_MESSAGE'), // How to render the MFA code field. "input" (HTML input element) or "custom" (custom HTML) 'field_type' => 'input', // The type attribute for the HTML input box. Typically "text" or "password". Use any HTML5 input type. 'input_type' => 'text', // The attributes for the HTML input box. 'input_attributes' => [ 'pattern' => "{0,9}", 'maxlength' => "6", 'inputmode' => "numeric", ], // Placeholder text for the HTML input box. Leave empty if you don't need it. 'placeholder' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_SETUP_PLACEHOLDER'), // Label to show above the HTML input box. Leave empty if you don't need it. 'label' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_LABEL'), // Custom HTML. Only used when field_type = custom. 'html' => '', // Custom HTML to display below the MFA form 'post_message' => '', // Should I hide the default Submit button? 'hide_submit' => false, // Is this MFA method validating against all configured authenticators of the same type? 'allowEntryBatching' => false, ] ) ); } /** * Returns the information which allows Joomla to render the MFA setup page. This is the page * which allows the user to add or modify a MFA Method for their user account. If the record * does not correspond to your plugin return an empty array. * * @param GetSetup $event The event we are handling * * @return void * @throws \Exception * @since 4.2.0 */ public function onUserMultifactorGetSetup(GetSetup $event): void { /** @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $key = $options['key'] ?? ''; $isKeyAlreadySetup = !empty($key); // If there's a key in the session use that instead. $session = $this->getApplication()->getSession(); $session->get('plg_multifactorauth_email.emailcode.key', $key); // Initialize objects $timeStep = min(max((int) $this->params->get('timestep', 120), 30), 900); $totp = new Totp($timeStep, self::CODE_LENGTH, self::SECRET_KEY_LENGTH); // If there's still no key in the options, generate one and save it in the session if (!$isKeyAlreadySetup) { $key = $totp->generateSecret(); $session->set('plg_multifactorauth_email.emailcode.key', $key); $session->set('plg_multifactorauth_email.emailcode.user_id', $record->user_id); $user = $this->getUserFactory()->loadUserById($record->user_id); $this->sendCode($key, $user); $event->addResult( new SetupRenderOptions( [ 'default_title' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_DISPLAYEDAS'), 'hidden_data' => [ 'key' => $key, ], 'field_type' => 'input', 'input_type' => 'text', 'input_attributes' => [ 'pattern' => "{0,9}", 'maxlength' => "6", 'inputmode' => "numeric", ], 'input_value' => '', 'placeholder' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_SETUP_PLACEHOLDER'), 'pre_message' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_PRE_MESSAGE'), 'label' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_LABEL'), ] ) ); } else { $event->addResult( new SetupRenderOptions( [ 'default_title' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_DISPLAYEDAS'), 'input_type' => 'hidden', 'html' => '', ] ) ); } } /** * Parse the input from the MFA setup page and return the configuration information to be saved to the database. If * the information is invalid throw a RuntimeException to signal the need to display the editor page again. The * message of the exception will be displayed to the user. If the record does not correspond to your plugin return * an empty array. * * @param SaveSetup $event The event we are handling * * @return void The configuration data to save to the database * @since 4.2.0 */ public function onUserMultifactorSaveSetup(SaveSetup $event): void { /** * @var MfaTable $record The record currently selected by the user. * @var Input $input The user input you are going to take into account. */ $record = $event['record']; $input = $event['input']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $key = $options['key'] ?? ''; $isKeyAlreadySetup = !empty($key); $session = $this->getApplication()->getSession(); // If there is no key in the options fetch one from the session if (empty($key)) { $key = $session->get('plg_multifactorauth_email.emailcode.key', null); } // If there is still no key in the options throw an error if (empty($key)) { throw new \RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'), 403); } /** * If the code is empty but the key already existed in $options someone is simply changing the title / default * Method status. We can allow this and stop checking anything else now. */ $code = $input->getCmd('code'); if (empty($code) && $isKeyAlreadySetup) { $event->addResult($options); return; } // In any other case validate the submitted code $timeStep = min(max((int) $this->params->get('timestep', 120), 30), 900); $totp = new Totp($timeStep, self::CODE_LENGTH, self::SECRET_KEY_LENGTH); $isValid = $totp->checkCode((string) $key, (string) $code); if (!$isValid) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_EMAIL_ERR_INVALID_CODE'), 500); } // The code is valid. Unset the key from the session. $session->set('plg_multifactorauth_email.emailcode.key', null); // Return the configuration to be serialized $event->addResult(['key' => $key]); } /** * Validates the Multi-factor Authentication code submitted by the user in the Multi-Factor * Authentication page. If the record does not correspond to your plugin return FALSE. * * @param Validate $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorValidate(Validate $event): void { /** * @var MfaTable $record The MFA Method's record you're validating against * @var User $user The user record * @var string|null $code The submitted code */ $record = $event['record']; $user = $event['user']; $code = $event['code']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { $event->addResult(false); return; } // Double check the MFA Method is for the correct user if ($user->id != $record->user_id) { $event->addResult(false); return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $key = $options['key'] ?? ''; // If there is no key in the options throw an error if (empty($key)) { $event->addResult(false); return; } // Check the MFA code for validity $timeStep = min(max((int) $this->params->get('timestep', 120), 30), 900); $totp = new Totp($timeStep, self::CODE_LENGTH, self::SECRET_KEY_LENGTH); $event->addResult($totp->checkCode($key, (string) $code)); } /** * Executes before showing the MFA Methods for the user. Used for the Force Enable feature. * * @param BeforeDisplayMethods $event The event we are handling * * @return void * @throws \Exception * @since 4.2.0 */ public function onUserMultifactorBeforeDisplayMethods(BeforeDisplayMethods $event): void { /** @var ?User $user */ $user = $event['user']; // Is the forced enable feature activated? if ($this->params->get('force_enable', 0) != 1) { return; } // Get MFA Methods for this user $userMfaRecords = MfaHelper::getUserMfaRecords($user->id); // If there are no Methods go back if (\count($userMfaRecords) < 1) { return; } // If the only Method is backup codes go back if (\count($userMfaRecords) == 1) { /** @var MfaTable $record */ $record = reset($userMfaRecords); if ($record->method == 'backupcodes') { return; } } // If I already have the email Method go back $emailRecords = array_filter( $userMfaRecords, function (MfaTable $record) { return $record->method == 'email'; } ); if (\count($emailRecords)) { return; } // Add the email Method try { /** @var MVCFactoryInterface $factory */ $factory = $this->getApplication()->bootComponent('com_users')->getMVCFactory(); /** @var MfaTable $record */ $record = $factory->createTable('Mfa', 'Administrator'); $record->reset(); $timeStep = min(max((int) $this->params->get('timestep', 120), 30), 900); $totp = new Totp($timeStep, self::CODE_LENGTH, self::SECRET_KEY_LENGTH); $record->save( [ 'method' => 'email', 'title' => Text::_('PLG_MULTIFACTORAUTH_EMAIL_LBL_DISPLAYEDAS'), 'options' => [ 'key' => ($totp)->generateSecret(), ], 'default' => 0, 'user_id' => $user->id, ] ); } catch (\Exception $event) { // Fail gracefully } } /** * Decodes the options from a record into an options object. * * @param MfaTable $record The record to decode * * @return array * @since 4.2.0 */ private function decodeRecordOptions(MfaTable $record): array { $options = [ 'key' => '', ]; if (!empty($record->options)) { $recordOptions = $record->options; $options = array_merge($options, $recordOptions); } return $options; } /** * Creates a new TOTP code based on secret key $key and sends it to the user via email. * * @param string $key The TOTP secret key * @param User|null $user The Joomla! user to use * * @return void * @throws \Exception * @since 4.2.0 */ private function sendCode(string $key, ?User $user = null) { static $alreadySent = false; // Make sure we have a user if (!is_object($user) || !($user instanceof User)) { $user = $this->getApplication()->getIdentity() ?: $this->getUserFactory()->loadUserById(0); } if ($alreadySent) { return; } $alreadySent = true; // Get the API objects $timeStep = min(max((int) $this->params->get('timestep', 120), 30), 900); $totp = new Totp($timeStep, self::CODE_LENGTH, self::SECRET_KEY_LENGTH); // Create the list of variable replacements $code = $totp->getCode($key); $replacements = [ 'code' => $code, 'sitename' => $this->getApplication()->get('sitename'), 'siteurl' => Uri::base(), 'username' => $user->username, 'email' => $user->email, 'fullname' => $user->name, ]; try { $jLanguage = $this->getApplication()->getLanguage(); $mailer = new MailTemplate('plg_multifactorauth_email.mail', $jLanguage->getTag()); $mailer->addRecipient($user->email, $user->name); $mailer->addTemplateData($replacements); $didSend = $mailer->send(); } catch (MailDisabledException | phpMailerException $exception) { try { Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror'); } catch (\RuntimeException $exception) { $this->getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning'); } } try { // The user somehow managed to not install the mail template. I'll send the email the traditional way. if (isset($didSend) && !$didSend) { $subject = Text::_('PLG_MULTIFACTORAUTH_EMAIL_EMAIL_SUBJECT'); $body = Text::_('PLG_MULTIFACTORAUTH_EMAIL_EMAIL_BODY'); foreach ($replacements as $key => $value) { $subject = str_replace('{' . strtoupper($key) . '}', $value, $subject); $body = str_replace('{' . strtoupper($key) . '}', $value, $body); } $mailer = Factory::getMailer(); $mailer->setSubject($subject); $mailer->setBody($body); $mailer->addRecipient($user->email, $user->name); $mailer->Send(); } } catch (MailDisabledException | phpMailerException $exception) { try { Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror'); } catch (\RuntimeException $exception) { $this->getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning'); } } } } PK!X * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') || die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Multifactorauth\Fixed\Extension\Fixed; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.2.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $config = (array) PluginHelper::getPlugin('multifactorauth', 'fixed'); $subject = $container->get(DispatcherInterface::class); return new Fixed($subject, $config); } ); } }; PK!hDӄmultifactorauth/fixed/fixed.xmlnu[ plg_multifactorauth_fixed Joomla! Project 2022-05 (C) 2022 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.2.0 PLG_MULTIFACTORAUTH_FIXED_XML_DESCRIPTION Joomla\Plugin\Multifactorauth\Fixed services src language/en-GB/plg_multifactorauth_fixed.ini language/en-GB/plg_multifactorauth_fixed.sys.ini PK!..-multifactorauth/fixed/src/Extension/Fixed.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Multifactorauth\Fixed\Extension; use Joomla\CMS\Event\MultiFactor\Captive; use Joomla\CMS\Event\MultiFactor\GetMethod; use Joomla\CMS\Event\MultiFactor\GetSetup; use Joomla\CMS\Event\MultiFactor\SaveSetup; use Joomla\CMS\Event\MultiFactor\Validate; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\User\User; use Joomla\Component\Users\Administrator\DataShape\CaptiveRenderOptions; use Joomla\Component\Users\Administrator\DataShape\MethodDescriptor; use Joomla\Component\Users\Administrator\DataShape\SetupRenderOptions; use Joomla\Component\Users\Administrator\Table\MfaTable; use Joomla\Event\SubscriberInterface; use Joomla\Input\Input; use RuntimeException; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! Multi-factor Authentication using a fixed code. * * Requires a static string (password), different for each user. It effectively works as a second * password. The fixed code is stored hashed, like a regular password. * * This is NOT to be used on production sites. It serves as a demonstration plugin and as a template * for developers to create their own custom Multi-factor Authentication plugins. * * @since 4.2.0 */ class Fixed extends CMSPlugin implements SubscriberInterface { /** * Affects constructor behavior. If true, language files will be loaded automatically. * * @var boolean * @since 4.2.0 */ protected $autoloadLanguage = true; /** * The MFA Method name handled by this plugin * * @var string * @since 4.2.0 */ private $mfaMethodName = 'fixed'; /** * Should I try to detect and register legacy event listeners, i.e. methods which accept unwrapped arguments? While * this maintains a great degree of backwards compatibility to Joomla! 3.x-style plugins it is much slower. You are * advised to implement your plugins using proper Listeners, methods accepting an AbstractEvent as their sole * parameter, for best performance. Also bear in mind that Joomla! 5.x onwards will only allow proper listeners, * removing support for legacy Listeners. * * @var boolean * @since 4.2.0 * * @deprecated 4.3 will be removed in 6.0 * Implement your plugin methods accepting an AbstractEvent object * Example: * onEventTriggerName(AbstractEvent $event) { * $context = $event->getArgument(...); * } */ protected $allowLegacyListeners = false; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.2.0 */ public static function getSubscribedEvents(): array { return [ 'onUserMultifactorGetMethod' => 'onUserMultifactorGetMethod', 'onUserMultifactorCaptive' => 'onUserMultifactorCaptive', 'onUserMultifactorGetSetup' => 'onUserMultifactorGetSetup', 'onUserMultifactorSaveSetup' => 'onUserMultifactorSaveSetup', 'onUserMultifactorValidate' => 'onUserMultifactorValidate', ]; } /** * Gets the identity of this MFA Method * * @param GetMethod $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorGetMethod(GetMethod $event): void { $event->addResult( new MethodDescriptor( [ 'name' => $this->mfaMethodName, 'display' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_DISPLAYEDAS'), 'shortinfo' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_SHORTINFO'), 'image' => 'media/plg_multifactorauth_fixed/images/fixed.svg', ] ) ); } /** * Returns the information which allows Joomla to render the Captive MFA page. This is the page * which appears right after you log in and asks you to validate your login with MFA. * * @param Captive $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorCaptive(Captive $event): void { /** * @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } $event->addResult( new CaptiveRenderOptions( [ // Custom HTML to display above the MFA form 'pre_message' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_PREMESSAGE'), // How to render the MFA code field. "input" (HTML input element) or "custom" (custom HTML) 'field_type' => 'input', // The type attribute for the HTML input box. Typically "text" or "password". Use any HTML5 input type. 'input_type' => 'password', // Placeholder text for the HTML input box. Leave empty if you don't need it. 'placeholder' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_PLACEHOLDER'), // Label to show above the HTML input box. Leave empty if you don't need it. 'label' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_LABEL'), // Custom HTML. Only used when field_type = custom. 'html' => '', // Custom HTML to display below the MFA form 'post_message' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_POSTMESSAGE'), ] ) ); } /** * Returns the information which allows Joomla to render the MFA setup page. This is the page * which allows the user to add or modify a MFA Method for their user account. If the record * does not correspond to your plugin return an empty array. * * @param GetSetup $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorGetSetup(GetSetup $event): void { /** @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); /** * Return the parameters used to render the GUI. * * Some MFA Methods need to display a different interface before and after the setup. For example, when setting * up Google Authenticator or a hardware OTP dongle you need the user to enter a MFA code to verify they are in * possession of a correctly configured device. After the setup is complete you don't want them to see that * field again. In the first state you could use the tabular_data to display the setup values, pre_message to * display the QR code and field_type=input to let the user enter the MFA code. In the second state do the same * BUT set field_type=custom, set html='' and show_submit=false to effectively hide the setup form from the * user. */ $event->addResult( new SetupRenderOptions( [ 'default_title' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_DEFAULTTITLE'), 'pre_message' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_SETUP_PREMESSAGE'), 'field_type' => 'input', 'input_type' => 'password', 'input_value' => $options->fixed_code, 'placeholder' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_PLACEHOLDER'), 'label' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_LABEL'), 'post_message' => Text::_('PLG_MULTIFACTORAUTH_FIXED_LBL_SETUP_POSTMESSAGE'), ] ) ); } /** * Parse the input from the MFA setup page and return the configuration information to be saved to the database. If * the information is invalid throw a RuntimeException to signal the need to display the editor page again. The * message of the exception will be displayed to the user. If the record does not correspond to your plugin return * an empty array. * * @param SaveSetup $event The event we are handling * * @return void The configuration data to save to the database * @since 4.2.0 */ public function onUserMultifactorSaveSetup(SaveSetup $event): void { /** * @var MfaTable $record The record currently selected by the user. * @var Input $input The user input you are going to take into account. */ $record = $event['record']; $input = $event['input']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); // Merge with the submitted form data $code = $input->get('code', $options->fixed_code, 'raw'); // Make sure the code is not empty if (empty($code)) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_FIXED_ERR_EMPTYCODE')); } // Return the configuration to be serialized $event->addResult(['fixed_code' => $code]); } /** * Validates the Multi-factor Authentication code submitted by the user in the Multi-Factor * Authentication. If the record does not correspond to your plugin return FALSE. * * @param Validate $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorValidate(Validate $event): void { /** * @var MfaTable $record The MFA Method's record you're validating against * @var User $user The user record * @var string|null $code The submitted code */ $record = $event['record']; $user = $event['user']; $code = $event['code']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { $event->addResult(false); return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); // Double check the MFA Method is for the correct user if ($user->id != $record->user_id) { $event->addResult(false); return; } // Check the MFA code for validity $event->addResult(hash_equals($options->fixed_code, $code ?? '')); } /** * Decodes the options from a record into an options object. * * @param MfaTable $record The record to decode options for * * @return object * @since 4.2.0 */ private function decodeRecordOptions(MfaTable $record): object { $options = [ 'fixed_code' => '', ]; if (!empty($record->options)) { $recordOptions = $record->options; $options = array_merge($options, $recordOptions); } return (object) $options; } } PK!}^-multifactorauth/yubikey/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') || die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Multifactorauth\Yubikey\Extension\Yubikey; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.2.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $config = (array) PluginHelper::getPlugin('multifactorauth', 'yubikey'); $subject = $container->get(DispatcherInterface::class); $plugin = new Yubikey($subject, $config); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!=z#multifactorauth/yubikey/yubikey.xmlnu[ plg_multifactorauth_yubikey Joomla! Project 2013-09 (C) 2013 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.2.0 PLG_MULTIFACTORAUTH_YUBIKEY_XML_DESCRIPTION Joomla\Plugin\Multifactorauth\Yubikey services src language/en-GB/plg_multifactorauth_yubikey.ini language/en-GB/plg_multifactorauth_yubikey.sys.ini PK!C0RR1multifactorauth/yubikey/src/Extension/Yubikey.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Multifactorauth\Yubikey\Extension; use Exception; use Joomla\CMS\Event\MultiFactor\Captive; use Joomla\CMS\Event\MultiFactor\GetMethod; use Joomla\CMS\Event\MultiFactor\GetSetup; use Joomla\CMS\Event\MultiFactor\SaveSetup; use Joomla\CMS\Event\MultiFactor\Validate; use Joomla\CMS\Http\HttpFactory; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\User; use Joomla\Component\Users\Administrator\DataShape\CaptiveRenderOptions; use Joomla\Component\Users\Administrator\DataShape\MethodDescriptor; use Joomla\Component\Users\Administrator\DataShape\SetupRenderOptions; use Joomla\Component\Users\Administrator\Helper\Mfa as MfaHelper; use Joomla\Component\Users\Administrator\Table\MfaTable; use Joomla\Event\SubscriberInterface; use Joomla\Input\Input; use RuntimeException; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! Multi-factor Authentication using Yubikey Plugin * * @since 4.2.0 */ class Yubikey extends CMSPlugin implements SubscriberInterface { /** * Affects constructor behavior. If true, language files will be loaded automatically. * * @var boolean * @since 3.2 */ protected $autoloadLanguage = true; /** * The MFA Method name handled by this plugin * * @var string * @since 4.2.0 */ private $mfaMethodName = 'yubikey'; /** * Should I try to detect and register legacy event listeners, i.e. methods which accept unwrapped arguments? While * this maintains a great degree of backwards compatibility to Joomla! 3.x-style plugins it is much slower. You are * advised to implement your plugins using proper Listeners, methods accepting an AbstractEvent as their sole * parameter, for best performance. Also bear in mind that Joomla! 5.x onwards will only allow proper listeners, * removing support for legacy Listeners. * * @var boolean * @since 4.2.0 * * @deprecated 4.3 will be removed in 6.0 * Implement your plugin methods accepting an AbstractEvent object * Example: * onEventTriggerName(AbstractEvent $event) { * $context = $event->getArgument(...); * } */ protected $allowLegacyListeners = false; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.2.0 */ public static function getSubscribedEvents(): array { return [ 'onUserMultifactorGetMethod' => 'onUserMultifactorGetMethod', 'onUserMultifactorCaptive' => 'onUserMultifactorCaptive', 'onUserMultifactorGetSetup' => 'onUserMultifactorGetSetup', 'onUserMultifactorSaveSetup' => 'onUserMultifactorSaveSetup', 'onUserMultifactorValidate' => 'onUserMultifactorValidate', ]; } /** * Gets the identity of this MFA Method * * @param GetMethod $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorGetMethod(GetMethod $event): void { $event->addResult( new MethodDescriptor( [ 'name' => $this->mfaMethodName, 'display' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_METHOD_TITLE'), 'shortinfo' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_SHORTINFO'), 'image' => 'media/plg_multifactorauth_yubikey/images/yubikey.svg', 'allowEntryBatching' => true, ] ) ); } /** * Returns the information which allows Joomla to render the Captive MFA page. This is the page * which appears right after you log in and asks you to validate your login with MFA. * * @param Captive $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorCaptive(Captive $event): void { /** * @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } $event->addResult( new CaptiveRenderOptions( [ // Custom HTML to display above the MFA form 'pre_message' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_CAPTIVE_PROMPT'), // How to render the MFA code field. "input" (HTML input element) or "custom" (custom HTML) 'field_type' => 'input', // The type attribute for the HTML input box. Typically "text" or "password". Use any HTML5 input type. 'input_type' => 'text', // Placeholder text for the HTML input box. Leave empty if you don't need it. 'placeholder' => '', // Label to show above the HTML input box. Leave empty if you don't need it. 'label' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_CODE_LABEL'), // Custom HTML. Only used when field_type = custom. 'html' => '', // Custom HTML to display below the MFA form 'post_message' => '', // Allow authentication against all entries of this MFA Method. 'allowEntryBatching' => 1, ] ) ); } /** * Returns the information which allows Joomla to render the MFA setup page. This is the page * which allows the user to add or modify a MFA Method for their user account. If the record * does not correspond to your plugin return an empty array. * * @param GetSetup $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorGetSetup(GetSetup $event): void { /** * @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $keyID = $options['id'] ?? ''; if (empty($keyID)) { $event->addResult( new SetupRenderOptions( [ 'default_title' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_METHOD_TITLE'), 'pre_message' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_LBL_SETUP_INSTRUCTIONS'), 'field_type' => 'input', 'input_type' => 'text', 'input_value' => $keyID, 'placeholder' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_LBL_SETUP_PLACEHOLDER'), 'label' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_LBL_SETUP_LABEL'), ] ) ); } else { $event->addResult( new SetupRenderOptions( [ 'default_title' => Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_METHOD_TITLE'), 'pre_message' => Text::sprintf('PLG_MULTIFACTORAUTH_YUBIKEY_LBL_AFTERSETUP_INSTRUCTIONS', $keyID), 'input_type' => 'hidden', ] ) ); } } /** * Parse the input from the MFA setup page and return the configuration information to be saved to the database. If * the information is invalid throw a RuntimeException to signal the need to display the editor page again. The * message of the exception will be displayed to the user. If the record does not correspond to your plugin return * an empty array. * * @param SaveSetup $event The event we are handling * * @return void The configuration data to save to the database * @throws \Exception * @since 4.2.0 */ public function onUserMultifactorSaveSetup(SaveSetup $event): void { /** * @var MfaTable $record The record currently selected by the user. * @var Input $input The user input you are going to take into account. */ $record = $event['record']; $input = $event['input']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $keyID = $options['id'] ?? ''; $isKeyAlreadySetup = !empty($keyID); /** * If the submitted code is 12 characters and identical to our existing key there is no change, perform no * further checks. */ $code = $input->getString('code'); if ($isKeyAlreadySetup || ((strlen($code) == 12) && ($code == $keyID))) { $event->addResult($options); return; } // If an empty code or something other than 44 characters was submitted I'm not having any of this! if (empty($code) || (strlen($code) != 44)) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_ERR_VALIDATIONFAILED'), 500); } // Validate the code $isValid = $this->validateYubikeyOtp($code); if (!$isValid) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_ERR_VALIDATIONFAILED'), 500); } // The code is valid. Keep the Yubikey ID (first twelve characters) $keyID = substr($code, 0, 12); // Return the configuration to be serialized $event->addResult(['id' => $keyID]); } /** * Validates the Multi-factor Authentication code submitted by the user in the Multi-Factor * Authentication page. If the record does not correspond to your plugin return FALSE. * * @param Validate $event The event we are handling * * @return void * @throws \Exception * @since 4.2.0 */ public function onUserMultifactorValidate(Validate $event): void { /** * @var MfaTable $record The MFA Method's record you're validating against * @var User $user The user record * @var string $code The submitted code */ $record = $event['record']; $user = $event['user']; $code = $event['code']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { $event->addResult(false); return; } // Double check the MFA Method is for the correct user if ($user->id != $record->user_id) { $event->addResult(false); return; } try { $records = MfaHelper::getUserMfaRecords($record->user_id); $records = array_filter( $records, function ($rec) use ($record) { return $rec->method === $record->method; } ); } catch (\Exception $e) { $records = []; } // Loop all records, stop if at least one matches $result = array_reduce( $records, function (bool $carry, $aRecord) use ($code) { return $carry || $this->validateAgainstRecord($aRecord, $code); }, false ); $event->addResult($result); } /** * Validates a Yubikey OTP against the Yubikey servers * * @param string $otp The OTP generated by your Yubikey * * @return boolean True if it's a valid OTP * @throws \Exception * @since 4.2.0 */ private function validateYubikeyOtp(string $otp): bool { // Let the user define a client ID and a secret key in the plugin's configuration $clientID = $this->params->get('client_id', 1); $secretKey = $this->params->get('secret', ''); $serverQueue = trim($this->params->get('servers', '')); if (!empty($serverQueue)) { $serverQueue = explode("\r", $serverQueue); } if (empty($serverQueue)) { $serverQueue = [ 'https://api.yubico.com/wsapi/2.0/verify', 'https://api2.yubico.com/wsapi/2.0/verify', 'https://api3.yubico.com/wsapi/2.0/verify', 'https://api4.yubico.com/wsapi/2.0/verify', 'https://api5.yubico.com/wsapi/2.0/verify', ]; } shuffle($serverQueue); $gotResponse = false; $http = HttpFactory::getHttp(); $token = $this->getApplication()->getFormToken(); $nonce = md5($token . uniqid(random_int(0, mt_getrandmax()))); $response = null; while (!$gotResponse && !empty($serverQueue)) { $server = array_shift($serverQueue); $uri = new Uri($server); // The client ID for signing the response $uri->setVar('id', $clientID); // The OTP we read from the user $uri->setVar('otp', $otp); // This prevents a REPLAYED_OTP status if the token doesn't change after a user submits an invalid OTP $uri->setVar('nonce', $nonce); // Minimum service level required: 50% (at least 50% of the YubiCloud servers must reply positively for the // OTP to validate) $uri->setVar('sl', 50); // Timeout waiting for YubiCloud servers to reply: 5 seconds. $uri->setVar('timeout', 5); // Set up the optional HMAC-SHA1 signature for the request. $this->signRequest($uri, $secretKey); if ($uri->hasVar('h')) { $uri->setVar('h', urlencode($uri->getVar('h'))); } try { $response = $http->get($uri->toString(), [], 6); if (!empty($response)) { $gotResponse = true; } else { continue; } } catch (\Exception $exc) { // No response, continue with the next server continue; } } if (empty($response)) { $gotResponse = false; } // No server replied; we can't validate this OTP if (!$gotResponse) { return false; } // Parse response $lines = explode("\n", $response->body); $data = []; foreach ($lines as $line) { $line = trim($line); $parts = explode('=', $line, 2); if (count($parts) < 2) { continue; } $data[$parts[0]] = $parts[1]; } // Validate the signature $h = $data['h'] ?? null; $fakeUri = Uri::getInstance('http://www.example.com'); $fakeUri->setQuery($data); $this->signRequest($fakeUri, $secretKey); $calculatedH = $fakeUri->getVar('h', null); if ($calculatedH != $h) { return false; } // Validate the response - We need an OK message reply if ($data['status'] !== 'OK') { return false; } // Validate the response - We need a confidence level over 50% if ($data['sl'] < 50) { return false; } // Validate the response - The OTP must match if ($data['otp'] != $otp) { return false; } // Validate the response - The token must match if ($data['nonce'] != $nonce) { return false; } return true; } /** * Sign the request to YubiCloud. * * @param Uri $uri The request URI to sign * @param string $secret The secret key to sign with * * @return void * @since 4.2.0 * * @see https://developers.yubico.com/yubikey-val/Validation_Protocol_V2.0.html */ private function signRequest(Uri $uri, string $secret): void { // Make sure we have an encoding secret $secret = trim($secret); if (empty($secret)) { return; } // I will need base64 encoding and decoding if (!function_exists('base64_encode') || !function_exists('base64_decode')) { return; } // I need HMAC-SHA-1 support. Therefore I check for HMAC and SHA1 support in the PHP 'hash' extension. if (!function_exists('hash_hmac') || !function_exists('hash_algos')) { return; } $algos = hash_algos(); if (!in_array('sha1', $algos)) { return; } // Get the parameters /** @var array $vars I have to explicitly state the type because the Joomla docblock is wrong :( */ $vars = $uri->getQuery(true); // 'h' is the hash and it doesn't participate in the calculation of itself. if (isset($vars['h'])) { unset($vars['h']); } // Alphabetically sort the set of key/value pairs by key order. ksort($vars); /** * Construct a single line with each ordered key/value pair concatenated using &, and each key and value * concatenated with =. Do not add any line breaks. Do not add whitespace. * * Now, if you thought I can't really write PHP code, a.k.a. why not use http_build_query, read on. * * The way YubiKey expects the query to be built is UTTERLY WRONG. They are doing string concatenation, not * URL query building! Therefore you cannot use http_build_query(). Instead, you need to use dumb string * concatenation. I kid you not. If you want to laugh (or cry) read their Auth_Yubico class. It's 1998 all over * again. */ $stringToSign = ''; foreach ($vars as $k => $v) { $stringToSign .= '&' . $k . '=' . $v; } $stringToSign = ltrim($stringToSign, '&'); /** * Apply the HMAC-SHA-1 algorithm on the line as an octet string using the API key as key (remember to * base64decode the API key obtained from Yubico). */ $decodedKey = base64_decode($secret); $hash = hash_hmac('sha1', $stringToSign, $decodedKey, true); /** * Base 64 encode the resulting value according to RFC 4648, for example, t2ZMtKeValdA+H0jVpj3LIichn4= */ $h = base64_encode($hash); /** * Append the value under key h to the message. */ $uri->setVar('h', $h); } /** * Decodes the options from a record into an options object. * * @param MfaTable $record The record to decode * * @return array * @since 4.2.0 */ private function decodeRecordOptions(MfaTable $record): array { $options = [ 'id' => '', ]; if (!empty($record->options)) { $recordOptions = $record->options; $options = array_merge($options, $recordOptions); } return $options; } /** * @param MfaTable $record The record to validate against * @param string $code The code given to us by the user * * @return boolean * @throws \Exception * @since 4.2.0 */ private function validateAgainstRecord(MfaTable $record, string $code): bool { // Load the options from the record (if any) $options = $this->decodeRecordOptions($record); $keyID = $options['id'] ?? ''; // If there is no key in the options throw an error if (empty($keyID)) { return false; } // If the submitted code is empty throw an error if (empty($code)) { return false; } // If the submitted code length is wrong throw an error if (strlen($code) != 44) { return false; } // If the submitted code's key ID does not match the stored throw an error if (substr($code, 0, 12) != $keyID) { return false; } // Check the OTP code for validity return $this->validateYubikeyOtp($code); } } PK!d.multifactorauth/webauthn/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') || die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\User\UserFactoryInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Multifactorauth\Webauthn\Extension\Webauthn; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.2.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $config = (array) PluginHelper::getPlugin('multifactorauth', 'webauthn'); $subject = $container->get(DispatcherInterface::class); $plugin = new Webauthn($subject, $config); $plugin->setApplication(Factory::getApplication()); $plugin->setUserFactory($container->get(UserFactoryInterface::class)); return $plugin; } ); } }; PK!ɧ%multifactorauth/webauthn/webauthn.xmlnu[ plg_multifactorauth_webauthn Joomla! Project 2022-05 (C) 2022 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.2.0 PLG_MULTIFACTORAUTH_WEBAUTHN_XML_DESCRIPTION Joomla\Plugin\Multifactorauth\Webauthn services src tmpl language/en-GB/plg_multifactorauth_webauthn.ini language/en-GB/plg_multifactorauth_webauthn.sys.ini PK!a)multifactorauth/webauthn/tmpl/default.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Prevent direct access defined('_JEXEC') || die; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; // This method is only available on HTTPS if (Uri::getInstance()->getScheme() !== 'https') : ?>

    getApplication()->getDocument()->getWebAssetManager()->useScript('plg_multifactorauth_webauthn.webauthn'); ?>

    PK!yK%K%5multifactorauth/webauthn/src/CredentialRepository.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Multifactorauth\Webauthn; use Joomla\CMS\Factory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\User\UserFactoryInterface; use Joomla\Component\Users\Administrator\Helper\Mfa as MfaHelper; use Joomla\Component\Users\Administrator\Table\MfaTable; use Webauthn\AttestationStatement\AttestationStatement; use Webauthn\AttestedCredentialData; use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialSource; use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\PublicKeyCredentialUserEntity; use Webauthn\TrustPath\EmptyTrustPath; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Implementation of the credentials repository for the WebAuthn library. * * Important assumption: interaction with Webauthn through the library is only performed for the currently logged in * user. Therefore all Methods which take a credential ID work by checking the Joomla MFA records of the current * user only. This is a necessity. The records are stored encrypted, therefore we cannot do a partial search in the * table. We have to load the records, decrypt them and inspect them. We cannot do that for thousands of records but * we CAN do that for the few records each user has under their account. * * This behavior can be changed by passing a user ID in the constructor of the class. * * @since 4.2.0 */ class CredentialRepository implements PublicKeyCredentialSourceRepository { /** * The user ID we will operate with * * @var integer * @since 4.2.0 */ private $userId = 0; /** * CredentialRepository constructor. * * @param int $userId The user ID this repository will be working with. * * @throws \Exception * @since 4.2.0 */ public function __construct(int $userId = 0) { if (empty($userId)) { $user = Factory::getApplication()->getIdentity() ?: Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById(0); $userId = $user->id; } $this->userId = $userId; } /** * Finds a WebAuthn record given a credential ID * * @param string $publicKeyCredentialId The public credential ID to look for * * @return PublicKeyCredentialSource|null * @since 4.2.0 */ public function findOneByCredentialId(string $publicKeyCredentialId): ?PublicKeyCredentialSource { $publicKeyCredentialUserEntity = new PublicKeyCredentialUserEntity('', $this->userId, '', ''); $credentials = $this->findAllForUserEntity($publicKeyCredentialUserEntity); foreach ($credentials as $record) { if ($record->getAttestedCredentialData()->getCredentialId() != $publicKeyCredentialId) { continue; } return $record; } return null; } /** * Find all WebAuthn entries given a user entity * * @param PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity The user entity to search by * * @return array|PublicKeyCredentialSource[] * @throws \Exception * @since 4.2.0 */ public function findAllForUserEntity(PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity): array { if (empty($publicKeyCredentialUserEntity)) { $userId = $this->userId; } else { $userId = $publicKeyCredentialUserEntity->getId(); } $return = []; $results = MfaHelper::getUserMfaRecords($userId); if (count($results) < 1) { return $return; } /** @var MfaTable $result */ foreach ($results as $result) { $options = $result->options; if (!is_array($options) || empty($options)) { continue; } if (!isset($options['attested']) && !isset($options['pubkeysource'])) { continue; } if (isset($options['attested']) && is_string($options['attested'])) { $options['attested'] = json_decode($options['attested'], true); $return[$result->id] = $this->attestedCredentialToPublicKeyCredentialSource( AttestedCredentialData::createFromArray($options['attested']), $userId ); } elseif (isset($options['pubkeysource']) && is_string($options['pubkeysource'])) { $options['pubkeysource'] = json_decode($options['pubkeysource'], true); $return[$result->id] = PublicKeyCredentialSource::createFromArray($options['pubkeysource']); } elseif (isset($options['pubkeysource']) && is_array($options['pubkeysource'])) { $return[$result->id] = PublicKeyCredentialSource::createFromArray($options['pubkeysource']); } } return $return; } /** * Converts a legacy AttestedCredentialData object stored in the database into a PublicKeyCredentialSource object. * * This makes several assumptions which can be problematic and the reason why the WebAuthn library version 2 moved * away from attested credentials to public key credential sources: * * - The credential is always of the public key type (that's safe as the only option supported) * - You can access it with any kind of authenticator transport: USB, NFC, Internal or Bluetooth LE (possibly * dangerous) * - There is no attestations (generally safe since browsers don't seem to support attestation yet) * - There is no trust path (generally safe since browsers don't seem to provide one) * - No counter was stored (dangerous since it can lead to replay attacks). * * @param AttestedCredentialData $record Legacy attested credential data object * @param int $userId User ID we are getting the credential source for * * @return PublicKeyCredentialSource * @since 4.2.0 */ private function attestedCredentialToPublicKeyCredentialSource(AttestedCredentialData $record, int $userId): PublicKeyCredentialSource { return new PublicKeyCredentialSource( $record->getCredentialId(), PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, [ PublicKeyCredentialDescriptor::AUTHENTICATOR_TRANSPORT_USB, PublicKeyCredentialDescriptor::AUTHENTICATOR_TRANSPORT_NFC, PublicKeyCredentialDescriptor::AUTHENTICATOR_TRANSPORT_INTERNAL, PublicKeyCredentialDescriptor::AUTHENTICATOR_TRANSPORT_BLE, ], AttestationStatement::TYPE_NONE, new EmptyTrustPath(), $record->getAaguid(), $record->getCredentialPublicKey(), $userId, 0 ); } /** * Save a WebAuthn record * * @param PublicKeyCredentialSource $publicKeyCredentialSource The record to save * * @return void * @throws \Exception * @since 4.2.0 */ public function saveCredentialSource(PublicKeyCredentialSource $publicKeyCredentialSource): void { // I can only create or update credentials for the user this class was created for if ($publicKeyCredentialSource->getUserHandle() != $this->userId) { throw new \RuntimeException('Cannot create or update WebAuthn credentials for a different user.', 403); } // Do I have an existing record for this credential? $recordId = null; $publicKeyCredentialUserEntity = new PublicKeyCredentialUserEntity('', $this->userId, '', ''); $credentials = $this->findAllForUserEntity($publicKeyCredentialUserEntity); foreach ($credentials as $id => $record) { if ($record->getAttestedCredentialData()->getCredentialId() != $publicKeyCredentialSource->getAttestedCredentialData()->getCredentialId()) { continue; } $recordId = $id; break; } // Create or update a record /** @var MVCFactoryInterface $factory */ $factory = Factory::getApplication()->bootComponent('com_users')->getMVCFactory(); /** @var MfaTable $mfaTable */ $mfaTable = $factory->createTable('Mfa', 'Administrator'); if ($recordId) { $mfaTable->load($recordId); $options = $mfaTable->options; if (isset($options['attested'])) { unset($options['attested']); } $options['pubkeysource'] = $publicKeyCredentialSource; $mfaTable->save( [ 'options' => $options, ] ); } else { $mfaTable->reset(); $mfaTable->save( [ 'user_id' => $this->userId, 'title' => 'WebAuthn auto-save', 'method' => 'webauthn', 'default' => 0, 'options' => ['pubkeysource' => $publicKeyCredentialSource], ] ); } } } PK!628C8C3multifactorauth/webauthn/src/Extension/Webauthn.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Multifactorauth\Webauthn\Extension; use Exception; use Joomla\CMS\Event\MultiFactor\Captive; use Joomla\CMS\Event\MultiFactor\GetMethod; use Joomla\CMS\Event\MultiFactor\GetSetup; use Joomla\CMS\Event\MultiFactor\SaveSetup; use Joomla\CMS\Event\MultiFactor\Validate; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\User; use Joomla\CMS\User\UserFactoryAwareTrait; use Joomla\Component\Users\Administrator\DataShape\CaptiveRenderOptions; use Joomla\Component\Users\Administrator\DataShape\MethodDescriptor; use Joomla\Component\Users\Administrator\DataShape\SetupRenderOptions; use Joomla\Component\Users\Administrator\Table\MfaTable; use Joomla\Event\SubscriberInterface; use Joomla\Input\Input; use Joomla\Plugin\Multifactorauth\Webauthn\Helper\Credentials; use RuntimeException; use Webauthn\PublicKeyCredentialRequestOptions; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla Multi-factor Authentication plugin for WebAuthn * * @since 4.2.0 */ class Webauthn extends CMSPlugin implements SubscriberInterface { use UserFactoryAwareTrait; /** * Auto-load the plugin's language files * * @var boolean * @since 4.2.0 */ protected $autoloadLanguage = true; /** * The MFA Method name handled by this plugin * * @var string * @since 4.2.0 */ private $mfaMethodName = 'webauthn'; /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.2.0 */ public static function getSubscribedEvents(): array { return [ 'onUserMultifactorGetMethod' => 'onUserMultifactorGetMethod', 'onUserMultifactorCaptive' => 'onUserMultifactorCaptive', 'onUserMultifactorGetSetup' => 'onUserMultifactorGetSetup', 'onUserMultifactorSaveSetup' => 'onUserMultifactorSaveSetup', 'onUserMultifactorValidate' => 'onUserMultifactorValidate', ]; } /** * Gets the identity of this MFA Method * * @param GetMethod $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorGetMethod(GetMethod $event): void { $event->addResult( new MethodDescriptor( [ 'name' => $this->mfaMethodName, 'display' => Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_DISPLAYEDAS'), 'shortinfo' => Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_SHORTINFO'), 'image' => 'media/plg_multifactorauth_webauthn/images/webauthn.svg', 'allowMultiple' => true, 'allowEntryBatching' => true, ] ) ); } /** * Returns the information which allows Joomla to render the MFA setup page. This is the page * which allows the user to add or modify a MFA Method for their user account. If the record * does not correspond to your plugin return an empty array. * * @param GetSetup $event The event we are handling * * @return void * @throws \Exception * @since 4.2.0 */ public function onUserMultifactorGetSetup(GetSetup $event): void { /** * @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Get some values assuming that we are NOT setting up U2F (the key is already registered) $submitClass = ''; $submitIcon = 'icon icon-ok'; $submitText = 'JSAVE'; $preMessage = Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_CONFIGURED'); $type = 'input'; $html = ''; $hiddenData = []; /** * If there are no authenticators set up yet I need to show a different message and take a different action when * my user clicks the submit button. */ if (!is_array($record->options) || empty($record->options['credentialId'] ?? '')) { $document = $this->getApplication()->getDocument(); $wam = $document->getWebAssetManager(); $wam->getRegistry()->addExtensionRegistryFile('plg_multifactorauth_webauthn'); $layoutPath = PluginHelper::getLayoutPath('multifactorauth', 'webauthn'); ob_start(); include $layoutPath; $html = ob_get_clean(); $type = 'custom'; // Load JS translations Text::script('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NOTAVAILABLE_HEAD'); $document->addScriptOptions('com_users.pagetype', 'setup', false); // Save the WebAuthn request to the session $user = $this->getApplication()->getIdentity() ?: $this->getUserFactory()->loadUserById(0); $hiddenData['pkRequest'] = base64_encode(Credentials::requestAttestation($user)); // Special button handling $submitClass = "multifactorauth_webauthn_setup"; $submitIcon = 'icon icon-lock'; $submitText = 'PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_REGISTERKEY'; // Message to display $preMessage = Text::sprintf( 'PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_INSTRUCTIONS', Text::_($submitText) ); } $event->addResult( new SetupRenderOptions( [ 'default_title' => Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_DISPLAYEDAS'), 'pre_message' => $preMessage, 'hidden_data' => $hiddenData, 'field_type' => $type, 'input_type' => 'hidden', 'html' => $html, 'show_submit' => true, 'submit_class' => $submitClass, 'submit_icon' => $submitIcon, 'submit_text' => $submitText, ] ) ); } /** * Parse the input from the MFA setup page and return the configuration information to be saved to the database. If * the information is invalid throw a RuntimeException to signal the need to display the editor page again. The * message of the exception will be displayed to the user. If the record does not correspond to your plugin return * an empty array. * * @param SaveSetup $event The event we are handling * * @return void The configuration data to save to the database * @since 4.2.0 */ public function onUserMultifactorSaveSetup(SaveSetup $event): void { /** * @var MfaTable $record The record currently selected by the user. * @var Input $input The user input you are going to take into account. */ $record = $event['record']; $input = $event['input']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } // Editing an existing authenticator: only the title is saved if (is_array($record->options) && !empty($record->options['credentialId'] ?? '')) { $event->addResult($record->options); return; } $code = $input->get('code', null, 'base64'); $session = $this->getApplication()->getSession(); $registrationRequest = $session->get('plg_multifactorauth_webauthn.publicKeyCredentialCreationOptions', null); // If there was no registration request BUT there is a registration response throw an error if (empty($registrationRequest) && !empty($code)) { throw new \RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'), 403); } // If there is no registration request (and there isn't a registration response) we are just saving the title. if (empty($registrationRequest)) { $event->addResult($record->options); return; } // In any other case try to authorize the registration try { $publicKeyCredentialSource = Credentials::verifyAttestation($code); } catch (\Exception $err) { throw new \RuntimeException($err->getMessage(), 403); } finally { // Unset the request data from the session. $session->set('plg_multifactorauth_webauthn.publicKeyCredentialCreationOptions', null); $session->set('plg_multifactorauth_webauthn.registration_user_id', null); } // Return the configuration to be serialized $event->addResult( [ 'credentialId' => base64_encode($publicKeyCredentialSource->getAttestedCredentialData()->getCredentialId()), 'pubkeysource' => json_encode($publicKeyCredentialSource), 'counter' => 0, ] ); } /** * Returns the information which allows Joomla to render the Captive MFA page. This is the page * which appears right after you log in and asks you to validate your login with MFA. * * @param Captive $event The event we are handling * * @return void * @throws \Exception * @since 4.2.0 */ public function onUserMultifactorCaptive(Captive $event): void { /** * @var MfaTable $record The record currently selected by the user. */ $record = $event['record']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { return; } /** * The following code looks stupid. An explanation is in order. * * What we normally want to do is save the authentication data returned by getAuthenticateData into the session. * This is what is sent to the authenticator through the Javascript API and signed. The signature is posted back * to the form as the "code" which is read by onUserMultifactorauthValidate. That Method will read the authentication * data from the session and pass it along with the key registration data (from the database) and the * authentication response (the "code" submitted in the form) to the WebAuthn library for validation. * * Validation will work as long as the challenge recorded in the encrypted AUTHENTICATION RESPONSE matches, upon * decryption, the challenge recorded in the AUTHENTICATION DATA. * * I observed that for whatever stupid reason the browser was sometimes sending TWO requests to the server's * Captive login page but only rendered the FIRST. This meant that the authentication data sent to the key had * already been overwritten in the session by the "invisible" second request. As a result the challenge would * not match and we'd get a validation error. * * The code below will attempt to read the authentication data from the session first. If it exists it will NOT * try to replace it (technically it replaces it with a copy of the same data - same difference!). If nothing * exists in the session, however, it WILL store the (random seeded) result of the getAuthenticateData Method. * Therefore the first request to the Captive login page will store a new set of authentication data whereas the * second, "invisible", request will just reuse the same data as the first request, fixing the observed issue in * a way that doesn't compromise security. * * In case you are wondering, yes, the data is removed from the session in the onUserMultifactorauthValidate Method. * In fact it's the first thing we do after reading it, preventing constant reuse of the same set of challenges. * * That was fun to debug - for "poke your eyes with a rusty fork" values of fun. */ $session = $this->getApplication()->getSession(); $pkOptionsEncoded = $session->get('plg_multifactorauth_webauthn.publicKeyCredentialRequestOptions', null); $force = $this->getApplication()->getInput()->getInt('force', 0); try { if ($force) { throw new \RuntimeException('Expected exception (good): force a new key request'); } if (empty($pkOptionsEncoded)) { throw new \RuntimeException('Expected exception (good): we do not have a pending key request'); } $serializedOptions = base64_decode($pkOptionsEncoded); $pkOptions = unserialize($serializedOptions); if (!is_object($pkOptions) || empty($pkOptions) || !($pkOptions instanceof PublicKeyCredentialRequestOptions)) { throw new \RuntimeException('The pending key request is corrupt; a new one will be created'); } $pkRequest = json_encode($pkOptions, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } catch (\Exception $e) { $pkRequest = Credentials::requestAssertion($record->user_id); } $document = $this->getApplication()->getDocument(); $wam = $document->getWebAssetManager(); $wam->getRegistry()->addExtensionRegistryFile('plg_multifactorauth_webauthn'); try { $document->addScriptOptions('com_users.authData', base64_encode($pkRequest), false); $layoutPath = PluginHelper::getLayoutPath('multifactorauth', 'webauthn'); ob_start(); include $layoutPath; $html = ob_get_clean(); } catch (\Exception $e) { return; } // Load JS translations Text::script('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NOTAVAILABLE_HEAD'); Text::script('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_NO_STORED_CREDENTIAL'); $document->addScriptOptions('com_users.pagetype', 'validate', false); $event->addResult( new CaptiveRenderOptions( [ 'pre_message' => Text::sprintf( 'PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_INSTRUCTIONS', Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_VALIDATEKEY') ), 'field_type' => 'custom', 'input_type' => 'hidden', 'placeholder' => '', 'label' => '', 'html' => $html, 'post_message' => '', 'hide_submit' => false, 'submit_icon' => 'icon icon-lock', 'submit_text' => 'PLG_MULTIFACTORAUTH_WEBAUTHN_LBL_VALIDATEKEY', 'allowEntryBatching' => true, ] ) ); } /** * Validates the Multi-factor Authentication code submitted by the user in the Multi-Factor * Authentication page. If the record does not correspond to your plugin return FALSE. * * @param Validate $event The event we are handling * * @return void * @since 4.2.0 */ public function onUserMultifactorValidate(Validate $event): void { // This method is only available on HTTPS if (Uri::getInstance()->getScheme() !== 'https') { $event->addResult(false); return; } /** * @var MfaTable $record The MFA Method's record you're validating against * @var User $user The user record * @var string $code The submitted code */ $record = $event['record']; $user = $event['user']; $code = $event['code']; // Make sure we are actually meant to handle this Method if ($record->method != $this->mfaMethodName) { $event->addResult(false); return; } // Double check the MFA Method is for the correct user if ($user->id != $record->user_id) { $event->addResult(false); return; } try { Credentials::verifyAssertion($code); } catch (\Exception $e) { try { $this->getApplication()->enqueueMessage($e->getMessage(), 'error'); } catch (\Exception $e) { } $event->addResult(false); return; } $event->addResult(true); } } PK!\ 53533multifactorauth/webauthn/src/Helper/Credentials.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Multifactorauth\Webauthn\Helper; use Exception; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\User; use Joomla\CMS\User\UserFactoryInterface; use Joomla\Plugin\Multifactorauth\Webauthn\CredentialRepository; use Joomla\Plugin\Multifactorauth\Webauthn\Hotfix\Server; use Joomla\Session\SessionInterface; use Laminas\Diactoros\ServerRequestFactory; use Webauthn\AttestedCredentialData; use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; use Webauthn\AuthenticatorSelectionCriteria; use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialRequestOptions; use Webauthn\PublicKeyCredentialRpEntity; use Webauthn\PublicKeyCredentialSource; use Webauthn\PublicKeyCredentialUserEntity; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Helper class to aid in credentials creation (link an authenticator to a user account) * * @since 4.2.0 */ abstract class Credentials { /** * Authenticator registration step 1: create a public key for credentials attestation. * * The result is a JSON string which can be used in Javascript code with navigator.credentials.create(). * * @param User $user The Joomla user to create the public key for * * @return string * @throws \Exception On error * @since 4.2.0 */ public static function requestAttestation(User $user): string { $publicKeyCredentialCreationOptions = self::getWebauthnServer($user->id) ->generatePublicKeyCredentialCreationOptions( self::getUserEntity($user), PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE, self::getPubKeyDescriptorsForUser($user), new AuthenticatorSelectionCriteria( AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE, false, AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_PREFERRED ), new AuthenticationExtensionsClientInputs() ); // Save data in the session $session = Factory::getApplication()->getSession(); $session->set( 'plg_multifactorauth_webauthn.publicKeyCredentialCreationOptions', base64_encode(serialize($publicKeyCredentialCreationOptions)) ); $session->set('plg_multifactorauth_webauthn.registration_user_id', $user->id); return json_encode($publicKeyCredentialCreationOptions, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } /** * Authenticator registration step 2: verify the credentials attestation by the authenticator * * This returns the attested credential data on success. * * An exception will be returned on error. Also, under very rare conditions, you may receive NULL instead of * attested credential data which means that something was off in the returned data from the browser. * * @param string $data The JSON-encoded data returned by the browser during the authentication flow * * @return AttestedCredentialData|null * @throws \Exception When something does not check out * @since 4.2.0 */ public static function verifyAttestation(string $data): ?PublicKeyCredentialSource { $session = Factory::getApplication()->getSession(); // Retrieve the PublicKeyCredentialCreationOptions object created earlier and perform sanity checks $encodedOptions = $session->get('plg_multifactorauth_webauthn.publicKeyCredentialCreationOptions', null); if (empty($encodedOptions)) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_CREATE_NO_PK')); } try { $publicKeyCredentialCreationOptions = unserialize(base64_decode($encodedOptions)); } catch (\Exception $e) { $publicKeyCredentialCreationOptions = null; } if (!is_object($publicKeyCredentialCreationOptions) || !($publicKeyCredentialCreationOptions instanceof PublicKeyCredentialCreationOptions)) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_CREATE_NO_PK')); } // Retrieve the stored user ID and make sure it's the same one in the request. $storedUserId = $session->get('plg_multifactorauth_webauthn.registration_user_id', 0); $myUser = Factory::getApplication()->getIdentity() ?: Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById(0); $myUserId = $myUser->id; if (($myUser->guest) || ($myUserId != $storedUserId)) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_CREATE_INVALID_USER')); } return self::getWebauthnServer($myUser->id)->loadAndCheckAttestationResponse( base64_decode($data), $publicKeyCredentialCreationOptions, ServerRequestFactory::fromGlobals() ); } /** * Authentication step 1: create a challenge for key verification * * @param int $userId The user ID to create a WebAuthn PK for * * @return string * @throws \Exception On error * @since 4.2.0 */ public static function requestAssertion(int $userId): string { $user = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById($userId); $publicKeyCredentialRequestOptions = self::getWebauthnServer($userId) ->generatePublicKeyCredentialRequestOptions( PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_PREFERRED, self::getPubKeyDescriptorsForUser($user) ); // Save in session. This is used during the verification stage to prevent replay attacks. /** @var SessionInterface $session */ $session = Factory::getApplication()->getSession(); $session->set('plg_multifactorauth_webauthn.publicKeyCredentialRequestOptions', base64_encode(serialize($publicKeyCredentialRequestOptions))); $session->set('plg_multifactorauth_webauthn.userHandle', $userId); $session->set('plg_multifactorauth_webauthn.userId', $userId); // Return the JSON encoded data to the caller return json_encode($publicKeyCredentialRequestOptions, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } /** * Authentication step 2: Checks if the browser's response to our challenge is valid. * * @param string $response Base64-encoded response * * @return void * @throws \Exception When something does not check out. * @since 4.2.0 */ public static function verifyAssertion(string $response): void { /** @var SessionInterface $session */ $session = Factory::getApplication()->getSession(); $encodedPkOptions = $session->get('plg_multifactorauth_webauthn.publicKeyCredentialRequestOptions', null); $userHandle = $session->get('plg_multifactorauth_webauthn.userHandle', null); $userId = $session->get('plg_multifactorauth_webauthn.userId', null); $session->set('plg_multifactorauth_webauthn.publicKeyCredentialRequestOptions', null); $session->set('plg_multifactorauth_webauthn.userHandle', null); $session->set('plg_multifactorauth_webauthn.userId', null); if (empty($userId)) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST')); } // Make sure the user exists $user = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById($userId); if ($user->id != $userId) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST')); } // Make sure the user is ourselves (we cannot perform MFA on behalf of another user!) $currentUser = Factory::getApplication()->getIdentity() ?: Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById(0); if ($currentUser->id != $userId) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST')); } // Make sure the public key credential request options in the session are valid $serializedOptions = base64_decode($encodedPkOptions); $publicKeyCredentialRequestOptions = unserialize($serializedOptions); if ( !is_object($publicKeyCredentialRequestOptions) || empty($publicKeyCredentialRequestOptions) || !($publicKeyCredentialRequestOptions instanceof PublicKeyCredentialRequestOptions) ) { throw new \RuntimeException(Text::_('PLG_MULTIFACTORAUTH_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST')); } // Unserialize the browser response data $data = base64_decode($response); self::getWebauthnServer($user->id)->loadAndCheckAssertionResponse( $data, $publicKeyCredentialRequestOptions, self::getUserEntity($user), ServerRequestFactory::fromGlobals() ); } /** * Get the user's avatar (through Gravatar) * * @param User $user The Joomla user object * @param int $size The dimensions of the image to fetch (default: 64 pixels) * * @return string The URL to the user's avatar * * @since 4.2.0 */ private static function getAvatar(User $user, int $size = 64) { $scheme = Uri::getInstance()->getScheme(); $subdomain = ($scheme == 'https') ? 'secure' : 'www'; return sprintf('%s://%s.gravatar.com/avatar/%s.jpg?s=%u&d=mm', $scheme, $subdomain, md5($user->email), $size); } /** * Get a WebAuthn user entity for a Joomla user * * @param User $user The user to get an entity for * * @return PublicKeyCredentialUserEntity * @since 4.2.0 */ private static function getUserEntity(User $user): PublicKeyCredentialUserEntity { return new PublicKeyCredentialUserEntity( $user->username, $user->id, $user->name, self::getAvatar($user, 64) ); } /** * Get the WebAuthn library server object * * @param int|null $userId The user ID holding the list of valid authenticators * * @return Server * @since 4.2.0 */ private static function getWebauthnServer(?int $userId): Server { /** @var CMSApplication $app */ try { $app = Factory::getApplication(); $siteName = $app->get('sitename'); } catch (\Exception $e) { $siteName = 'Joomla! Site'; } // Credentials repository $repository = new CredentialRepository($userId); // Relaying Party -- Our site $rpEntity = new PublicKeyCredentialRpEntity( $siteName ?? 'Joomla! Site', Uri::getInstance()->toString(['host']), '' ); $refClass = new \ReflectionClass(Server::class); $refConstructor = $refClass->getConstructor(); $params = $refConstructor->getParameters(); if (count($params) === 3) { // WebAuthn library 2, 3 $server = new Server($rpEntity, $repository, null); } else { // WebAuthn library 4 (based on the deprecated comments in library version 3) $server = new Server($rpEntity, $repository); } // Ed25519 is only available with libsodium if (!function_exists('sodium_crypto_sign_seed_keypair')) { $server->setSelectedAlgorithms(['RS256', 'RS512', 'PS256', 'PS512', 'ES256', 'ES512']); } return $server; } /** * Returns an array of the PK credential descriptors (registered authenticators) for the given user. * * @param User $user The user to get the descriptors for * * @return PublicKeyCredentialDescriptor[] * @since 4.2.0 */ private static function getPubKeyDescriptorsForUser(User $user): array { $userEntity = self::getUserEntity($user); $repository = new CredentialRepository($user->id); $descriptors = []; $records = $repository->findAllForUserEntity($userEntity); foreach ($records as $record) { $descriptors[] = $record->getPublicKeyCredentialDescriptor(); } return $descriptors; } } PK!##Jmultifactorauth/webauthn/src/Hotfix/FidoU2FAttestationStatementSupport.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt * @copyright (C) 2014-2019 Spomky-Labs * @license This software may be modified and distributed under the terms * of the MIT license. * See libraries/vendor/web-auth/webauthn-lib/LICENSE */ namespace Joomla\Plugin\Multifactorauth\Webauthn\Hotfix; use Assert\Assertion; use CBOR\Decoder; use CBOR\MapObject; use CBOR\OtherObject\OtherObjectManager; use CBOR\Tag\TagObjectManager; use Cose\Key\Ec2Key; use Webauthn\AttestationStatement\AttestationStatement; use Webauthn\AttestationStatement\AttestationStatementSupport; use Webauthn\AuthenticatorData; use Webauthn\CertificateToolbox; use Webauthn\MetadataService\MetadataStatementRepository; use Webauthn\StringStream; use Webauthn\TrustPath\CertificateTrustPath; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * We had to fork the key attestation support object from the WebAuthn server package to address an * issue with PHP 8. * * We are currently using an older version of the WebAuthn library (2.x) which was written before * PHP 8 was developed. We cannot upgrade the WebAuthn library to a newer major version because of * Joomla's Semantic Versioning promise. * * The FidoU2FAttestationStatementSupport class forces an assertion on the result of the * openssl_pkey_get_public() function, assuming it will return a resource. However, starting with * PHP 8.0 this function returns an OpenSSLAsymmetricKey object and the assertion fails. As a * result, you cannot use Android or FIDO U2F keys with WebAuthn. * * The assertion check is in a private method, therefore we have to fork both attestation support * class to change the assertion. The assertion takes place through a third party library we cannot * (and should not!) modify. * * @since 4.2.0 * * @deprecated 4.2 will be removed in 6.0 * Will be removed without replacement * We will upgrade the WebAuthn library to version 3 or later and this will go away. */ final class FidoU2FAttestationStatementSupport implements AttestationStatementSupport { /** * @var Decoder * @since 4.2.0 */ private $decoder; /** * @var MetadataStatementRepository|null * @since 4.2.0 */ private $metadataStatementRepository; /** * @param Decoder|null $decoder Obvious * @param MetadataStatementRepository|null $metadataStatementRepository Obvious * * @since 4.2.0 */ public function __construct( ?Decoder $decoder = null, ?MetadataStatementRepository $metadataStatementRepository = null ) { if ($decoder !== null) { @trigger_error('The argument "$decoder" is deprecated since 2.1 and will be removed in v3.0. Set null instead', E_USER_DEPRECATED); } if ($metadataStatementRepository === null) { @trigger_error( 'Setting "null" for argument "$metadataStatementRepository" is deprecated since 2.1 and will be mandatory in v3.0.', E_USER_DEPRECATED ); } $this->decoder = $decoder ?? new Decoder(new TagObjectManager(), new OtherObjectManager()); $this->metadataStatementRepository = $metadataStatementRepository; } /** * @return string * @since 4.2.0 */ public function name(): string { return 'fido-u2f'; } /** * @param array $attestation Obvious * * @return AttestationStatement * @throws \Assert\AssertionFailedException * * @since 4.2.0 */ public function load(array $attestation): AttestationStatement { Assertion::keyExists($attestation, 'attStmt', 'Invalid attestation object'); foreach (['sig', 'x5c'] as $key) { Assertion::keyExists($attestation['attStmt'], $key, sprintf('The attestation statement value "%s" is missing.', $key)); } $certificates = $attestation['attStmt']['x5c']; Assertion::isArray($certificates, 'The attestation statement value "x5c" must be a list with one certificate.'); Assertion::count($certificates, 1, 'The attestation statement value "x5c" must be a list with one certificate.'); Assertion::allString($certificates, 'The attestation statement value "x5c" must be a list with one certificate.'); reset($certificates); $certificates = CertificateToolbox::convertAllDERToPEM($certificates); $this->checkCertificate($certificates[0]); return AttestationStatement::createBasic($attestation['fmt'], $attestation['attStmt'], new CertificateTrustPath($certificates)); } /** * @param string $clientDataJSONHash Obvious * @param AttestationStatement $attestationStatement Obvious * @param AuthenticatorData $authenticatorData Obvious * * @return boolean * @throws \Assert\AssertionFailedException * @since 4.2.0 */ public function isValid( string $clientDataJSONHash, AttestationStatement $attestationStatement, AuthenticatorData $authenticatorData ): bool { Assertion::eq( $authenticatorData->getAttestedCredentialData()->getAaguid()->toString(), '00000000-0000-0000-0000-000000000000', 'Invalid AAGUID for fido-u2f attestation statement. Shall be "00000000-0000-0000-0000-000000000000"' ); if ($this->metadataStatementRepository !== null) { CertificateToolbox::checkAttestationMedata( $attestationStatement, $authenticatorData->getAttestedCredentialData()->getAaguid()->toString(), [], $this->metadataStatementRepository ); } $trustPath = $attestationStatement->getTrustPath(); Assertion::isInstanceOf($trustPath, CertificateTrustPath::class, 'Invalid trust path'); $dataToVerify = "\0"; $dataToVerify .= $authenticatorData->getRpIdHash(); $dataToVerify .= $clientDataJSONHash; $dataToVerify .= $authenticatorData->getAttestedCredentialData()->getCredentialId(); $dataToVerify .= $this->extractPublicKey($authenticatorData->getAttestedCredentialData()->getCredentialPublicKey()); return openssl_verify($dataToVerify, $attestationStatement->get('sig'), $trustPath->getCertificates()[0], OPENSSL_ALGO_SHA256) === 1; } /** * @param string|null $publicKey Obvious * * @return string * @throws \Assert\AssertionFailedException * @since 4.2.0 */ private function extractPublicKey(?string $publicKey): string { Assertion::notNull($publicKey, 'The attested credential data does not contain a valid public key.'); $publicKeyStream = new StringStream($publicKey); $coseKey = $this->decoder->decode($publicKeyStream); Assertion::true($publicKeyStream->isEOF(), 'Invalid public key. Presence of extra bytes.'); $publicKeyStream->close(); Assertion::isInstanceOf($coseKey, MapObject::class, 'The attested credential data does not contain a valid public key.'); $coseKey = $coseKey->getNormalizedData(); $ec2Key = new Ec2Key($coseKey + [Ec2Key::TYPE => 2, Ec2Key::DATA_CURVE => Ec2Key::CURVE_P256]); return "\x04" . $ec2Key->x() . $ec2Key->y(); } /** * @param string $publicKey Obvious * * @return void * @throws \Assert\AssertionFailedException * @since 4.2.0 */ private function checkCertificate(string $publicKey): void { try { $resource = openssl_pkey_get_public($publicKey); if (version_compare(PHP_VERSION, '8.0', 'lt')) { Assertion::isResource($resource, 'Unable to read the certificate'); } else { /** @noinspection PhpElementIsNotAvailableInCurrentPhpVersionInspection */ Assertion::isInstanceOf($resource, \OpenSSLAsymmetricKey::class, 'Unable to read the certificate'); } } catch (\Throwable $throwable) { throw new \InvalidArgumentException('Invalid certificate or certificate chain', 0, $throwable); } $details = openssl_pkey_get_details($resource); Assertion::keyExists($details, 'ec', 'Invalid certificate or certificate chain'); Assertion::keyExists($details['ec'], 'curve_name', 'Invalid certificate or certificate chain'); Assertion::eq($details['ec']['curve_name'], 'prime256v1', 'Invalid certificate or certificate chain'); Assertion::keyExists($details['ec'], 'curve_oid', 'Invalid certificate or certificate chain'); Assertion::eq($details['ec']['curve_oid'], '1.2.840.10045.3.1.7', 'Invalid certificate or certificate chain'); } } PK!N,,Mmultifactorauth/webauthn/src/Hotfix/AndroidKeyAttestationStatementSupport.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt * @copyright (C) 2014-2019 Spomky-Labs * @license This software may be modified and distributed under the terms * of the MIT license. * See libraries/vendor/web-auth/webauthn-lib/LICENSE */ namespace Joomla\Plugin\Multifactorauth\Webauthn\Hotfix; use Assert\Assertion; use CBOR\Decoder; use CBOR\OtherObject\OtherObjectManager; use CBOR\Tag\TagObjectManager; use Cose\Algorithms; use Cose\Key\Ec2Key; use Cose\Key\Key; use Cose\Key\RsaKey; use FG\ASN1\ASNObject; use FG\ASN1\ExplicitlyTaggedObject; use FG\ASN1\Universal\OctetString; use FG\ASN1\Universal\Sequence; use Webauthn\AttestationStatement\AttestationStatement; use Webauthn\AttestationStatement\AttestationStatementSupport; use Webauthn\AuthenticatorData; use Webauthn\CertificateToolbox; use Webauthn\MetadataService\MetadataStatementRepository; use Webauthn\StringStream; use Webauthn\TrustPath\CertificateTrustPath; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * We had to fork the key attestation support object from the WebAuthn server package to address an * issue with PHP 8. * * We are currently using an older version of the WebAuthn library (2.x) which was written before * PHP 8 was developed. We cannot upgrade the WebAuthn library to a newer major version because of * Joomla's Semantic Versioning promise. * * The AndroidKeyAttestationStatementSupport class forces an assertion on the result of the * openssl_pkey_get_public() function, assuming it will return a resource. However, starting with * PHP 8.0 this function returns an OpenSSLAsymmetricKey object and the assertion fails. As a * result, you cannot use Android or FIDO U2F keys with WebAuthn. * * The assertion check is in a private method, therefore we have to fork both attestation support * class to change the assertion. The assertion takes place through a third party library we cannot * (and should not!) modify. * * @since 4.2.0 * * @deprecated 4.2 will be removed in 6.0 * Will be removed without replacement * We will upgrade the WebAuthn library to version 3 or later and this will go away. */ final class AndroidKeyAttestationStatementSupport implements AttestationStatementSupport { /** * @var Decoder * @since 4.2.0 */ private $decoder; /** * @var MetadataStatementRepository|null * @since 4.2.0 */ private $metadataStatementRepository; /** * @param Decoder|null $decoder Obvious * @param MetadataStatementRepository|null $metadataStatementRepository Obvious * * @since 4.2.0 */ public function __construct( ?Decoder $decoder = null, ?MetadataStatementRepository $metadataStatementRepository = null ) { if ($decoder !== null) { @trigger_error('The argument "$decoder" is deprecated since 2.1 and will be removed in v3.0. Set null instead', E_USER_DEPRECATED); } if ($metadataStatementRepository === null) { @trigger_error( 'Setting "null" for argument "$metadataStatementRepository" is deprecated since 2.1 and will be mandatory in v3.0.', E_USER_DEPRECATED ); } $this->decoder = $decoder ?? new Decoder(new TagObjectManager(), new OtherObjectManager()); $this->metadataStatementRepository = $metadataStatementRepository; } /** * @return string * @since 4.2.0 */ public function name(): string { return 'android-key'; } /** * @param array $attestation Obvious * * @return AttestationStatement * @throws \Assert\AssertionFailedException * @since 4.2.0 */ public function load(array $attestation): AttestationStatement { Assertion::keyExists($attestation, 'attStmt', 'Invalid attestation object'); foreach (['sig', 'x5c', 'alg'] as $key) { Assertion::keyExists($attestation['attStmt'], $key, sprintf('The attestation statement value "%s" is missing.', $key)); } $certificates = $attestation['attStmt']['x5c']; Assertion::isArray($certificates, 'The attestation statement value "x5c" must be a list with at least one certificate.'); Assertion::greaterThan(\count($certificates), 0, 'The attestation statement value "x5c" must be a list with at least one certificate.'); Assertion::allString($certificates, 'The attestation statement value "x5c" must be a list with at least one certificate.'); $certificates = CertificateToolbox::convertAllDERToPEM($certificates); return AttestationStatement::createBasic($attestation['fmt'], $attestation['attStmt'], new CertificateTrustPath($certificates)); } /** * @param string $clientDataJSONHash Obvious * @param AttestationStatement $attestationStatement Obvious * @param AuthenticatorData $authenticatorData Obvious * * @return boolean * @throws \Assert\AssertionFailedException * @since 4.2.0 */ public function isValid( string $clientDataJSONHash, AttestationStatement $attestationStatement, AuthenticatorData $authenticatorData ): bool { $trustPath = $attestationStatement->getTrustPath(); Assertion::isInstanceOf($trustPath, CertificateTrustPath::class, 'Invalid trust path'); $certificates = $trustPath->getCertificates(); if ($this->metadataStatementRepository !== null) { $certificates = CertificateToolbox::checkAttestationMedata( $attestationStatement, $authenticatorData->getAttestedCredentialData()->getAaguid()->toString(), $certificates, $this->metadataStatementRepository ); } // Decode leaf attestation certificate $leaf = $certificates[0]; $this->checkCertificateAndGetPublicKey($leaf, $clientDataJSONHash, $authenticatorData); $signedData = $authenticatorData->getAuthData() . $clientDataJSONHash; $alg = $attestationStatement->get('alg'); return openssl_verify($signedData, $attestationStatement->get('sig'), $leaf, Algorithms::getOpensslAlgorithmFor((int) $alg)) === 1; } /** * @param string $certificate Obvious * @param string $clientDataHash Obvious * @param AuthenticatorData $authenticatorData Obvious * * @return void * @throws \Assert\AssertionFailedException * @throws \FG\ASN1\Exception\ParserException * @since 4.2.0 */ private function checkCertificateAndGetPublicKey( string $certificate, string $clientDataHash, AuthenticatorData $authenticatorData ): void { $resource = openssl_pkey_get_public($certificate); if (version_compare(PHP_VERSION, '8.0', 'lt')) { Assertion::isResource($resource, 'Unable to read the certificate'); } else { /** @noinspection PhpElementIsNotAvailableInCurrentPhpVersionInspection */ Assertion::isInstanceOf($resource, \OpenSSLAsymmetricKey::class, 'Unable to read the certificate'); } $details = openssl_pkey_get_details($resource); Assertion::isArray($details, 'Unable to read the certificate'); // Check that authData publicKey matches the public key in the attestation certificate $attestedCredentialData = $authenticatorData->getAttestedCredentialData(); Assertion::notNull($attestedCredentialData, 'No attested credential data found'); $publicKeyData = $attestedCredentialData->getCredentialPublicKey(); Assertion::notNull($publicKeyData, 'No attested public key found'); $publicDataStream = new StringStream($publicKeyData); $coseKey = $this->decoder->decode($publicDataStream)->getNormalizedData(false); Assertion::true($publicDataStream->isEOF(), 'Invalid public key data. Presence of extra bytes.'); $publicDataStream->close(); $publicKey = Key::createFromData($coseKey); Assertion::true(($publicKey instanceof Ec2Key) || ($publicKey instanceof RsaKey), 'Unsupported key type'); Assertion::eq($publicKey->asPEM(), $details['key'], 'Invalid key'); $certDetails = openssl_x509_parse($certificate); // Find Android KeyStore Extension with OID “1.3.6.1.4.1.11129.2.1.17” in certificate extensions Assertion::keyExists($certDetails, 'extensions', 'The certificate has no extension'); Assertion::isArray($certDetails['extensions'], 'The certificate has no extension'); Assertion::keyExists( $certDetails['extensions'], '1.3.6.1.4.1.11129.2.1.17', 'The certificate extension "1.3.6.1.4.1.11129.2.1.17" is missing' ); $extension = $certDetails['extensions']['1.3.6.1.4.1.11129.2.1.17']; $extensionAsAsn1 = ASNObject::fromBinary($extension); Assertion::isInstanceOf($extensionAsAsn1, Sequence::class, 'The certificate extension "1.3.6.1.4.1.11129.2.1.17" is invalid'); $objects = $extensionAsAsn1->getChildren(); // Check that attestationChallenge is set to the clientDataHash. Assertion::keyExists($objects, 4, 'The certificate extension "1.3.6.1.4.1.11129.2.1.17" is invalid'); Assertion::isInstanceOf($objects[4], OctetString::class, 'The certificate extension "1.3.6.1.4.1.11129.2.1.17" is invalid'); Assertion::eq($clientDataHash, hex2bin(($objects[4])->getContent()), 'The client data hash is not valid'); // Check that both teeEnforced and softwareEnforced structures don’t contain allApplications(600) tag. Assertion::keyExists($objects, 6, 'The certificate extension "1.3.6.1.4.1.11129.2.1.17" is invalid'); $softwareEnforcedFlags = $objects[6]; Assertion::isInstanceOf($softwareEnforcedFlags, Sequence::class, 'The certificate extension "1.3.6.1.4.1.11129.2.1.17" is invalid'); $this->checkAbsenceOfAllApplicationsTag($softwareEnforcedFlags); Assertion::keyExists($objects, 7, 'The certificate extension "1.3.6.1.4.1.11129.2.1.17" is invalid'); $teeEnforcedFlags = $objects[6]; Assertion::isInstanceOf($teeEnforcedFlags, Sequence::class, 'The certificate extension "1.3.6.1.4.1.11129.2.1.17" is invalid'); $this->checkAbsenceOfAllApplicationsTag($teeEnforcedFlags); } /** * @param Sequence $sequence Obvious * * @return void * @throws \Assert\AssertionFailedException * @since 4.2.0 */ private function checkAbsenceOfAllApplicationsTag(Sequence $sequence): void { foreach ($sequence->getChildren() as $tag) { Assertion::isInstanceOf($tag, ExplicitlyTaggedObject::class, 'Invalid tag'); /** * @var ExplicitlyTaggedObject $tag It is silly that I have to do that for PHPCS to be happy. */ Assertion::notEq(600, (int) $tag->getTag(), 'Forbidden tag 600 found'); } } } PK!3UY(I(I.multifactorauth/webauthn/src/Hotfix/Server.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt * @copyright (C) 2014-2019 Spomky-Labs * @license This software may be modified and distributed under the terms * of the MIT license. * See libraries/vendor/web-auth/webauthn-lib/LICENSE */ namespace Joomla\Plugin\Multifactorauth\Webauthn\Hotfix; use Assert\Assertion; use Cose\Algorithm\Algorithm; use Cose\Algorithm\ManagerFactory; use Cose\Algorithm\Signature\ECDSA; use Cose\Algorithm\Signature\EdDSA; use Cose\Algorithm\Signature\RSA; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\ServerRequestInterface; use Webauthn\AttestationStatement\AndroidSafetyNetAttestationStatementSupport; use Webauthn\AttestationStatement\AttestationObjectLoader; use Webauthn\AttestationStatement\AttestationStatementSupportManager; use Webauthn\AttestationStatement\NoneAttestationStatementSupport; use Webauthn\AttestationStatement\PackedAttestationStatementSupport; use Webauthn\AttestationStatement\TPMAttestationStatementSupport; use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler; use Webauthn\AuthenticatorAssertionResponse; use Webauthn\AuthenticatorAssertionResponseValidator; use Webauthn\AuthenticatorAttestationResponse; use Webauthn\AuthenticatorAttestationResponseValidator; use Webauthn\AuthenticatorSelectionCriteria; use Webauthn\MetadataService\MetadataStatementRepository; use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialLoader; use Webauthn\PublicKeyCredentialParameters; use Webauthn\PublicKeyCredentialRequestOptions; use Webauthn\PublicKeyCredentialRpEntity; use Webauthn\PublicKeyCredentialSource; use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\PublicKeyCredentialUserEntity; use Webauthn\TokenBinding\TokenBindingNotSupportedHandler; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Customised WebAuthn server object. * * We had to fork the server object from the WebAuthn server package to address an issue with PHP 8. * * We are currently using an older version of the WebAuthn library (2.x) which was written before * PHP 8 was developed. We cannot upgrade the WebAuthn library to a newer major version because of * Joomla's Semantic Versioning promise. * * The FidoU2FAttestationStatementSupport and AndroidKeyAttestationStatementSupport classes force * an assertion on the result of the openssl_pkey_get_public() function, assuming it will return a * resource. However, starting with PHP 8.0 this function returns an OpenSSLAsymmetricKey object * and the assertion fails. As a result, you cannot use Android or FIDO U2F keys with WebAuthn. * * The assertion check is in a private method, therefore we have to fork both attestation support * classes to change the assertion. The assertion takes place through a third party library we * cannot (and should not!) modify. * * The assertions objects, however, are injected to the attestation support manager in a private * method of the Server object. Because literally everything in this class is private we have no * option than to fork the entire class to apply our two forked attestation support classes. * * This is marked as deprecated because we'll be able to upgrade the WebAuthn library on Joomla 5. * * @since 4.2.0 * * @deprecated 4.2 will be removed in 6.0 * Will be removed without replacement * We will upgrade the WebAuthn library to version 3 or later and this will go away. */ class Server extends \Webauthn\Server { /** * @var integer * @since 4.2.0 */ public $timeout = 60000; /** * @var integer * @since 4.2.0 */ public $challengeSize = 32; /** * @var PublicKeyCredentialRpEntity * @since 4.2.0 */ private $rpEntity; /** * @var ManagerFactory * @since 4.2.0 */ private $coseAlgorithmManagerFactory; /** * @var PublicKeyCredentialSourceRepository * @since 4.2.0 */ private $publicKeyCredentialSourceRepository; /** * @var TokenBindingNotSupportedHandler * @since 4.2.0 */ private $tokenBindingHandler; /** * @var ExtensionOutputCheckerHandler * @since 4.2.0 */ private $extensionOutputCheckerHandler; /** * @var string[] * @since 4.2.0 */ private $selectedAlgorithms; /** * @var MetadataStatementRepository|null * @since 4.2.0 */ private $metadataStatementRepository; /** * @var ClientInterface * @since 4.2.0 */ private $httpClient; /** * @var string * @since 4.2.0 */ private $googleApiKey; /** * @var RequestFactoryInterface * @since 4.2.0 */ private $requestFactory; /** * Overridden constructor. * * @param PublicKeyCredentialRpEntity $relayingParty Obvious * @param PublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository Obvious * @param MetadataStatementRepository|null $metadataStatementRepository Obvious * * @since 4.2.0 */ public function __construct( PublicKeyCredentialRpEntity $relayingParty, PublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository, ?MetadataStatementRepository $metadataStatementRepository ) { $this->rpEntity = $relayingParty; $this->coseAlgorithmManagerFactory = new ManagerFactory(); $this->coseAlgorithmManagerFactory->add('RS1', new RSA\RS1()); $this->coseAlgorithmManagerFactory->add('RS256', new RSA\RS256()); $this->coseAlgorithmManagerFactory->add('RS384', new RSA\RS384()); $this->coseAlgorithmManagerFactory->add('RS512', new RSA\RS512()); $this->coseAlgorithmManagerFactory->add('PS256', new RSA\PS256()); $this->coseAlgorithmManagerFactory->add('PS384', new RSA\PS384()); $this->coseAlgorithmManagerFactory->add('PS512', new RSA\PS512()); $this->coseAlgorithmManagerFactory->add('ES256', new ECDSA\ES256()); $this->coseAlgorithmManagerFactory->add('ES256K', new ECDSA\ES256K()); $this->coseAlgorithmManagerFactory->add('ES384', new ECDSA\ES384()); $this->coseAlgorithmManagerFactory->add('ES512', new ECDSA\ES512()); $this->coseAlgorithmManagerFactory->add('Ed25519', new EdDSA\Ed25519()); $this->selectedAlgorithms = ['RS256', 'RS512', 'PS256', 'PS512', 'ES256', 'ES512', 'Ed25519']; $this->publicKeyCredentialSourceRepository = $publicKeyCredentialSourceRepository; $this->tokenBindingHandler = new TokenBindingNotSupportedHandler(); $this->extensionOutputCheckerHandler = new ExtensionOutputCheckerHandler(); $this->metadataStatementRepository = $metadataStatementRepository; } /** * @param string[] $selectedAlgorithms Obvious * * @return void * @since 4.2.0 */ public function setSelectedAlgorithms(array $selectedAlgorithms): void { $this->selectedAlgorithms = $selectedAlgorithms; } /** * @param TokenBindingNotSupportedHandler $tokenBindingHandler Obvious * * @return void * @since 4.2.0 */ public function setTokenBindingHandler(TokenBindingNotSupportedHandler $tokenBindingHandler): void { $this->tokenBindingHandler = $tokenBindingHandler; } /** * @param string $alias Obvious * @param Algorithm $algorithm Obvious * * @return void * @since 4.2.0 */ public function addAlgorithm(string $alias, Algorithm $algorithm): void { $this->coseAlgorithmManagerFactory->add($alias, $algorithm); $this->selectedAlgorithms[] = $alias; $this->selectedAlgorithms = array_unique($this->selectedAlgorithms); } /** * @param ExtensionOutputCheckerHandler $extensionOutputCheckerHandler Obvious * * @return void * @since 4.2.0 */ public function setExtensionOutputCheckerHandler(ExtensionOutputCheckerHandler $extensionOutputCheckerHandler): void { $this->extensionOutputCheckerHandler = $extensionOutputCheckerHandler; } /** * @param string|null $userVerification Obvious * @param PublicKeyCredentialDescriptor[] $allowedPublicKeyDescriptors Obvious * @param AuthenticationExtensionsClientInputs|null $extensions Obvious * * @return PublicKeyCredentialRequestOptions * @throws \Exception * @since 4.2.0 */ public function generatePublicKeyCredentialRequestOptions( ?string $userVerification = PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_PREFERRED, array $allowedPublicKeyDescriptors = [], ?AuthenticationExtensionsClientInputs $extensions = null ): PublicKeyCredentialRequestOptions { return new PublicKeyCredentialRequestOptions( random_bytes($this->challengeSize), $this->timeout, $this->rpEntity->getId(), $allowedPublicKeyDescriptors, $userVerification, $extensions ?? new AuthenticationExtensionsClientInputs() ); } /** * @param PublicKeyCredentialUserEntity $userEntity Obvious * @param string|null $attestationMode Obvious * @param PublicKeyCredentialDescriptor[] $excludedPublicKeyDescriptors Obvious * @param AuthenticatorSelectionCriteria|null $criteria Obvious * @param AuthenticationExtensionsClientInputs|null $extensions Obvious * * @return PublicKeyCredentialCreationOptions * @throws \Exception * @since 4.2.0 */ public function generatePublicKeyCredentialCreationOptions( PublicKeyCredentialUserEntity $userEntity, ?string $attestationMode = PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE, array $excludedPublicKeyDescriptors = [], ?AuthenticatorSelectionCriteria $criteria = null, ?AuthenticationExtensionsClientInputs $extensions = null ): PublicKeyCredentialCreationOptions { $coseAlgorithmManager = $this->coseAlgorithmManagerFactory->create($this->selectedAlgorithms); $publicKeyCredentialParametersList = []; foreach ($coseAlgorithmManager->all() as $algorithm) { $publicKeyCredentialParametersList[] = new PublicKeyCredentialParameters( PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $algorithm::identifier() ); } $criteria = $criteria ?? new AuthenticatorSelectionCriteria(); $extensions = $extensions ?? new AuthenticationExtensionsClientInputs(); $challenge = random_bytes($this->challengeSize); return new PublicKeyCredentialCreationOptions( $this->rpEntity, $userEntity, $challenge, $publicKeyCredentialParametersList, $this->timeout, $excludedPublicKeyDescriptors, $criteria, $attestationMode, $extensions ); } /** * @param string $data Obvious * @param PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions Obvious * @param ServerRequestInterface $serverRequest Obvious * * @return PublicKeyCredentialSource * @throws \Assert\AssertionFailedException * @since 4.2.0 */ public function loadAndCheckAttestationResponse( string $data, PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, ServerRequestInterface $serverRequest ): PublicKeyCredentialSource { $attestationStatementSupportManager = $this->getAttestationStatementSupportManager(); $attestationObjectLoader = new AttestationObjectLoader($attestationStatementSupportManager); $publicKeyCredentialLoader = new PublicKeyCredentialLoader($attestationObjectLoader); $publicKeyCredential = $publicKeyCredentialLoader->load($data); $authenticatorResponse = $publicKeyCredential->getResponse(); Assertion::isInstanceOf($authenticatorResponse, AuthenticatorAttestationResponse::class, 'Not an authenticator attestation response'); $authenticatorAttestationResponseValidator = new AuthenticatorAttestationResponseValidator( $attestationStatementSupportManager, $this->publicKeyCredentialSourceRepository, $this->tokenBindingHandler, $this->extensionOutputCheckerHandler ); return $authenticatorAttestationResponseValidator->check($authenticatorResponse, $publicKeyCredentialCreationOptions, $serverRequest); } /** * @param string $data Obvious * @param PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions Obvious * @param PublicKeyCredentialUserEntity|null $userEntity Obvious * @param ServerRequestInterface $serverRequest Obvious * * @return PublicKeyCredentialSource * @throws \Assert\AssertionFailedException * @since 4.2.0 */ public function loadAndCheckAssertionResponse( string $data, PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions, ?PublicKeyCredentialUserEntity $userEntity, ServerRequestInterface $serverRequest ): PublicKeyCredentialSource { $attestationStatementSupportManager = $this->getAttestationStatementSupportManager(); $attestationObjectLoader = new AttestationObjectLoader($attestationStatementSupportManager); $publicKeyCredentialLoader = new PublicKeyCredentialLoader($attestationObjectLoader); $publicKeyCredential = $publicKeyCredentialLoader->load($data); $authenticatorResponse = $publicKeyCredential->getResponse(); Assertion::isInstanceOf($authenticatorResponse, AuthenticatorAssertionResponse::class, 'Not an authenticator assertion response'); $authenticatorAssertionResponseValidator = new AuthenticatorAssertionResponseValidator( $this->publicKeyCredentialSourceRepository, null, $this->tokenBindingHandler, $this->extensionOutputCheckerHandler, $this->coseAlgorithmManagerFactory->create($this->selectedAlgorithms) ); return $authenticatorAssertionResponseValidator->check( $publicKeyCredential->getRawId(), $authenticatorResponse, $publicKeyCredentialRequestOptions, $serverRequest, null !== $userEntity ? $userEntity->getId() : null ); } /** * @param ClientInterface $client Obvious * @param string $apiKey Obvious * @param RequestFactoryInterface $requestFactory Obvious * * @return void * @since 4.2.0 */ public function enforceAndroidSafetyNetVerification( ClientInterface $client, string $apiKey, RequestFactoryInterface $requestFactory ): void { $this->httpClient = $client; $this->googleApiKey = $apiKey; $this->requestFactory = $requestFactory; } /** * @return AttestationStatementSupportManager * @since 4.2.0 */ private function getAttestationStatementSupportManager(): AttestationStatementSupportManager { $attestationStatementSupportManager = new AttestationStatementSupportManager(); $attestationStatementSupportManager->add(new NoneAttestationStatementSupport()); if ($this->metadataStatementRepository !== null) { $coseAlgorithmManager = $this->coseAlgorithmManagerFactory->create($this->selectedAlgorithms); $attestationStatementSupportManager->add(new FidoU2FAttestationStatementSupport(null, $this->metadataStatementRepository)); /** * Work around a third party library (web-token/jwt-signature-algorithm-eddsa) bug. * * On PHP 8 libsodium is compiled into PHP, it is not an extension. However, the third party library does * not check if the libsodium function are available; it checks if the "sodium" extension is loaded. This of * course causes an immediate failure with a Runtime exception EVEN IF the attested data isn't attested by * Android Safety Net. Therefore we have to not even load the AndroidSafetyNetAttestationStatementSupport * class in this case... */ if (function_exists('sodium_crypto_sign_seed_keypair') && function_exists('extension_loaded') && extension_loaded('sodium')) { $attestationStatementSupportManager->add( new AndroidSafetyNetAttestationStatementSupport( $this->httpClient, $this->googleApiKey, $this->requestFactory, 2000, 60000, $this->metadataStatementRepository ) ); } $attestationStatementSupportManager->add(new AndroidKeyAttestationStatementSupport(null, $this->metadataStatementRepository)); $attestationStatementSupportManager->add(new TPMAttestationStatementSupport($this->metadataStatementRepository)); $attestationStatementSupportManager->add( new PackedAttestationStatementSupport( null, $coseAlgorithmManager, $this->metadataStatementRepository ) ); } return $attestationStatementSupportManager; } } PK!6VM  &behaviour/compat/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Behaviour\Compat\Extension\Compat; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * @since 4.4.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $plugin = PluginHelper::getPlugin('behaviour', 'compat'); $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Compat($dispatcher, (array) $plugin); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!&\\behaviour/compat/compat.xmlnu[ plg_behaviour_compat Joomla! Project 2023-09 (C) 2023 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.4.0 PLG_COMPAT_XML_DESCRIPTION Joomla\Plugin\Behaviour\Compat services src language/en-GB/plg_behaviour_compat.ini language/en-GB/plg_behaviour_compat.sys.ini PK!؝)behaviour/compat/src/Extension/Compat.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Behaviour\Compat\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\SubscriberInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! Compat Plugin. * * @since 4.4.0 */ final class Compat extends CMSPlugin implements SubscriberInterface { /** * Returns an array of CMS events this plugin will listen to and the respective handlers. * * @return array * * @since 4.4.0 */ public static function getSubscribedEvents(): array { /** * This plugin does not listen to any events. */ return []; } } PK!\(behaviour/taggable/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Behaviour\Taggable\Extension\Taggable; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.2.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Taggable( $dispatcher, (array) PluginHelper::getPlugin('behaviour', 'taggable') ); return $plugin; } ); } }; PK!~~behaviour/taggable/taggable.xmlnu[ plg_behaviour_taggable 4.0.0 2015-08 Joomla! Project admin@joomla.org www.joomla.org (C) 2016 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt PLG_BEHAVIOUR_TAGGABLE_XML_DESCRIPTION Joomla\Plugin\Behaviour\Taggable services src language/en-GB/plg_behaviour_taggable.ini language/en-GB/plg_behaviour_taggable.sys.ini PK!u''-behaviour/taggable/src/Extension/Taggable.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Behaviour\Taggable\Extension; use Joomla\CMS\Event\Model\BeforeBatchEvent; use Joomla\CMS\Event\Table\AfterLoadEvent; use Joomla\CMS\Event\Table\AfterResetEvent; use Joomla\CMS\Event\Table\AfterStoreEvent; use Joomla\CMS\Event\Table\BeforeDeleteEvent; use Joomla\CMS\Event\Table\BeforeStoreEvent; use Joomla\CMS\Event\Table\ObjectCreateEvent; use Joomla\CMS\Event\Table\SetNewTagsEvent; use Joomla\CMS\Helper\TagsHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Table\TableInterface; use Joomla\CMS\Tag\TaggableTableInterface; use Joomla\Event\SubscriberInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Implements the Taggable behaviour which allows extensions to automatically support tags for their content items. * * This plugin supersedes JHelperObserverTags. * * @since 4.0.0 */ final class Taggable extends CMSPlugin implements SubscriberInterface { /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.2.0 */ public static function getSubscribedEvents(): array { return [ 'onTableObjectCreate' => 'onTableObjectCreate', 'onTableBeforeStore' => 'onTableBeforeStore', 'onTableAfterStore' => 'onTableAfterStore', 'onTableBeforeDelete' => 'onTableBeforeDelete', 'onTableSetNewTags' => 'onTableSetNewTags', 'onTableAfterReset' => 'onTableAfterReset', 'onTableAfterLoad' => 'onTableAfterLoad', 'onBeforeBatch' => 'onBeforeBatch', ]; } /** * Runs when a new table object is being created * * @param ObjectCreateEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableObjectCreate(ObjectCreateEvent $event) { // Extract arguments /** @var TableInterface $table */ $table = $event['subject']; // If the tags table doesn't implement the interface bail if (!($table instanceof TaggableTableInterface)) { return; } // If the table already has a tags helper we have nothing to do if (!is_null($table->getTagsHelper())) { return; } $tagsHelper = new TagsHelper(); $tagsHelper->typeAlias = $table->typeAlias; $table->setTagsHelper($tagsHelper); // This is required because getTagIds overrides the tags property of the Tags Helper. $cloneHelper = clone $table->getTagsHelper(); $tagIds = $cloneHelper->getTagIds($table->getId(), $table->getTypeAlias()); if (!empty($tagIds)) { $table->getTagsHelper()->tags = explode(',', $tagIds); } } /** * Pre-processor for $table->store($updateNulls) * * @param BeforeStoreEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableBeforeStore(BeforeStoreEvent $event) { // Extract arguments /** @var TableInterface $table */ $table = $event['subject']; // If the tags table doesn't implement the interface bail if (!($table instanceof TaggableTableInterface)) { return; } // If the table doesn't have a tags helper we can't proceed if (is_null($table->getTagsHelper())) { return; } /** @var TagsHelper $tagsHelper */ $tagsHelper = $table->getTagsHelper(); $tagsHelper->typeAlias = $table->getTypeAlias(); $newTags = $table->newTags ?? []; if (empty($newTags)) { $tagsHelper->preStoreProcess($table); } else { $tagsHelper->preStoreProcess($table, (array) $newTags); } } /** * Post-processor for $table->store($updateNulls) * * @param AfterStoreEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableAfterStore(AfterStoreEvent $event) { // Extract arguments /** @var TableInterface $table */ $table = $event['subject']; $result = $event['result']; if (!$result) { return; } if (!is_object($table) || !($table instanceof TaggableTableInterface)) { return; } // If the table doesn't have a tags helper we can't proceed if (is_null($table->getTagsHelper())) { return; } // Get the Tags helper and assign the parsed alias /** @var TagsHelper $tagsHelper */ $tagsHelper = $table->getTagsHelper(); $tagsHelper->typeAlias = $table->getTypeAlias(); $newTags = $table->newTags ?? []; if (empty($newTags)) { $result = $tagsHelper->postStoreProcess($table); } else { if (is_string($newTags) && (strpos($newTags, ',') !== false)) { $newTags = explode(',', $newTags); } elseif (!is_array($newTags)) { $newTags = (array) $newTags; } $result = $tagsHelper->postStoreProcess($table, $newTags); } } /** * Pre-processor for $table->delete($pk) * * @param BeforeDeleteEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableBeforeDelete(BeforeDeleteEvent $event) { // Extract arguments /** @var TableInterface $table */ $table = $event['subject']; $pk = $event['pk']; // If the tags table doesn't implement the interface bail if (!($table instanceof TaggableTableInterface)) { return; } // If the table doesn't have a tags helper we can't proceed if (is_null($table->getTagsHelper())) { return; } // Get the Tags helper and assign the parsed alias $table->getTagsHelper()->typeAlias = $table->getTypeAlias(); $table->getTagsHelper()->deleteTagData($table, $pk); } /** * Handles the tag setting in $table->batchTag($value, $pks, $contexts) * * @param SetNewTagsEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableSetNewTags(SetNewTagsEvent $event) { // Extract arguments /** @var TableInterface $table */ $table = $event['subject']; $newTags = $event['newTags']; $replaceTags = $event['replaceTags']; // If the tags table doesn't implement the interface bail if (!($table instanceof TaggableTableInterface)) { return; } // If the table doesn't have a tags helper we can't proceed if (is_null($table->getTagsHelper())) { return; } // Get the Tags helper and assign the parsed alias /** @var TagsHelper $tagsHelper */ $tagsHelper = $table->getTagsHelper(); $tagsHelper->typeAlias = $table->getTypeAlias(); if (!$tagsHelper->postStoreProcess($table, $newTags, $replaceTags)) { throw new \RuntimeException($table->getError()); } } /** * Runs when an existing table object is reset * * @param AfterResetEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableAfterReset(AfterResetEvent $event) { // Extract arguments /** @var TableInterface $table */ $table = $event['subject']; // If the tags table doesn't implement the interface bail if (!($table instanceof TaggableTableInterface)) { return; } // Parse the type alias $tagsHelper = new TagsHelper(); $tagsHelper->typeAlias = $table->getTypeAlias(); $table->setTagsHelper($tagsHelper); } /** * Runs when an existing table object has been loaded * * @param AfterLoadEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableAfterLoad(AfterLoadEvent $event) { // Extract arguments /** @var TableInterface $table */ $table = $event['subject']; // If the tags table doesn't implement the interface bail if (!($table instanceof TaggableTableInterface)) { return; } // If the table doesn't have a tags helper we can't proceed if (is_null($table->getTagsHelper())) { return; } // This is required because getTagIds overrides the tags property of the Tags Helper. $cloneHelper = clone $table->getTagsHelper(); $tagIds = $cloneHelper->getTagIds($table->getId(), $table->getTypeAlias()); if (!empty($tagIds)) { $table->getTagsHelper()->tags = explode(',', $tagIds); } } /** * Runs when an existing table object has been loaded * * @param BeforeBatchEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onBeforeBatch(BeforeBatchEvent $event) { /** @var TableInterface $sourceTable */ $sourceTable = $event['src']; if (!($sourceTable instanceof TaggableTableInterface)) { return; } if ($event['type'] === 'copy') { $sourceTable->newTags = $sourceTable->getTagsHelper()->tags; } else { /** * All other batch actions we don't want the tags to be modified so clear the helper - that way no actions * will be performed on store */ $sourceTable->clearTagsHelper(); } } } PK!Z+behaviour/versionable/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Helper\CMSHelper; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Filter\InputFilter; use Joomla\Plugin\Behaviour\Versionable\Extension\Versionable; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.2.0 */ public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Versionable( $dispatcher, (array) PluginHelper::getPlugin('behaviour', 'versionable'), new InputFilter(), new CMSHelper() ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!ѐ%behaviour/versionable/versionable.xmlnu[ plg_behaviour_versionable 4.0.0 2015-08 Joomla! Project admin@joomla.org www.joomla.org (C) 2016 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt PLG_BEHAVIOUR_VERSIONABLE_XML_DESCRIPTION Joomla\Plugin\Behaviour\Versionable services src language/en-GB/plg_behaviour_versionable.ini language/en-GB/plg_behaviour_versionable.sys.ini PK!7}aEE3behaviour/versionable/src/Extension/Versionable.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Behaviour\Versionable\Extension; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Event\Table\AfterStoreEvent; use Joomla\CMS\Event\Table\BeforeDeleteEvent; use Joomla\CMS\Helper\CMSHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Versioning\VersionableTableInterface; use Joomla\CMS\Versioning\Versioning; use Joomla\Event\DispatcherInterface; use Joomla\Event\SubscriberInterface; use Joomla\Filter\InputFilter; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Implements the Versionable behaviour which allows extensions to automatically support content history for their content items. * * This plugin supersedes JTableObserverContenthistory. * * @since 4.0.0 */ final class Versionable extends CMSPlugin implements SubscriberInterface { /** * Returns an array of events this subscriber will listen to. * * @return array * * @since 4.2.0 */ public static function getSubscribedEvents(): array { return [ 'onTableAfterStore' => 'onTableAfterStore', 'onTableBeforeDelete' => 'onTableBeforeDelete', ]; } /** * The input filter * * @var InputFilter * @since 4.2.0 */ private $filter; /** * The CMS helper * * @var CMSHelper * @since 4.2.0 */ private $helper; /** * Constructor. * * @param DispatcherInterface $dispatcher The dispatcher * @param array $config An optional associative array of configuration settings * @param InputFilter $filter The input filter * @param CMSHelper $helper The CMS helper * * @since 4.0.0 */ public function __construct(DispatcherInterface $dispatcher, array $config, InputFilter $filter, CMSHelper $helper) { parent::__construct($dispatcher, $config); $this->filter = $filter; $this->helper = $helper; } /** * Post-processor for $table->store($updateNulls) * * @param AfterStoreEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableAfterStore(AfterStoreEvent $event) { // Extract arguments /** @var VersionableTableInterface $table */ $table = $event['subject']; $result = $event['result']; if (!$result) { return; } if (!(is_object($table) && $table instanceof VersionableTableInterface)) { return; } // Get the Tags helper and assign the parsed alias $typeAlias = $table->getTypeAlias(); $aliasParts = explode('.', $typeAlias); if ($aliasParts[0] === '' || !ComponentHelper::getParams($aliasParts[0])->get('save_history', 0)) { return; } $id = $table->getId(); $data = $this->helper->getDataObject($table); $input = $this->getApplication()->getInput(); $jform = $input->get('jform', [], 'array'); $versionNote = ''; if (isset($jform['version_note'])) { $versionNote = $this->filter->clean($jform['version_note'], 'string'); } Versioning::store($typeAlias, $id, $data, $versionNote); } /** * Pre-processor for $table->delete($pk) * * @param BeforeDeleteEvent $event The event to handle * * @return void * * @since 4.0.0 */ public function onTableBeforeDelete(BeforeDeleteEvent $event) { // Extract arguments /** @var VersionableTableInterface $table */ $table = $event['subject']; if (!(is_object($table) && $table instanceof VersionableTableInterface)) { return; } $typeAlias = $table->getTypeAlias(); $aliasParts = explode('.', $typeAlias); if ($aliasParts[0] && ComponentHelper::getParams($aliasParts[0])->get('save_history', 0)) { Versioning::delete($typeAlias, $table->getId()); } } } PK!J''Lconvertforms/convertkit/language/ru-RU/ru-RU.plg_convertforms_convertkit.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CONVERTKIT_ALIAS="ConvertKit" PLG_CONVERTFORMS_CONVERTKIT="Преобразовать формы - Интеграция с ConvertKit" PLG_CONVERTFORMS_CONVERTKIT_DESC="Преобразование форм - интеграция с сервисами почтового маркетинга ConvertKit." PLG_CONVERTFORMS_CONVERTKIT_KEY="ключ API" PLG_CONVERTFORMS_CONVERTKIT_KEY_DESC="Ваш ключ API ConvertKit" PLG_CONVERTFORMS_CONVERTKIT_FORM_ID="Форма ID" PLG_CONVERTFORMS_CONVERTKIT_FORM_ID_DESC="Идентификатор формы, на которую должен подписаться пользователь" PLG_CONVERTFORMS_CONVERTKIT_FIND_API_KEY="Где я могу найти ключ API?" PLG_CONVERTFORMS_CONVERTKIT_FIND_FORM_ID="Где я могу найти идентификатор формы?" PK! PLG_CONVERTFORMS_CONVERTKIT PLG_CONVERTFORMS_CONVERTKIT_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later March 2017 script.install.php language convertkit.php form.xml script.install.helper.php PK!b%/ς convertforms/convertkit/form.xmlnu[
    PK!,ٟ991convertforms/convertkit/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsConvertkitInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!vx&convertforms/convertkit/convertkit.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsConvertKit extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ function subscribe() { $api = new NR_ConvertKit($this->lead->campaign->api); $api->subscribe( $this->lead->email, $this->lead->campaign->formid, $this->lead->params ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK!3 *convertforms/convertkit/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsConvertKitInstallerScript extends PlgConvertFormsConvertKitInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_CONVERTKIT'; public $alias = 'convertkit'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!E@convertforms/zoho/language/ru-RU/ru-RU.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Кампании" PLG_CONVERTFORMS_ZOHO="Преобразование форм - интеграция кампании Zoho" PLG_CONVERTFORMS_ZOHO_DESC="Преобразование форм - интеграция с кампаниями Zoho." PLG_CONVERTFORMS_ZOHO_KEY="код аутентификации" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Ваш код авторизации Zoho" PLG_CONVERTFORMS_ZOHO_LIST_ID="список ID" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="Идентификатор списка, на который пользователь должен подписаться" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Где я могу найти код аутентификации?" PK!*Zo@convertforms/zoho/language/ca-ES/ca-ES.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Campaigns" PLG_CONVERTFORMS_ZOHO="Integració Convert Forms - Zoho Campaigns" PLG_CONVERTFORMS_ZOHO_DESC="Integració entre Convert Forms i Zoho Campaigns." PLG_CONVERTFORMS_ZOHO_KEY="Auth Code" PLG_CONVERTFORMS_ZOHO_KEY_DESC="El teu Zoho Auth Code" PLG_CONVERTFORMS_ZOHO_LIST_ID="ID de llista" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="L'ID del llistat al que s'hauria de subscriure l'usuari" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="On trobar l'Auth Code?" PK!233@convertforms/zoho/language/bg-BG/bg-BG.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Campaigns" PLG_CONVERTFORMS_ZOHO="Convert Forms – Zoho Campaigns интеграция" PLG_CONVERTFORMS_ZOHO_DESC="Convert Forms – интеграция със Zoho Campaigns." PLG_CONVERTFORMS_ZOHO_KEY="Auth Code " PLG_CONVERTFORMS_ZOHO_KEY_DESC="Вашият Zoho Auth Code разрешаващ код" PLG_CONVERTFORMS_ZOHO_LIST_ID="ID списък" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="ID на списъка, за който потребителят трябва да се абонира" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Къде да намерите Auth Code?" PK!zj@convertforms/zoho/language/cs-CZ/cs-CZ.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Campaigns" PLG_CONVERTFORMS_ZOHO="Convert Forms - Integrace Zoho Campaigns" PLG_CONVERTFORMS_ZOHO_DESC="Convert Forms - Integrace Zoho Campaigns." PLG_CONVERTFORMS_ZOHO_KEY="Autorizační kód" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Vás Zoho autorizační kód" PLG_CONVERTFORMS_ZOHO_LIST_ID="ID seznamu" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="ID seznamu k jehož odběru se uživatel přihlašuje" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Kde najdu autorizační kód?" PK!S!  @convertforms/zoho/language/es-ES/es-ES.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Campañas Zoho" PLG_CONVERTFORMS_ZOHO="\"Formularios de conversión\" - Integración campañas Zoho" PLG_CONVERTFORMS_ZOHO_DESC="\"Formularios de conversión\" - Integración con Campañas Zoho." PLG_CONVERTFORMS_ZOHO_KEY="Código de autentificación" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Tu código de autentificación Zoho" PLG_CONVERTFORMS_ZOHO_LIST_ID="Lista ID" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="La lista ID a la que el usuario debiera estar suscrito" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="¿Dónde encontrar el código de autentificación?" PK!GT@convertforms/zoho/language/fi-FI/fi-FI.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Campaigns" PLG_CONVERTFORMS_ZOHO="Convert Forms - Zoho Campaigns liitäntä" PLG_CONVERTFORMS_ZOHO_DESC="Convert Forms - IIntegrointi Zoho Campaigns." PLG_CONVERTFORMS_ZOHO_KEY="Valtuutuskoodi" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Sinun Zoho valtuutuskoodi" PLG_CONVERTFORMS_ZOHO_LIST_ID="Luettelo ID" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="Luettelo ID, jonka käyttäjän tulee tilata" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Mistä löytyy valtuutuskoodi?" PK!@convertforms/zoho/language/en-GB/en-GB.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Campaigns" PLG_CONVERTFORMS_ZOHO="Convert Forms - Zoho Campaigns Integration" PLG_CONVERTFORMS_ZOHO_DESC="Convert Forms - Integration with Zoho Campaigns." PLG_CONVERTFORMS_ZOHO_KEY="Auth Code" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Your Zoho Auth Code" PLG_CONVERTFORMS_ZOHO_LIST_ID="List ID" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="The List ID which the user should be subscribed to" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Where to find Auth Code?"PK!!bbDconvertforms/zoho/language/en-GB/en-GB.plg_convertforms_zoho.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO="Convert Forms - Zoho Campaigns Integration" PLG_CONVERTFORMS_ZOHO_DESC="Convert Forms - Integration with Zoho Campaigns."PK!;/n@convertforms/zoho/language/sv-SE/sv-SE.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho kampanjer" PLG_CONVERTFORMS_ZOHO="Convert Forms - Zoho Kampanjintegration" PLG_CONVERTFORMS_ZOHO_DESC="Convert Forms - Integration med Zoho kampanjer." PLG_CONVERTFORMS_ZOHO_KEY="Behörighetskod" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Din Zoho behörighetskod" PLG_CONVERTFORMS_ZOHO_LIST_ID="List ID" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="List-ID som användaren ska prenumerera på" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Var hittar jag behörighetskoden?" PK!BI@convertforms/zoho/language/uk-UA/uk-UA.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Кампанії" PLG_CONVERTFORMS_ZOHO="Перетворення форм - інтеграція кампанії Zoho" PLG_CONVERTFORMS_ZOHO_DESC="Перетворити форми - інтеграція з кампаніями Zoho." PLG_CONVERTFORMS_ZOHO_KEY="код аутентифікації" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Ваш код Zoho Auth" PLG_CONVERTFORMS_ZOHO_LIST_ID="список ID" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="Ідентифікатор списку, на який повинен підписатись користувач" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Де я можу знайти код аутентифікації?" PK!T  @convertforms/zoho/language/fr-FR/fr-FR.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Campagne Zoho" PLG_CONVERTFORMS_ZOHO="Convertisseur de formulaire - Intégration de la campagne Zoho" PLG_CONVERTFORMS_ZOHO_DESC="Convertisseur de formulaires - Intégration avec la campagne Zoho." PLG_CONVERTFORMS_ZOHO_KEY="Code d'authentification" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Votre code d'authentification Zoho" PLG_CONVERTFORMS_ZOHO_LIST_ID="ID de la liste" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="L'ID de la liste à laquelle l'utilisateur doit s'abonner" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Où trouver votre code d'authentification ?" PK!Q@convertforms/zoho/language/de-DE/de-DE.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Campaigns" PLG_CONVERTFORMS_ZOHO="Convert Forms - Zoho Campaigns Integration" PLG_CONVERTFORMS_ZOHO_DESC="Convert Forms - Integration mit Zoho Campaigns." PLG_CONVERTFORMS_ZOHO_KEY="Authentifizierungscode" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Ihr Zoho Authentifizierungscode" PLG_CONVERTFORMS_ZOHO_LIST_ID="Listen ID" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="Die Listen ID, zu der der Benutzer hinzugefügt werden soll" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Wo findet man den Authentifizierungscode?" PK!}]@convertforms/zoho/language/it-IT/it-IT.plg_convertforms_zoho.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHO_ALIAS="Zoho Campaigns" PLG_CONVERTFORMS_ZOHO="Integrazione Convert Forms - Zoho Campaigns" PLG_CONVERTFORMS_ZOHO_DESC="Integrazione Convert Forms con Zoho Campaigns." PLG_CONVERTFORMS_ZOHO_KEY="Codice di autorizzazione" PLG_CONVERTFORMS_ZOHO_KEY_DESC="Il tuo codice di autorizzazione di Zoho" PLG_CONVERTFORMS_ZOHO_LIST_ID="ID elenco" PLG_CONVERTFORMS_ZOHO_LIST_ID_DESC="L'ID elenco a cui l'utente dovrebbe essere iscritto" PLG_CONVERTFORMS_ZOHO_FIND_API_KEY="Dove trovare il codice di autorizzazione?" PK!dBVMconvertforms/zoho/form.xmlnu[
    PK! T}]{9{9+convertforms/zoho/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsZohoInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!?Qconvertforms/zoho/zoho.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsZoho extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ function subscribe() { $api = new NR_ZoHo(array('api' => $this->lead->campaign->api)); $api->subscribe( $this->lead->email, $this->lead->campaign->list, $this->lead->params ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK! %$convertforms/zoho/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsZoHoInstallerScript extends PlgConvertFormsZoHoInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_ZOHO'; public $alias = 'zoho'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!convertforms/zoho/zoho.xmlnu[ PLG_CONVERTFORMS_ZOHO PLG_CONVERTFORMS_ZOHO_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2017 Tassos Marinos GNU General Public License version 3, or later May 2017 script.install.php language zoho.php form.xml script.install.helper.php PK!BVFconvertforms/hubspot/language/ru-RU/ru-RU.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Преобразование форм - интеграция HubSpot" PLG_CONVERTFORMS_HUBSPOT_DESC="Преобразование форм - интеграция с сервисами почтового маркетинга HubSpot." PLG_CONVERTFORMS_HUBSPOT_KEY="ключ API" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Ваш ключ API HubSpot" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Где я могу найти ключ API?" PK!o]]Fconvertforms/hubspot/language/ca-ES/ca-ES.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Integració Convert Forms - HubSpot" PLG_CONVERTFORMS_HUBSPOT_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic HubSpot" PLG_CONVERTFORMS_HUBSPOT_KEY="Clau API" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="La teva clau API de Hubspot" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="On trobar la clau API?" PK! Fconvertforms/hubspot/language/bg-BG/bg-BG.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Convert Forms – HubSpot интеграция" PLG_CONVERTFORMS_HUBSPOT_DESC="Convert Forms – интеграция с HubSpot имейл маркетингови услуги." PLG_CONVERTFORMS_HUBSPOT_KEY="API ключ" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Вашият HubSpot API ключ" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Къде да намерите API ключ?" PK!:VPJJFconvertforms/hubspot/language/cs-CZ/cs-CZ.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Convert Forms - Integrace HubSpot" PLG_CONVERTFORMS_HUBSPOT_DESC="Convert Forms - Integrace emailových a marketingových služeb HubSpot." PLG_CONVERTFORMS_HUBSPOT_KEY="API klíč" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Váš HubSpot API klíč" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Kde získáte API klíč?" PK! nzzFconvertforms/hubspot/language/es-ES/es-ES.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="\"Formas de conversión\" - Integración con HubSpot" PLG_CONVERTFORMS_HUBSPOT_DESC="\"Formularios de conversión\" - Integración con servicios de marketing de Email HubSpot." PLG_CONVERTFORMS_HUBSPOT_KEY="Clave de API" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Tu clave de API HubSpot" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="¿Dónde encontrar la clave de API?" PK!5A99Fconvertforms/hubspot/language/fi-FI/fi-FI.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Convert Forms - HubSpot liitäntä" PLG_CONVERTFORMS_HUBSPOT_DESC="Convert Forms - Integrointi HubSpot Email Marketing palveluun." PLG_CONVERTFORMS_HUBSPOT_KEY="API Key" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Sinun HubSpot API Key" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Mistä löytyy API Key?" PK!c;;Fconvertforms/hubspot/language/en-GB/en-GB.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Convert Forms - HubSpot Integration" PLG_CONVERTFORMS_HUBSPOT_DESC="Convert Forms - Integration with HubSpot Email Marketing Services." PLG_CONVERTFORMS_HUBSPOT_KEY="API Key" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Your HubSpot API Key" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Where to find API Key?"PK!ssJconvertforms/hubspot/language/en-GB/en-GB.plg_convertforms_hubspot.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT="Convert Forms - HubSpot Integration" PLG_CONVERTFORMS_HUBSPOT_DESC="Convert Forms - Integration with HubSpot Email Marketing Services."PK!IFconvertforms/hubspot/language/uk-UA/uk-UA.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Перетворити форми - інтеграція HubSpot" PLG_CONVERTFORMS_HUBSPOT_DESC="Перетворити форми - інтеграція з маркетинговими послугами HubSpot." PLG_CONVERTFORMS_HUBSPOT_KEY="ключ API" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Ваш ключ API HubSpot" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Де я можу знайти ключ API?" PK!euFconvertforms/hubspot/language/fr-FR/fr-FR.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Convertisseur de formulaire - Intégration de HubSpot" PLG_CONVERTFORMS_HUBSPOT_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing de HubSpot." PLG_CONVERTFORMS_HUBSPOT_KEY="Clé de l'API" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Votre clé de l'API HubSpot" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Où trouver la clé de l'API ?" PK!(TTFconvertforms/hubspot/language/de-DE/de-DE.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Convert Forms - HubSpot Integration" PLG_CONVERTFORMS_HUBSPOT_DESC="Convert Forms - Integration mit HubSpot E-Mail-Marketing-Diensten." PLG_CONVERTFORMS_HUBSPOT_KEY="API Schlüssel" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="Ihr HubSpot API Schlüssel" PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Wo findet man den API Schlüssel?" PK!4fQQFconvertforms/hubspot/language/it-IT/it-IT.plg_convertforms_hubspot.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_HUBSPOT_ALIAS="HubSpot" PLG_CONVERTFORMS_HUBSPOT="Integrazione Convert Forms - HubSpot" PLG_CONVERTFORMS_HUBSPOT_DESC="Integrazione Convert Forms con i servizi Email Marketing di HubSpot " PLG_CONVERTFORMS_HUBSPOT_KEY="Chiave API" PLG_CONVERTFORMS_HUBSPOT_KEY_DESC="La tua chiave API di HubSpot " PLG_CONVERTFORMS_HUBSPOT_FIND_API_KEY="Dove trovare la chiave API?" PK!6convertforms/hubspot/form.xmlnu[
    PK!`L~9~9.convertforms/hubspot/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsHubspotInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!0$$ convertforms/hubspot/hubspot.xmlnu[ PLG_CONVERTFORMS_HUBSPOT PLG_CONVERTFORMS_HUBSPOT_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2017 Tassos Marinos GNU General Public License version 3, or later March 2017 script.install.php language hubspot.php form.xml script.install.helper.php PK!vdZ'convertforms/hubspot/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsHubSpotInstallerScript extends PlgConvertFormsHubSpotInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_HUBSPOT'; public $alias = 'hubspot'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!:  convertforms/hubspot/hubspot.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsHubSpot extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ function subscribe() { $api = new NR_HubSpot($this->lead->campaign->api); $api->subscribe( $this->lead->email, $this->lead->params ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK!.ĕM M Dconvertforms/aweber/language/ru-RU/ru-RU.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Преобразовать формы - интеграция AWeber" PLG_CONVERTFORMS_AWEBER_DESC="Конвертировать формы - интеграция с сервисами почтового маркетинга AWeber." PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Код авторизации" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Код авторизации, созданный AWeber. Скопируйте его из всплывающего окна и вставьте его здесь." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Получить код аутентификации" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Уникальный идентификатор списка" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="Уникальный идентификатор списка вашего списка. Вы можете найти его в настройках списка вашего аккаунта AWeber." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Где вы можете найти свой уникальный идентификатор списка?" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Обновить существующего пользователя" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Обновите пользователя на AWeber новыми данными, если он уже существует." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber не поддерживает однократную подписку через свой API. Прочитайте наш Документация для получения дополнительной информации." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="Неправильный код авторизации. Пожалуйста, попробуйте получить новый." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="Соединение AWeber было успешно установлено." PK!dDconvertforms/aweber/language/ca-ES/ca-ES.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Integració Convert Forms - AWeber" PLG_CONVERTFORMS_AWEBER_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic Aweber" PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Codi d'autorització" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="El codi d'autorització creat a AWeber. Copia'l des de l'emergent i enganxa'l aquí." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Aconseguir l'Auth Code" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="ID de llistat únic" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="L'ID de llistat únic de la teva llista. El pots trobar a la configuració de llistat al teu compte Aweber." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="On trobar l'ID de llistat únic" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Actualitzar usuari existent" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Actualitza l'usuari a Aweber amb les noves dades si ja existeix." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="Aweber no suporta la confirmació d'entrada simple a través de la seva API. Llegeix la nostra documentació per més informació." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="El codi d'autorització no és correcte. Aconsegueix-ne un de nou." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="S'ha establert amb èxit la connexió amb Aweber." PK! 2Dconvertforms/aweber/language/bg-BG/bg-BG.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Convert Forms – AWeber интеграция" PLG_CONVERTFORMS_AWEBER_DESC="Convert Forms – интеграциия с AWeber имейл маркетинг услуга." PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Код за разрешение" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Кодът за упълномощаване, създаден от AWeber. Копирайте го от изскачащrият прозорец и го поставете тук." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Вземете Auth Code / Код за разрешение" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Уникален ID идентификационен номер на списъка" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="Уникалният ID идентификационен номер на вашия списък. Той може да бъде намерен в Настройките на списък във вашия AWeber акаунт." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Къде да намеря уникалния ID номер на списък?" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Актуализирайте съществуващия потребител" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Актуализирайте потребителя в AWeber с новите данни, ако той вече съществува." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber не поддържа Single Opt-in чрез техния API. Прочетете нашата документация за повече информация." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="Кодът за разрешение не е правилен. Моля, опитайте да се сдобиете с нов." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="Връзката AWeber е успешно установена." PK!NvTTDconvertforms/aweber/language/cs-CZ/cs-CZ.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Convert Forms - Integrace AWeber" PLG_CONVERTFORMS_AWEBER_DESC="Convert Forms - Integrace AWeber Email." PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Autorizační kód" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Autorizační kód vytvořený službou AWeber. Zkopírujte jej z okna a vložte sem." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Získat autorizační kód" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Unikátní ID seznamu" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="Unikátní ID seznamu. Najdete ho ve svém účtu AWeber v části List Settings." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Kde najdu ID seznamu" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Upravit stávajícího uživatele" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Aktualizujte informace o uživateli služby AWeber, pokud byl již uživatel vytvořen." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="Služba AWeber nepodporuje jednoduchý Opt-in skrze API. Přečtěte si dokumentataci pro podrobnějsí informace." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="Autorizační kód není správný. Prosím, zkontrolujte kód nebo zkuste zadat jiný." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="Spojení se službou AWeber bylo úspěšně nastaveno." PK!oyDconvertforms/aweber/language/es-ES/es-ES.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="\"Formas de conversión\" - Integración con AWeber" PLG_CONVERTFORMS_AWEBER_DESC="\"Formularios de conversión\" - Integración con servicios de marketing de Email AWeber" PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Código de autorización" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Código de autorización creado con AWeber. Copia desde el popup y pégalo aquí." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Obtén tu código de autentificación" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Lista ID única" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="La Lista ID única de tu Lista. Se puede encontrar en la configuración de Listas de tu cuenta AWeber." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="¿Dónde encontrar tu Lista ID única?" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Actualiza usuario existente" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Actualiza el usuario en AWeber con los nuevos datos si es que ya existe." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber no permite Optin simple por su API. Lea nuestra documentación para más información." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="El código de autorización no es correcto. Por favor intenta obtener uno nuevo." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="La conexión con AWeber se ha establecido." PK!7DzDconvertforms/aweber/language/fi-FI/fi-FI.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Convert Forms - AWeber liitäntä" PLG_CONVERTFORMS_AWEBER_DESC="Convert Forms - Integrointi AWeber Email Marketing palveluun." PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Valtuutuskoodi" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="AWeberissä luotu valtuutuskoodi. Kopioi se ponnahdusikkunasta ja liitä se tähän." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Hanki valtuutus-koodi" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Uniikki luettelo ID" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="Luettelosi uniikki luettelo ID. Se löytyy AWeber-tilisi luetteloasetuksista." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Mistä löytyy uniikki luettelo ID" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Päivitä nykyinen käyttäjä" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Päivitä AWeber-käyttäjän tiedot uusilla tiedoilla, jos hän on jo olemassa." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber ei tue kertakirjautumista heidän sovellusliittymänsä kautta. Lue dokumenteista lisätietoa." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="Valtuutuskoodi on väärä. Yritä hankkia uusi." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="AWeber-yhteys on muodostettu onnistuneesti." PK!4...Dconvertforms/aweber/language/en-GB/en-GB.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Convert Forms - AWeber Integration" PLG_CONVERTFORMS_AWEBER_DESC="Convert Forms - Integration with AWeber Email Marketing Services." PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Authorization Code" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="The Authorization Code created from AWeber. Copy it from the popup and paste it here." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Get the Auth Code" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Unique List ID" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="The Unique List ID of your List. It can be found in the List Settings in your AWeber Account." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Where to find your Unique List ID" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Update existing user" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Update the user on AWeber with the new data if he already exists." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber does not support Single Opt-in through their API. Read our documentation for more info." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="The Authorization Code is not correct. Please try to get a new one." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="The AWeber connection has been successfully established."PK!fuooHconvertforms/aweber/language/en-GB/en-GB.plg_convertforms_aweber.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER="Convert Forms - AWeber Integration" PLG_CONVERTFORMS_AWEBER_DESC="Convert Forms - Integration with AWeber Email Marketing Services."PK!\vD488Dconvertforms/aweber/language/sv-SE/sv-SE.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Convert Forms - AWeber Integration" PLG_CONVERTFORMS_AWEBER_DESC="Convert Forms - Integration med AWeber Email Marketing Services." PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Behörighetskod" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Auktoriseringskoden skapad av AWeber. Kopiera den från popup-fönstret och klistra in den här." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Få auktoriseringskoden" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Unikt List ID" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="Din listas unika ID. Den finns i list-inställningarna på ditt AWeber-konto." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Var du hittar ditt unika list-ID" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Uppdatera befintlig användare" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Uppdatera användaren på AWeber med den nya datan om den redan finns." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber stöder inte Single Opt-in via deras API. Läs vår dokumentation för mer information." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="Auktoriseringskoden är inte korrekt. Försök att skaffa en ny." ; PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="The AWeber connection has been successfully established." PK!!&> > Dconvertforms/aweber/language/uk-UA/uk-UA.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Перетворити форми - інтеграція в веб-сайти" PLG_CONVERTFORMS_AWEBER_DESC="Перетворити форми - інтеграція з послугами маркетингу електронної пошти AWeber." PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Код авторизації" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Код авторизації, створений AWeber. Скопіюйте його зі спливаючого вікна та вставте його сюди." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Отримати код автентифікації" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Унікальний ідентифікатор списку" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="Унікальний ідентифікатор списку вашого списку. Ви можете знайти його в налаштуваннях списку вашого облікового запису AWeber." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Де ви можете знайти свій унікальний ідентифікатор списку?" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Оновити існуючого користувача" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Оновіть користувача в AWeber за допомогою нових даних, якщо він вже є." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber не підтримує єдине вхід через API. Читайте наш Документація для отримання додаткової інформації. " PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="Код авторизації невірний. Будь ласка, спробуйте отримати новий." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="З'єднання AWeber успішно встановлено." PK!֤Dconvertforms/aweber/language/fr-FR/fr-FR.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Convertisseur de formulaire - Intégration de AWeber" PLG_CONVERTFORMS_AWEBER_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing d'AWeber" PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Code d'autorisation" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Le code d'autorisation est créé depuis AWeber. Copiez-le depuis le popup et collez-le ici." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Obtenir le code d'authentification" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="ID unique de la liste" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="L'ID unique de votre liste. Il peut être trouvé dans les paramètres de liste dans votre compte AWeber." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Où trouver votre ID unique de la liste ?" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Mettre à jour un utilisateur existant" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Met à jour l'utilisateur sur AWeber avec les nouvelles données s'il existe déjà." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber ne supporte pas Single Opt-in depuis son API. Lisez notre documentation d'info." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="Le code d'autorisation est erroné. Merci d'essayer d'en obtenir un nouveau." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="La connexion de AWeber a été établi avec succès." PK! dDconvertforms/aweber/language/de-DE/de-DE.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Convert Forms - AWeber Integration" PLG_CONVERTFORMS_AWEBER_DESC="Convert Forms - Integration mit AWeber E-Mail-Marketing-Diensten." PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Autorisierungscode" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Der von AWeber erstellte Autorisierungscode. Kopieren Sie ihn aus dem Popup und fügen Sie ihn hier ein." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Authentifizierungscode abrufen" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="Eindeutige Listen ID" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="Die eindeutige Listen ID Ihrer Liste. Sie finden sie in den Listeneinstellungen in Ihrem AWeber-Konto." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Wo findet man die eindeutige Listen ID?" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Bestehenden Benutzer aktualisieren" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Aktualisieren Sie den Benutzer auf AWeber mit den neuen Daten, falls er bereits existiert." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber unterstützt kein einfaches Opt-in über sein API. Lesen Sie unsere Dokumentation für weitere Informationen." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE="Der Autorisierungscode ist nicht korrekt. Bitte versuchen Sie, einen neuen zu erhalten." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="Die AWeber-Verbindung wurde erfolgreich hergestellt." PK!O~~Dconvertforms/aweber/language/it-IT/it-IT.plg_convertforms_aweber.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_AWEBER_ALIAS="AWeber" PLG_CONVERTFORMS_AWEBER="Integrazione Convert Forms - AWeber " PLG_CONVERTFORMS_AWEBER_DESC="Integrazione Convert Forms con i servizi Email Marketing di AWeber" PLG_CONVERTFORMS_AWEBER_AUTH_CODE="Codice di autorizzazione" PLG_CONVERTFORMS_AWEBER_AUTH_CODE_DESC="Il codice di autorizzazione creato da AWeber. Copialo dal popup e incollalo qui." PLG_CONVERTFORMS_AWEBER_FIND_AUTH_CODE="Ricevi il codice di autorizzazione" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID="ID elenco unico" PLG_CONVERTFORMS_AWEBER_UNIQUE_LIST_ID_DESC="L'ID elenco unico del tuo elenco. Può essere trovato nelle impostazioni elenco nell'account AWeber." PLG_CONVERTFORMS_AWEBER_FIND_UNIQUE_LIST_ID="Dove trovare il tuo ID elenco unico" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER="Aggiorna utente esistente" PLG_CONVERTFORMS_AWEBER_UPDATE_EXISTING_USER_DESC="Aggiorna l'utente su AWeber con le nuove informazioni se è già esistente." PLG_CONVERTFORMS_AWEBER_SINGLE_OPTIN_DESC="AWeber non supporta opt-in singolo con le proprie API. Leggi la nostra documentazione per maggiori informazioni." PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE=" Il codice di autorizzazione non è corretto. Ti prego di procurartene uno nuovo." PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED="La connessione ad AWeber è stata stabilita con successo." PK!,UCCconvertforms/aweber/aweber.xmlnu[ PLG_CONVERTFORMS_AWEBER PLG_CONVERTFORMS_AWEBER_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later January 2017 script.install.php language wrapper aweber.php form.xml script.install.helper.php PK!4*convertforms/aweber/wrapper/exceptions.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); class AWeberException extends Exception { } /** * Thrown when the API returns an error. (HTTP status >= 400) * * * @uses AWeberException * @package * @version $id$ */ class AWeberAPIException extends AWeberException { public $type; public $status; public $message; public $documentation_url; public $url; public function __construct($error, $url) { // record specific details of the API exception for processing $this->url = $url; $this->type = $error['type']; $this->status = array_key_exists('status', $error) ? $error['status'] : ''; $this->message = $error['message']; $this->documentation_url = $error['documentation_url']; parent::__construct($this->message); } } /** * Thrown when attempting to use a resource that is not implemented. * * @uses AWeberException * @package * @version $id$ */ class AWeberResourceNotImplemented extends AWeberException { public function __construct($object, $value) { $this->object = $object; $this->value = $value; parent::__construct("Resource \"{$value}\" is not implemented on this resource."); } } /** * AWeberMethodNotImplemented * * Thrown when attempting to call a method that is not implemented for a resource * / collection. Differs from standard method not defined errors, as this will * be thrown when the method is infact implemented on the base class, but the * current resource type does not provide access to that method (ie calling * getByMessageNumber on a web_forms collection). * * @uses AWeberException * @package * @version $id$ */ class AWeberMethodNotImplemented extends AWeberException { public function __construct($object) { $this->object = $object; parent::__construct("This method is not implemented by the current resource."); } } /** * AWeberOAuthException * * OAuth exception, as generated by an API JSON error response * @uses AWeberException * @package * @version $id$ */ class AWeberOAuthException extends AWeberException { public function __construct($type, $message) { $this->type = $type; $this->message = $message; parent::__construct("{$type}: {$message}"); } } /** * AWeberOAuthDataMissing * * Used when a specific piece or pieces of data was not found in the * response. This differs from the exception that might be thrown as * an AWeberOAuthException when parameters are not provided because * it is not the servers' expectations that were not met, but rather * the expecations of the client were not met by the server. * * @uses AWeberException * @package * @version $id$ */ class AWeberOAuthDataMissing extends AWeberException { public function __construct($missing) { if (!is_array($missing)) { $missing = array($missing); } $this->missing = $missing; $required = join(', ', $this->missing); parent::__construct("OAuthDataMissing: Response was expected to contain: {$required}"); } } /** * AWeberResponseError * * This is raised when the server returns a non-JSON response. This * should only occur when there is a server or some type of connectivity * issue. * * @uses AWeberException * @package * @version $id$ */ class AWeberResponseError extends AWeberException { public function __construct($uri) { $this->uri = $uri; parent::__construct("Request for {$uri} did not respond properly."); } } PK!+\\,convertforms/aweber/wrapper/aweber_entry.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); class AWeberEntry extends AWeberResponse { /** * @var array Holds list of data keys that are not publicly accessible */ protected $_privateData = array( 'resource_type_link', 'http_etag', ); /** * @var array Stores local modifications that have not been saved */ protected $_localDiff = array(); /** * @var array Holds AWeberCollection objects already instantiated, keyed by * their resource name (plural) */ protected $_collections = array(); /** * attrs * * Provides a simple array of all the available data (and collections) available * in this entry. * * @access public * @return array */ public function attrs() { $attrs = array(); foreach ($this->data as $key => $value) { if (!in_array($key, $this->_privateData) && !strpos($key, 'collection_link')) { $attrs[$key] = $value; } } if (!empty(AWeberAPI::$_collectionMap[$this->type])) { foreach (AWeberAPI::$_collectionMap[$this->type] as $child) { $attrs[$child] = 'collection'; } } return $attrs; } /** * _type * * Used to pull the name of this resource from its resource_type_link * @access protected * @return String */ protected function _type() { if (empty($this->type)) { if (!empty($this->data['resource_type_link'])) { list($url, $type) = explode('#', $this->data['resource_type_link']); $this->type = $type; } elseif (!empty($this->data['broadcast_id'])) { $this->type = 'broadcast'; } else { return null; } } return $this->type; } /** * delete * * Delete this object from the AWeber system. May not be supported * by all entry types. * @access public * @return boolean Returns true if it is successfully deleted, false * if the delete request failed. */ public function delete() { $this->adapter->request('DELETE', $this->url, array(), array('return' => 'status')); return true; } /** * move * * Invoke the API method to MOVE an entry resource to a different List. * * Note: Not all entry resources are eligible to be moved, please * refer to the AWeber API Reference Documentation at * https://labs.aweber.com/docs/reference/1.0 for more * details on which entry resources may be moved and if there * are any requirements for moving that resource. * * @access public * @param AWeberEntry(List) List to move Resource (this) too. * @return mixed AWeberEntry(Resource) Resource created on List ($list) * or False if resource was not created. */ public function move($list, $last_followup_message_number_sent = NULL) { # Move Resource $params = array( 'ws.op' => 'move', 'list_link' => $list->self_link, ); if (isset($last_followup_message_number_sent)) { $params['last_followup_message_number_sent'] = $last_followup_message_number_sent; } $data = $this->adapter->request('POST', $this->url, $params, array('return' => 'headers')); # Return new Resource $url = $data['Location']; $resource_data = $this->adapter->request('GET', $url); return new AWeberEntry($resource_data, $url, $this->adapter); } /** * save * * Saves the current state of this object if it has been changed. * @access public * @return void */ public function save() { if (!empty($this->_localDiff)) { $data = $this->adapter->request('PATCH', $this->url, $this->_localDiff, array('return' => 'status')); } $this->_localDiff = array(); return true; } /** * __get * * Used to look up items in data, and special properties like type and * child collections dynamically. * * @param String $value Attribute being accessed * @access public * @throws AWeberResourceNotImplemented * @return mixed */ public function __get($value) { if (in_array($value, $this->_privateData)) { return null; } if (!empty($this->data) && array_key_exists($value, $this->data)) { if (is_array($this->data[$value])) { $array = new AWeberEntryDataArray($this->data[$value], $value, $this); $this->data[$value] = $array; } return $this->data[$value]; } if ($value == 'type') { return $this->_type(); } if ($this->_isChildCollection($value)) { return $this->_getCollection($value); } throw new AWeberResourceNotImplemented($this, $value); } /** * __set * * If the key provided is part of the data array, then update it in the * data array. Otherwise, use the default __set() behavior. * * @param mixed $key Key of the attr being set * @param mixed $value Value being set to the $key attr * @access public */ public function __set($key, $value) { if (array_key_exists($key, $this->data)) { $this->_localDiff[$key] = $value; return $this->data[$key] = $value; } else { return parent::__set($key, $value); } } /** getParentEntry * * Gets an entry's parent entry * Returns NULL if no parent entry */ public function getParentEntry() { $url_parts = explode('/', $this->url); $size = count($url_parts); #Remove entry id and slash from end of url $url = substr($this->url, 0, -strlen($url_parts[$size - 1]) - 1); #Remove collection name and slash from end of url $url = substr($url, 0, -strlen($url_parts[$size - 2]) - 1); try { $data = $this->adapter->request('GET', $url); return new AWeberEntry($data, $url, $this->adapter); } catch (Exception $e) { return NULL; } } /** * _parseNamedOperation * * Turns a dumb array of json into an array of Entries. This is NOT * a collection, but simply an array of entries, as returned from a * named operation. * * @param array $data * @access protected * @return array */ protected function _parseNamedOperation($data) { $results = array(); foreach ($data as $entryData) { $results[] = new AWeberEntry($entryData, str_replace($this->adapter->app->getBaseUri(), '', $entryData['self_link']), $this->adapter); } return $results; } /** * _methodFor * * Raises exception if $this->type is not in array entryTypes. * Used to restrict methods to specific entry type(s). * @param mixed $entryTypes Array of entry types as strings, ie array('account') * @access protected * @return void */ protected function _methodFor($entryTypes) { if (in_array($this->type, $entryTypes)) { return true; } throw new AWeberMethodNotImplemented($this); } /** * _getCollection * * Returns the AWeberCollection object representing the given * collection name, relative to this entry. * * @param String $value The name of the sub-collection * @access protected * @return AWeberCollection */ protected function _getCollection($value) { if (empty($this->_collections[$value])) { $url = "{$this->url}/{$value}"; $data = $this->adapter->request('GET', $url); $this->_collections[$value] = new AWeberCollection($data, $url, $this->adapter); } return $this->_collections[$value]; } /** * _isChildCollection * * Is the given name of a collection a child collection of this entry? * * @param String $value The name of the collection we are looking for * @access protected * @return boolean * @throws AWeberResourceNotImplemented */ protected function _isChildCollection($value) { $this->_type(); if (!empty(AWeberAPI::$_collectionMap[$this->type]) && in_array($value, AWeberAPI::$_collectionMap[$this->type])) { return true; } return false; } } PK!b_""-convertforms/aweber/wrapper/oauth_adapter.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); interface AWeberOAuthAdapter { public function request($method, $uri, $data = array()); public function getRequestToken($callbackUrl = false); } ?> PK!U8ؔ""*convertforms/aweber/wrapper/aweber_api.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/exceptions.php'; require_once __DIR__ . '/oauth_adapter.php'; require_once __DIR__ . '/oauth_application.php'; require_once __DIR__ . '/aweber_response.php'; require_once __DIR__ . '/aweber_collection.php'; require_once __DIR__ . '/aweber_entry_data_array.php'; require_once __DIR__ . '/aweber_entry.php'; /** * AWeberServiceProvider * * Provides specific AWeber information or implementing OAuth. * @uses OAuthServiceProvider * @package * @version $id$ */ class AWeberServiceProvider implements OAuthServiceProvider { /** * @var String Location for API calls */ public $baseUri = 'https://api.aweber.com/1.0'; /** * @var String Location to request an access token */ public $accessTokenUrl = 'https://auth.aweber.com/1.0/oauth/access_token'; /** * @var String Location to authorize an Application */ public $authorizeUrl = 'https://auth.aweber.com/1.0/oauth/authorize'; /** * @var String Location to request a request token */ public $requestTokenUrl = 'https://auth.aweber.com/1.0/oauth/request_token'; public function getBaseUri() { return $this->baseUri; } public function removeBaseUri($url) { return str_replace($this->getBaseUri(), '', $url); } public function getAccessTokenUrl() { return $this->accessTokenUrl; } public function getAuthorizeUrl() { return $this->authorizeUrl; } public function getRequestTokenUrl() { return $this->requestTokenUrl; } public function getAuthTokenFromUrl() { return ''; } public function getUserData() { return ''; } } /** * AWeberAPIBase * * Base object that all AWeberAPI objects inherit from. Allows specific pieces * of functionality to be shared across any object in the API, such as the * ability to introspect the collections map. * * @package * @version $id$ */ class AWeberAPIBase { /** * Maintains data about what children collections a given object type * contains. */ static protected $_collectionMap = array( 'account' => array('lists', 'integrations'), 'broadcast_campaign' => array('links', 'messages', 'stats'), 'followup_campaign' => array('links', 'messages', 'stats'), 'link' => array('clicks'), 'list' => array('campaigns', 'custom_fields', 'subscribers', 'web_forms', 'web_form_split_tests'), 'web_form' => array(), 'web_form_split_test' => array('components'), ); /** * loadFromUrl * * Creates an object, either collection or entry, based on the given * URL. * * @param mixed $url URL for this request * @access public * @return AWeberEntry or AWeberCollection */ public function loadFromUrl($url) { $data = $this->adapter->request('GET', $url); return $this->readResponse($data, $url); } protected function _cleanUrl($url) { return str_replace($this->adapter->app->getBaseUri(), '', $url); } /** * readResponse * * Interprets a response, and creates the appropriate object from it. * @param mixed $response Data returned from a request to the AWeberAPI * @param mixed $url URL that this data was requested from * @access protected * @return mixed */ protected function readResponse($response, $url) { $this->adapter->parseAsError($response); if (!empty($response['id']) || !empty($response['broadcast_id'])) { return new AWeberEntry($response, $url, $this->adapter); } else if (array_key_exists('entries', $response)) { return new AWeberCollection($response, $url, $this->adapter); } return false; } } /** * AWeberAPI * * Creates a connection to the AWeberAPI for a given consumer application. * This is generally the starting point for this library. Instances can be * created directly with consumerKey and consumerSecret. * @uses AWeberAPIBase * @package * @version $id$ */ class AWeberAPI extends AWeberAPIBase { /** * @var String Consumer Key */ public $consumerKey = false; /** * @var String Consumer Secret */ public $consumerSecret = false; /** * @var Object - Populated in setAdapter() */ public $adapter = false; /** * Uses the app's authorization code to fetch an access token * * @param String Authorization code from authorize app page */ public static function getDataFromAweberID($string) { list($consumerKey, $consumerSecret, $requestToken, $tokenSecret, $verifier) = AWeberAPI::_parseAweberID($string); if (!$verifier) { return null; } $aweber = new AWeberAPI($consumerKey, $consumerSecret); $aweber->adapter->user->requestToken = $requestToken; $aweber->adapter->user->tokenSecret = $tokenSecret; $aweber->adapter->user->verifier = $verifier; list($accessToken, $accessSecret) = $aweber->getAccessToken(); return array($consumerKey, $consumerSecret, $accessToken, $accessSecret); } protected static function _parseAWeberID($string) { $values = explode('|', $string); if (count($values) < 5) { return null; } return array_slice($values, 0, 5); } /** * Sets the consumer key and secret for the API object. The * key and secret are listed in the My Apps page in the labs.aweber.com * Control Panel OR, in the case of distributed apps, will be returned * from the getDataFromAweberID() function * * @param String Consumer Key * @param String Consumer Secret * @return null */ public function __construct($key, $secret) { // Load key / secret $this->consumerKey = $key; $this->consumerSecret = $secret; $this->setAdapter(); } /** * Returns the authorize URL by appending the request * token to the end of the Authorize URI, if it exists * * @return string The Authorization URL */ public function getAuthorizeUrl() { $requestToken = $this->user->requestToken; return (empty($requestToken)) ? $this->adapter->app->getAuthorizeUrl() : $this->adapter->app->getAuthorizeUrl() . "?oauth_token={$this->user->requestToken}"; } /** * Sets the adapter for use with the API */ public function setAdapter($adapter = null) { if (empty($adapter)) { $serviceProvider = new AWeberServiceProvider(); $adapter = new OAuthApplication($serviceProvider); $adapter->consumerKey = $this->consumerKey; $adapter->consumerSecret = $this->consumerSecret; } $this->adapter = $adapter; } /** * Fetches account data for the associated account * * @param String Access Token (Only optional/cached if you called getAccessToken() earlier * on the same page) * @param String Access Token Secret (Only optional/cached if you called getAccessToken() earlier * on the same page) * @return Object AWeberCollection Object with the requested * account data */ public function getAccount($token = false, $secret = false) { if ($token && $secret) { $user = new OAuthUser(); $user->accessToken = $token; $user->tokenSecret = $secret; $this->adapter->user = $user; } $body = $this->adapter->request('GET', '/accounts'); $accounts = $this->readResponse($body, '/accounts'); return $accounts[0]; } /** * PHP Automagic */ public function __get($item) { if ($item == 'user') { return $this->adapter->user; } trigger_error("Could not find \"{$item}\""); } /** * Request a request token from AWeber and associate the * provided $callbackUrl with the new token * @param String The URL where users should be redirected * once they authorize your app * @return Array Contains the request token as the first item * and the request token secret as the second item of the array */ public function getRequestToken($callbackUrl) { $requestToken = $this->adapter->getRequestToken($callbackUrl); return array($requestToken, $this->user->tokenSecret); } /** * Request an access token using the request tokens stored in the * current user object. You would want to first set the request tokens * on the user before calling this function via: * * $aweber->user->tokenSecret = $_COOKIE['requestTokenSecret']; * $aweber->user->requestToken = $_GET['oauth_token']; * $aweber->user->verifier = $_GET['oauth_verifier']; * * @return Array Contains the access token as the first item * and the access token secret as the second item of the array */ public function getAccessToken() { return $this->adapter->getAccessToken(); } } ?> PK!KK1convertforms/aweber/wrapper/oauth_application.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); if (!class_exists('CurlObject')) { require_once 'curl_object.php'; } if (!class_exists('CurlResponse')) { require_once 'curl_response.php'; } /** * OAuthServiceProvider * * Represents the service provider in the OAuth authentication model. * The class that implements the service provider will contain the * specific knowledge about the API we are interfacing with, and * provide useful methods for interfacing with its API. * * For example, an OAuthServiceProvider would know the URLs necessary * to perform specific actions, the type of data that the API calls * would return, and would be responsible for manipulating the results * into a useful manner. * * It should be noted that the methods enforced by the OAuthServiceProvider * interface are made so that it can interact with our OAuthApplication * cleanly, rather than from a general use perspective, though some * methods for those purposes do exists (such as getUserData). * * @package * @version $id$ */ interface OAuthServiceProvider { public function getAccessTokenUrl(); public function getAuthorizeUrl(); public function getRequestTokenUrl(); public function getAuthTokenFromUrl(); public function getBaseUri(); public function getUserData(); } /** * OAuthApplication * * Base class to represent an OAuthConsumer application. This class is * intended to be extended and modified for each ServiceProvider. Each * OAuthServiceProvider should have a complementary OAuthApplication * * The OAuthApplication class should contain any details on preparing * requires that is unique or specific to that specific service provider's * implementation of the OAuth model. * * This base class is based on OAuth 1.0, designed with AWeber's implementation * as a model. An OAuthApplication built to work with a different service * provider (especially an OAuth2.0 Application) may alter or bypass portions * of the logic in this class to meet the needs of the service provider it * is designed to interface with. * * @package * @version $id$ */ class OAuthApplication implements AWeberOAuthAdapter { public $debug = false; public $userAgent = 'AWeber OAuth Consumer Application 1.0 - https://labs.aweber.com/'; public $format = false; public $requiresTokenSecret = true; public $signatureMethod = 'HMAC-SHA1'; public $version = '1.0'; public $curl = false; /** * @var OAuthUser User currently interacting with the service provider */ public $user = false; // Data binding this OAuthApplication to the consumer application it is acting // as a proxy for public $consumerKey = false; public $consumerSecret = false; /** * __construct * * Create a new OAuthApplication, based on an OAuthServiceProvider * @access public * @return void */ public function __construct($parentApp = false) { if ($parentApp) { if (!is_a($parentApp, 'OAuthServiceProvider')) { throw new Exception('Parent App must be a valid OAuthServiceProvider!'); } $this->app = $parentApp; } $this->user = new OAuthUser(); $this->curl = new CurlObject(); } /** * request * * Implemented for a standard OAuth adapter interface * @param mixed $method * @param mixed $uri * @param array $data * @param array $options * @access public * @return void */ public function request($method, $uri, $data = array(), $options = array()) { $uri = $this->app->removeBaseUri($uri); $url = $this->app->getBaseUri() . $uri; # WARNING: non-primative items in data must be json serialized in GET and POST. if ($method == 'POST' or $method == 'GET') { foreach ($data as $key => $value) { if (is_array($value)) { $data[$key] = json_encode($value); } } } $response = $this->makeRequest($method, $url, $data); if (!empty($options['return'])) { if ($options['return'] == 'status') { return $response->headers['Status-Code']; } if ($options['return'] == 'headers') { return $response->headers; } if ($options['return'] == 'integer') { return intval($response->body); } } $data = json_decode($response->body, true); if (empty($options['allow_empty']) && !isset($data)) { throw new AWeberResponseError($uri); } return $data; } /** * getRequestToken * * Gets a new request token / secret for this user. * @access public * @return void */ public function getRequestToken($callbackUrl = false) { $data = ($callbackUrl) ? array('oauth_callback' => $callbackUrl) : array(); $resp = $this->makeRequest('POST', $this->app->getRequestTokenUrl(), $data); $data = $this->parseResponse($resp); $this->requiredFromResponse($data, array('oauth_token', 'oauth_token_secret')); $this->user->requestToken = $data['oauth_token']; $this->user->tokenSecret = $data['oauth_token_secret']; return $data['oauth_token']; } /** * getAccessToken * * Makes a request for access tokens. Requires that the current user has an authorized * token and token secret. * * @access public * @return void */ public function getAccessToken() { $resp = $this->makeRequest('POST', $this->app->getAccessTokenUrl(), array('oauth_verifier' => $this->user->verifier) ); $data = $this->parseResponse($resp); $this->requiredFromResponse($data, array('oauth_token', 'oauth_token_secret')); if (empty($data['oauth_token'])) { throw new AWeberOAuthDataMissing('oauth_token'); } $this->user->accessToken = $data['oauth_token']; $this->user->tokenSecret = $data['oauth_token_secret']; return array($data['oauth_token'], $data['oauth_token_secret']); } /** * parseAsError * * Checks if response is an error. If it is, raise an appropriately * configured exception. * * @param mixed $response Data returned from the server, in array form * @access public * @throws AWeberOAuthException * @return void */ public function parseAsError($response) { if (!empty($response['error'])) { throw new AWeberOAuthException($response['error']['type'], $response['error']['message']); } } /** * requiredFromResponse * * Enforce that all the fields in requiredFields are present and not * empty in data. If a required field is empty, throw an exception. * * @param mixed $data Array of data * @param mixed $requiredFields Array of required field names. * @access protected * @return void */ protected function requiredFromResponse($data, $requiredFields) { foreach ($requiredFields as $field) { if (empty($data[$field])) { throw new AWeberOAuthDataMissing($field); } } } /** * get * * Make a get request. Used to exchange user tokens with serice provider. * @param mixed $url URL to make a get request from. * @param array $data Data for the request. * @access protected * @return void */ protected function get($url, $data) { $url = $this->_addParametersToUrl($url, $data); $handle = $this->curl->init($url); $resp = $this->_sendRequest($handle); return $resp; } /** * _addParametersToUrl * * Adds the parameters in associative array $data to the * given URL * @param String $url URL * @param array $data Parameters to be added as a query string to * the URL provided * @access protected * @return void */ protected function _addParametersToUrl($url, $data) { if (!empty($data)) { if (strpos($url, '?') === false) { $url .= '?' . $this->buildData($data); } else { $url .= '&' . $this->buildData($data); } } return $url; } /** * generateNonce * * Generates a 'nonce', which is a unique request id based on the * timestamp. If no timestamp is provided, generate one. * @param mixed $timestamp Either a timestamp (epoch seconds) or false, * in which case it will generate a timestamp. * @access public * @return string Returns a unique nonce */ public function generateNonce($timestamp = false) { if (!$timestamp) { $timestamp = $this->generateTimestamp(); } return md5($timestamp . '-' . rand(10000, 99999) . '-' . uniqid()); } /** * generateTimestamp * * Generates a timestamp, in seconds * @access public * @return int Timestamp, in epoch seconds */ public function generateTimestamp() { return time(); } /** * createSignature * * Creates a signature on the signature base and the signature key * @param mixed $sigBase Base string of data to sign * @param mixed $sigKey Key to sign the data with * @access public * @return string The signature */ public function createSignature($sigBase, $sigKey) { switch ($this->signatureMethod) { case 'HMAC-SHA1': default: return base64_encode(hash_hmac('sha1', $sigBase, $sigKey, true)); } } /** * encode * * Short-cut for utf8_encode / rawurlencode * @param mixed $data Data to encode * @access protected * @return void Encoded data */ protected function encode($data) { return rawurlencode($data); } /** * createSignatureKey * * Creates a key that will be used to sign our signature. Signatures * are signed with the consumerSecret for this consumer application and * the token secret of the user that the application is acting on behalf * of. * @access public * @return void */ public function createSignatureKey() { return $this->consumerSecret . '&' . $this->user->tokenSecret; } /** * getOAuthRequestData * * Get all the pre-signature, OAuth specific parameters for a request. * @access public * @return void */ public function getOAuthRequestData() { $token = $this->user->getHighestPriorityToken(); $ts = $this->generateTimestamp(); $nonce = $this->generateNonce($ts); return array( 'oauth_token' => $token, 'oauth_consumer_key' => $this->consumerKey, 'oauth_version' => $this->version, 'oauth_timestamp' => $ts, 'oauth_signature_method' => $this->signatureMethod, 'oauth_nonce' => $nonce); } /** * mergeOAuthData * * @param mixed $requestData * @access public * @return void */ public function mergeOAuthData($requestData) { $oauthData = $this->getOAuthRequestData(); return array_merge($requestData, $oauthData); } /** * createSignatureBase * * @param mixed $method String name of HTTP method, such as "GET" * @param mixed $url URL where this request will go * @param mixed $data Array of params for this request. This should * include ALL oauth properties except for the signature. * @access public * @return void */ public function createSignatureBase($method, $url, $data) { $method = $this->encode(strtoupper($method)); $query = parse_url($url, PHP_URL_QUERY); if ($query) { $parts = explode('?', $url, 2); $url = array_shift($parts); $items = explode('&', $query); foreach ($items as $item) { list($key, $value) = explode('=', $item); $data[rawurldecode($key)] = rawurldecode($value); } } $url = $this->encode($url); $data = $this->encode($this->collapseDataForSignature($data)); return $method . '&' . $url . '&' . $data; } /** * collapseDataForSignature * * Turns an array of request data into a string, as used by the oauth * signature * @param mixed $data * @access public * @return void */ public function collapseDataForSignature($data) { ksort($data); $collapse = ''; foreach ($data as $key => $val) { if (!empty($collapse)) { $collapse .= '&'; } $collapse .= $key . '=' . $this->encode($val); } return $collapse; } /** * signRequest * * Signs the request. * * @param mixed $method HTTP method * @param mixed $url URL for the request * @param mixed $data The data to be signed * @access public * @return array The data, with the signature. */ public function signRequest($method, $url, $data) { $base = $this->createSignatureBase($method, $url, $data); $key = $this->createSignatureKey(); $data['oauth_signature'] = $this->createSignature($base, $key); ksort($data); return $data; } /** * makeRequest * * Public facing function to make a request * * @param mixed $method * @param mixed $url - Reserved characters in query params MUST be escaped * @param mixed $data - Reserved characters in values MUST NOT be escaped * @access public * @return void */ public function makeRequest($method, $url, $data = array()) { if ($this->debug) { echo "\n** {$method}: $url\n"; } switch (strtoupper($method)) { case 'POST': $oauth = $this->prepareRequest($method, $url, $data); $resp = $this->post($url, $oauth); break; case 'GET': $oauth = $this->prepareRequest($method, $url, $data); $resp = $this->get($url, $oauth, $data); break; case 'DELETE': $oauth = $this->prepareRequest($method, $url, $data); $resp = $this->delete($url, $oauth); break; case 'PATCH': $oauth = $this->prepareRequest($method, $url, array()); $resp = $this->patch($url, $oauth, $data); break; } // enable debug output if ($this->debug) { echo "
    ";
    			print_r($oauth);
    			echo " --> Status: {$resp->headers['Status-Code']}\n";
    			echo " --> Body: {$resp->body}";
    			echo "
    "; } if (!$resp) { $msg = 'Unable to connect to the AWeber API. (' . $this->error . ')'; $error = array('message' => $msg, 'type' => 'APIUnreachableError', 'documentation_url' => 'https://labs.aweber.com/docs/troubleshooting'); throw new AWeberAPIException($error, $url); } if ($resp->headers['Status-Code'] >= 400) { $data = json_decode($resp->body, true); throw new AWeberAPIException($data['error'], $url); } return $resp; } /** * put * * Prepare an OAuth put method. * * @param mixed $url URL where we are making the request to * @param mixed $data Data that is used to make the request * @access protected * @return void */ protected function patch($url, $oauth, $data) { $url = $this->_addParametersToUrl($url, $oauth); $handle = $this->curl->init($url); $this->curl->setopt($handle, CURLOPT_CUSTOMREQUEST, 'PATCH'); $this->curl->setopt($handle, CURLOPT_POSTFIELDS, json_encode($data)); $resp = $this->_sendRequest($handle, array('Expect:', 'Content-Type: application/json')); return $resp; } /** * post * * Prepare an OAuth post method. * * @param mixed $url URL where we are making the request to * @param mixed $data Data that is used to make the request * @access protected * @return void */ protected function post($url, $oauth) { $handle = $this->curl->init($url); $postData = $this->buildData($oauth); $this->curl->setopt($handle, CURLOPT_POST, true); $this->curl->setopt($handle, CURLOPT_POSTFIELDS, $postData); $resp = $this->_sendRequest($handle); return $resp; } /** * delete * * Makes a DELETE request * @param mixed $url URL where we are making the request to * @param mixed $data Data that is used in the request * @access protected * @return void */ protected function delete($url, $data) { $url = $this->_addParametersToUrl($url, $data); $handle = $this->curl->init($url); $this->curl->setopt($handle, CURLOPT_CUSTOMREQUEST, 'DELETE'); $resp = $this->_sendRequest($handle); return $resp; } /** * buildData * * Creates a string of data for either post or get requests. * @param mixed $data Array of key value pairs * @access public * @return void */ public function buildData($data) { ksort($data); $params = array(); foreach ($data as $key => $value) { $params[] = $key . '=' . $this->encode($value); } return implode('&', $params); } /** * _sendRequest * * Actually makes a request. * @param mixed $handle Curl handle * @param array $headers Additional headers needed for request * @access private * @return void */ private function _sendRequest($handle, $headers = array('Expect:')) { $this->curl->setopt($handle, CURLOPT_RETURNTRANSFER, true); $this->curl->setopt($handle, CURLOPT_HEADER, true); $this->curl->setopt($handle, CURLOPT_HTTPHEADER, $headers); $this->curl->setopt($handle, CURLOPT_USERAGENT, $this->userAgent); $this->curl->setopt($handle, CURLOPT_SSL_VERIFYPEER, FALSE); $this->curl->setopt($handle, CURLOPT_VERBOSE, FALSE); $this->curl->setopt($handle, CURLOPT_CONNECTTIMEOUT, 10); $this->curl->setopt($handle, CURLOPT_TIMEOUT, 90); $resp = $this->curl->execute($handle); if ($resp) { return new CurlResponse($resp); } $this->error = $this->curl->errno($handle) . ' - ' . $this->curl->error($handle); return false; } /** * prepareRequest * * @param mixed $method HTTP method * @param mixed $url URL for the request * @param mixed $data The data to generate oauth data and be signed * @access public * @return void The data, with all its OAuth variables and signature */ public function prepareRequest($method, $url, $data) { $data = $this->mergeOAuthData($data); $data = $this->signRequest($method, $url, $data); return $data; } /** * parseResponse * * Parses the body of the response into an array * @param mixed $string The body of a response * @access public * @return void */ public function parseResponse($resp) { $data = array(); if (!$resp) { return $data;} if (empty($resp)) { return $data;} if (empty($resp->body)) { return $data;} switch ($this->format) { case 'json': $data = json_decode($resp->body); break; default: parse_str($resp->body, $data); } $this->parseAsError($data); return $data; } } /** * OAuthUser * * Simple data class representing the user in an OAuth application. * @package * @version $id$ */ class OAuthUser { public $authorizedToken = false; public $requestToken = false; public $verifier = false; public $tokenSecret = false; public $accessToken = false; /** * isAuthorized * * Checks if this user is authorized. * @access public * @return void */ public function isAuthorized() { if (empty($this->authorizedToken) && empty($this->accessToken)) { return false; } return true; } /** * getHighestPriorityToken * * Returns highest priority token - used to define authorization * state for a given OAuthUser * @access public * @return void */ public function getHighestPriorityToken() { if (!empty($this->accessToken)) { return $this->accessToken; } if (!empty($this->authorizedToken)) { return $this->authorizedToken; } if (!empty($this->requestToken)) { return $this->requestToken; } // Return no token, new user return ''; } } ?> PK!/!ll/convertforms/aweber/wrapper/aweber_response.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); /** * AWeberResponse * * Base class for objects that represent a response from the AWeberAPI. * Responses will exist as one of the two AWeberResponse subclasses: * - AWeberEntry - a single instance of an AWeber resource * - AWeberCollection - a collection of AWeber resources * @uses AWeberAPIBase * @package * @version $id$ */ class AWeberResponse extends AWeberAPIBase { public $adapter = false; public $data = array(); public $_dynamicData = array(); /** * __construct * * Creates a new AWeberRespones * * @param mixed $response Data returned by the API servers * @param mixed $url URL we hit to get the data * @param mixed $adapter OAuth adapter used for future interactions * @access public * @return void */ public function __construct($response, $url, $adapter) { $this->adapter = $adapter; $this->url = $url; $this->data = $response; } /** * __set * * Manual re-implementation of __set, allows sub classes to access * the default behavior by using the parent:: format. * * @param mixed $key Key of the attr being set * @param mixed $value Value being set to the attr * @access public */ public function __set($key, $value) { $this->{$key} = $value; } /** * __get * * PHP "MagicMethod" to allow for dynamic objects. Defers first to the * data in $this->data. * * @param String $value Name of the attribute requested * @access public * @return mixed */ public function __get($value) { if (in_array($value, $this->_privateData)) { return null; } if (array_key_exists($value, $this->data)) { return $this->data[$value]; } if ($value == 'type') { return $this->_type(); } } } PK!etU-convertforms/aweber/wrapper/curl_response.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); # CurlResponse # # Author Sean Huber - shuber@huberry.com # Date May 2008 # # A basic CURL wrapper for PHP # # See the README for documentation/examples or http://php.net/curl for more information # about the libcurl extension for PHP -- http://github.com/shuber/curl/tree/master # class CurlResponse { public $body = ''; public $headers = array(); public function __construct($response) { # Extract headers from response $pattern = '#HTTP/\d\.\d.*?$.*?\r\n\r\n#ims'; preg_match_all($pattern, $response, $matches); $headers = explode("\r\n", str_replace("\r\n\r\n", '', array_pop($matches[0]))); # Extract the version and status from the first header $version_and_status = array_shift($headers); preg_match('#HTTP/(\d\.\d)\s(\d\d\d)\s(.*)#', $version_and_status, $matches); $this->headers['Http-Version'] = $matches[1]; $this->headers['Status-Code'] = $matches[2]; $this->headers['Status'] = $matches[2] . ' ' . $matches[3]; # Convert headers into an associative array foreach ($headers as $header) { preg_match('#(.*?)\:\s(.*)#', $header, $matches); $this->headers[$matches[1]] = $matches[2]; } # Remove the headers from the response body $this->body = preg_replace($pattern, '', $response); } public function __toString() { return $this->body; } public function headers() { return $this->headers; } } PK!Z +convertforms/aweber/wrapper/curl_object.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); /** * CurlInterface * * An object-oriented shim that wraps the standard PHP cURL library. * * This interface has been created so that cURL functionality can be stubbed * out for unit testing, or swapped for an alternative library. * * @see curl * @package * @version $id$ */ interface CurlInterface { /** * errNo * * Encapsulates curl_errno - Returns the last error number * @param resource $ch - A cURL handle returned by init. * @access public * @return the error number or 0 if no error occured. */ public function errno($ch); /** * error * * Encapsulates curl_error - Return last error string * @param resource $ch - A cURL handle returned by init. * @access public * @return the error messge or '' if no error occured. */ public function error($ch); /** * execute * * Encapsulates curl_exec - Perform a cURL session. * @param resource $ch - A cURL handle returned by init. * @access public * @return TRUE on success, FALSE on failure. */ public function execute($ch); /** * init * * Encapsulates curl_init - Initialize a cURL session. * @param string $url - url to use. * @access public * @return cURL handle on success, FALSE on failure. */ public function init($url); /** * setopt * * Encapsulates curl_setopt - Set an option for cURL transfer. * @param resource $ch - A cURL handle returned by init. * @param int $opt - The CURLOPT to set. * @param mixed $value - The value to set. * @access public * @return True on success, FALSE on failure. */ public function setopt($ch, $option, $value); } /** * CurlObject * * A concrete implementation of CurlInterface using the PHP cURL library. * * @package * @version $id$ */ class CurlObject implements CurlInterface { public function errno($ch) { return curl_errno($ch); } public function error($ch) { return curl_error($ch); } public function execute($ch) { return curl_exec($ch); } public function init($url) { return curl_init($url); } public function setopt($ch, $option, $value) { return curl_setopt($ch, $option, $value); } } ?> PK!7convertforms/aweber/wrapper/aweber_entry_data_array.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); class AWeberEntryDataArray implements ArrayAccess, Countable, Iterator { private $counter = 0; protected $data; protected $keys; protected $name; protected $parent; public function __construct($data, $name, $parent) { $this->data = $data; $this->keys = array_keys($data); $this->name = $name; $this->parent = $parent; } public function count() { return sizeOf($this->data); } public function offsetExists($offset) { return (isset($this->data[$offset])); } public function offsetGet($offset) { return $this->data[$offset]; } public function offsetSet($offset, $value) { $this->data[$offset] = $value; $this->parent->{$this->name} = $this->data; return $value; } public function offsetUnset($offset) { unset($this->data[$offset]); } public function rewind() { $this->counter = 0; } public function current() { return $this->data[$this->key()]; } public function key() { return $this->keys[$this->counter]; } public function next() { $this->counter++; } public function valid() { if ($this->counter >= sizeOf($this->data)) { return false; } return true; } } ?> PK!ۡ=='convertforms/aweber/wrapper/wrapper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die; require_once __DIR__ . '/aweber_api.php'; class NR_AWeber { /** * Create a new instance of NR_AWeber * * @param array $credentials An array containing the consumerKey, consumerSecret, * accessToken and accessSecret * @param string $listUID The AWeber Unique List ID */ public function __construct($credentials, $listUID) { if (!NR_AWeber::checkCredentials($credentials)) { throw new Exception("The AWeber Credentials are incomplete or incorrect", 1); } $this->application = new AWeberAPI($credentials['consumerKey'], $credentials['consumerSecret']); $this->account = $this->application->getAccount($credentials['accessToken'], $credentials['accessSecret']); $this->list = $this->findList($listUID); if ($this->list === false) { throw new Exception("The AWeber List could not be found", 1); } } /** * Finds the List resource * * @param string $listUID The AWeber Unique List ID * * @return object The AWeber List resource */ public function findList($listUID) { $foundLists = $this->account->lists->find(array('name' => $listUID)); if (count($foundLists)) { $foundList = $foundLists[0]; $listUrl = "/accounts/{$this->account->id}/lists/{$foundList->id}"; $list = $this->account->loadFromUrl($listUrl); return $list; } return false; } /** * Finds the Subscriber resource * * @param string $email The email of the subscriber we are searching for * * @return object The AWeber Subscriber resource */ public function findSubscriber($email) { $foundSubscribers = $this->list->subscribers->find(array('email' => $email)); return $foundSubscribers[0]; } /** * Updates a Subscriber * * @param array $subscriber An array containing subscriber data * * @return boolean The result of the operation */ public function updateSubscriber($subscriber) { $oldSubscriber = $this->findSubscriber($subscriber['email']); // If the subscriber does not exist, create it if (!is_object($oldSubscriber)) { return $this->createSubscriber($subscriber); } foreach ($subscriber as $key => $value) { // Fix Tags if ($key == 'tags') { $newTags = $value; if (empty($newTags) || is_null($newTags)) { continue; } $oldSubscriber->tags = [ 'add' => (array) $newTags, 'remove' => array_diff($oldSubscriber->data['tags'], $newTags) ]; continue; } $oldSubscriber->$key = $value; } $oldSubscriber->save(); return true; } /** * Creates a Subscriber * * @param array $subscriber An array containing subscriber data * * @return boolean The result of the operation */ public function createSubscriber($subscriber) { $newSubscriber = $this->list->subscribers->create($subscriber); return true; } /** * The entry point of a subscribe operation * * @param array $subscriber An array containing subscriber data * * @return boolean The result of the operation */ public function subscribe($subscriber) { if ($subscriber['updateexisting']) { $this->updateSubscriber($subscriber); } else { $this->createSubscriber($subscriber); } return true; } /** * Checks if the credentials have the correct structure for the OAuth 1.0 protocol * * @param array $credentials An array containing the consumerKey, consumerSecret, * accessToken and accessSecret * @param object $oldCampaign The campaign object carrying the old data * * @return boolean The result of the check */ public static function checkCredentials($credentials, $oldCampaign = false) { // Typecast simple objects $credentials = (array) $credentials; // Remove empty values $credentials = array_filter($credentials); // We need to have the following keys present in the credentials array $requiredCredentialsKeys = array('consumerKey', 'consumerSecret', 'accessToken', 'accessSecret'); // We need to check if the Auth Code has changed if (($oldCampaign !== false) && (is_object($oldCampaign)) && (isset($oldCampaign->authcode)) && ($oldCampaign->authcode !== $credentials['authcode'])) { return false; } // Check if the above mandatory keys are present if (count(array_intersect_key(array_flip($requiredCredentialsKeys), $credentials)) == count($requiredCredentialsKeys)) { return true; } } /** * Returns a new array with valid only custom fields * * @param array $customFields Array of custom fields * * @return array Array of valid only custom fields */ public function validateCustomFields($customFields) { $fields = array(); if (!is_array($customFields)) { return $fields; } $listCustomFields = $this->list->custom_fields; if (count($listCustomFields)) { foreach ($listCustomFields as $key => $customField) { if (!isset($customFields[$customField->name])) { continue; } $fields[$customField->name] = $customFields[$customField->name]; } } return $fields; } /** * Checks if the Authorization Code structure is correct * * @param string $authCode The Authorization Code * * @return boolean The result of the check */ public static function checkAuthCode($authCode) { $values = explode('|', $authCode); if (count($values) < 5) { return false; } return true; } }PK!"}g1convertforms/aweber/wrapper/aweber_collection.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); class AWeberCollection extends AWeberResponse implements ArrayAccess, Iterator, Countable { protected $pageSize = 100; protected $pageStart = 0; protected function _updatePageSize() { # grab the url, or prev and next url and pull ws.size from it $url = $this->url; if (array_key_exists('next_collection_link', $this->data)) { $url = $this->data['next_collection_link']; } elseif (array_key_exists('prev_collection_link', $this->data)) { $url = $this->data['prev_collection_link']; } # scan querystring for ws_size $url_parts = parse_url($url); # we have a query string if (array_key_exists('query', $url_parts)) { parse_str($url_parts['query'], $params); # we have a ws_size if (array_key_exists('ws_size', $params)) { # set pageSize $this->pageSize = $params['ws_size']; return; } } # we dont have one, just count the # of entries $this->pageSize = count($this->data['entries']); } public function __construct($response, $url, $adapter) { parent::__construct($response, $url, $adapter); $this->_updatePageSize(); } /** * @var array Holds list of keys that are not publicly accessible */ protected $_privateData = array( 'entries', 'start', 'next_collection_link', ); /** * getById * * Gets an entry object of this collection type with the given id * @param mixed $id ID of the entry you are requesting * @access public * @return AWeberEntry */ public function getById($id) { $data = $this->adapter->request('GET', "{$this->url}/{$id}"); $url = "{$this->url}/{$id}"; return new AWeberEntry($data, $url, $this->adapter); } /** getParentEntry * * Gets an entry's parent entry * Returns NULL if no parent entry */ public function getParentEntry() { $url_parts = explode('/', $this->url); $size = count($url_parts); # Remove collection id and slash from end of url $url = substr($this->url, 0, -strlen($url_parts[$size - 1]) - 1); try { $data = $this->adapter->request('GET', $url); return new AWeberEntry($data, $url, $this->adapter); } catch (Exception $e) { return NULL; } } /** * _type * * Interpret what type of resources are held in this collection by * analyzing the URL * * @access protected * @return void */ protected function _type() { $urlParts = explode('/', $this->url); $type = array_pop($urlParts); return $type; } /** * create * * Invoke the API method to CREATE a new entry resource. * * Note: Not all entry resources are eligible to be created, please * refer to the AWeber API Reference Documentation at * https://labs.aweber.com/docs/reference/1.0 for more * details on which entry resources may be created and what * attributes are required for creating resources. * * @access public * @param params mixed associtative array of key/value pairs. * @return AWeberEntry(Resource) The new resource created */ public function create($kv_pairs) { # Create Resource $params = array_merge(array('ws.op' => 'create'), $kv_pairs); $data = $this->adapter->request('POST', $this->url, $params, array('return' => 'headers')); # Return new Resource $url = $data['Location']; $resource_data = $this->adapter->request('GET', $url); return new AWeberEntry($resource_data, $url, $this->adapter); } /** * find * * Invoke the API 'find' operation on a collection to return a subset * of that collection. Not all collections support the 'find' operation. * refer to https://labs.aweber.com/docs/reference/1.0 for more information. * * @param mixed $search_data Associative array of key/value pairs used as search filters * * refer to https://labs.aweber.com/docs/reference/1.0 for a * complete list of valid search filters. * * filtering on attributes that require additional permissions to * display requires an app authorized with those additional permissions. * @access public * @return AWeberCollection */ public function find($search_data) { # invoke find operation $params = array_merge($search_data, array('ws.op' => 'find')); $data = $this->adapter->request('GET', $this->url, $params); # get total size $ts_params = array_merge($params, array('ws.show' => 'total_size')); $total_size = $this->adapter->request('GET', $this->url, $ts_params, array('return' => 'integer')); $data['total_size'] = $total_size; # return collection return $this->readResponse($data, $this->url); } /* * ArrayAccess Functions * * Allows this object to be accessed via bracket notation (ie $obj[$x]) * http://php.net/manual/en/class.arrayaccess.php */ public function offsetSet($offset, $value) {} public function offsetUnset($offset) {} public function offsetExists($offset) { if ($offset >= 0 && $offset < $this->total_size) { return true; } return false; } protected function _fetchCollectionData($offset) { # we dont have a next page, we're done if (!array_key_exists('next_collection_link', $this->data)) { return null; } # snag query string args from collection $parsed = parse_url($this->data['next_collection_link']); # parse the query string to get params $pairs = explode('&', $parsed['query']); foreach ($pairs as $pair) { list($key, $val) = explode('=', $pair); $params[$key] = $val; } # calculate new args $limit = $params['ws.size']; $pagination_offset = intval($offset / $limit) * $limit; $params['ws.start'] = $pagination_offset; # fetch data, exclude query string $url_parts = explode('?', $this->url); $data = $this->adapter->request('GET', $url_parts[0], $params); $this->pageStart = $params['ws.start']; $this->pageSize = $params['ws.size']; $collection_data = array('entries', 'next_collection_link', 'prev_collection_link', 'ws.start'); foreach ($collection_data as $item) { if (!array_key_exists($item, $this->data)) { continue; } if (!array_key_exists($item, $data)) { continue; } $this->data[$item] = $data[$item]; } } public function offsetGet($offset) { if (!$this->offsetExists($offset)) { return null; } $limit = $this->pageSize; $pagination_offset = intval($offset / $limit) * $limit; # load collection page if needed if ($pagination_offset !== $this->pageStart) { $this->_fetchCollectionData($offset); } $entry = $this->data['entries'][$offset - $pagination_offset]; # we have an entry, cast it to an AWeberEntry and return it $entry_url = $this->adapter->app->removeBaseUri($entry['self_link']); return new AWeberEntry($entry, $entry_url, $this->adapter); } /* * Iterator */ protected $_iterationKey = 0; public function current() { return $this->offsetGet($this->_iterationKey); } public function key() { return $this->_iterationKey; } public function next() { $this->_iterationKey++; } public function rewind() { $this->_iterationKey = 0; } public function valid() { return $this->offsetExists($this->key()); } /* * Countable interface methods * Allows PHP's count() and sizeOf() functions to act on this object * http://www.php.net/manual/en/class.countable.php */ public function count() { return $this->total_size; } } PK!onH~ ~ convertforms/aweber/aweber.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ // No direct access defined('_JEXEC') or die('Restricted access'); class plgConvertFormsAWeber extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ public function subscribe() { $lead = $this->lead; $credentials = array( 'consumerKey' => $lead->campaign->consumerKey, 'consumerSecret' => $lead->campaign->consumerSecret, 'accessToken' => $lead->campaign->accessToken, 'accessSecret' => $lead->campaign->accessSecret, ); $api = new NR_AWeber($credentials, $lead->campaign->uniquelistid); jimport('joomla.application.helper'); $ad_tracking = 'convertforms_' . JApplicationHelper::stringURLSafe($lead->campaign->name); $name = isset($lead->params['name']) ? $lead->params['name'] : ''; $tags = isset($lead->params['tags']) ? explode(',', $lead->params['tags']) : array(); $user = array( 'email' => $lead->email, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'ad_tracking' => $ad_tracking, 'name' => $name, 'tags' => $tags, 'updateexisting' => $lead->campaign->updateexisting ); if ($customFields = $api->validateCustomFields($lead->params)) { $user['custom_fields'] = $customFields; } $api->subscribe($user); } /** * Create the final credentials with the auth code * * @param string $context The context of the content passed to the plugin (added in 1.6) * @param object $article A JTableContent object * @param bool $isNew If the content has just been created * * @return boolean */ public function onContentBeforeSave($context, $article, $isNew) { if ($context != 'com_convertforms.campaign') { return; } if (!is_object($article) || !isset($article->params) || !isset($article->service) || ($article->service != 'aweber')) { return; } $this->loadWrapper(); $oldCampaign = false; if (isset($article->id)) { $oldCampaign = ConvertForms\Helper::getCampaign($article->id); } $params = json_decode($article->params); if (isset($params->authcode) && !NR_AWeber::checkAuthCode($params->authcode)) { JFactory::getApplication()->enqueueMessage(JText::_('PLG_CONVERTFORMS_AWEBER_WRONG_AUTH_CODE'), 'error'); return; } if (isset($params->authcode) && !NR_AWeber::checkCredentials($params, $oldCampaign)) { try { $credentials = AWeberAPI::getDataFromAweberID($params->authcode); $params->consumerKey = $credentials[0]; $params->consumerSecret = $credentials[1]; $params->accessToken = $credentials[2]; $params->accessSecret = $credentials[3]; $article->params = json_encode($params); JFactory::getApplication()->enqueueMessage(JText::_('PLG_CONVERTFORMS_AWEBER_CONNECTION_ESTABLISHED')); } catch (Exception $e) { JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); } } return true; } /** * Returns Service Wrapper File * * @return string */ protected function getWrapperFile() { return JPATH_PLUGINS . '/convertforms/aweber/wrapper/wrapper.php'; } }PK!]7,convertforms/aweber/form.xmlnu[
    PK!T}9}9-convertforms/aweber/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsAweberInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!n&convertforms/aweber/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsAWeberInstallerScript extends PlgConvertFormsAWeberInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_AWEBER'; public $alias = 'aweber'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!=hPconvertforms/elasticemail/language/ru-RU/ru-RU.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Преобразование форм - интеграция с ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Преобразование форм - интеграция со службами электронной почты ElasticEmail." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="ключ API" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Ваш ключ API ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="список ID" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="Идентификатор списка, на который пользователь должен подписаться" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Где я могу найти ключ API?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Двойной Optin" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Следует ли информировать пользователя по электронной почте после подписки, чтобы он мог активировать его?" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Обновить существующего пользователя" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Следует ли обновлять существующего пользователя при повторном входе в систему с новыми данными?" PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="Не удалось получить идентификатор общедоступной эластичной учетной записи электронной почты. Пожалуйста, проверьте свой ключ API и попробуйте снова сохранить кампанию." PK!Pconvertforms/elasticemail/language/ca-ES/ca-ES.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Integració Convert Forms - ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_KEY="Clau API" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="La teva clau API d'ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="ID de llista" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="L'ID del llistat al que s'hauria de subscriure l'usuari" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="On trobar la clau API?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Doble confirmació d'entrada" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Escull si s'hauria d'informar per correu electrònic l'usuari per activar la subscripció." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Actualitzar usuari existent" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Escull si s'hauria d'actualitzar un usuari existent si es torna a subscriure amb noves dades." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="No s'ha pogut recuperar l'ID de Compte Públic d'ElasticMail. Comprova la teva clau API i intenta tornar a guardar la campanya." PK!˷KTTPconvertforms/elasticemail/language/bg-BG/bg-BG.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Convert Forms – ElasticEmail интеграция" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Convert Forms – интеграция на ElasticEmail имейл маркетинг услуги." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="API ключ" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Вашият ElasticEmail API ключ" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="ID на списък" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="ID на списъка, за който потребителят трябва да се абонира" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Къде да намерите API ключ?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Double Optin активация" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Дали потребителят трябва да бъде уведомен чрез имейл след абонамента си с линк за да активира абонамента си." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Актуализиране съществуващия потребител" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Дали съществуващ потребител трябва да бъде актуализиран, когато той се абонира отново с нови данни." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="Elastic Email Public Account ID не може да бъде извлечен. Моля, проверете вашия API ключ и опитайте да запазите кампанията отново." PK!Pconvertforms/elasticemail/language/cs-CZ/cs-CZ.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Convert Forms - Integrace ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Convert Forms - Integrace emailových a marketingových služeb ElasticEmail." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="API klíč" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Váš ElasticEmail API klíč" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="ID seznamu" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="ID seznamu k jehož odběru se uživatel přihlašuje" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Kde získáte API klíč?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Dvojité potvrzení souhlasu" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Možnosti informovat uživatele e-mailem o přihlášení k odběru, aby jej mohl potvrdit a tím aktivovat." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Upravit stávajícího uživatele" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Možnost aktualizovat stávajícího uživatele, pokud se znovu přihlásí s novými údaji." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="ID veřejného účtu Elastic Email nelze načíst. Zkontrolujte váš klíč API a zkuste kampaň znovu uložit." PK!NPconvertforms/elasticemail/language/es-ES/es-ES.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="\"Formas de conversión\" - Integración con ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="\"Formularios de conversión\" - Integración con servicios de marketing de Email ElasticEmail." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="Clave de API" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Tu clave de API ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="Lista ID" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="La lista ID a la que el usuario debiera estar suscrito" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="¿Dónde encontrar la clave de API?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Optin doble" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Si el usuario debe ser notificado por email después de su suscripción para activarla." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Actualiza usuario existente" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Si un usuario existente debe ser actualizado si se subscribe de nuevo con nuevos datos." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="La ID de cuenta pública de ElasticEmail no se pudo recuperar. Por favor revise su clave de API e intente guardar la campaña nuevamente." PK!&ssPconvertforms/elasticemail/language/fi-FI/fi-FI.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Convert Forms - ElasticEmail liitäntä" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Convert Forms -Integrointi ElasticEmail Email Marketing palveluun." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="API Key" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Sinun ElasticEmail API Key" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="Luettelo ID" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="Luettelo ID, jonka käyttäjän tulee tilata" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Mistä löytyy API Key?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Tupla varmistus" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Pitääkö käyttäjälle ilmoittaa tilauksen jälkeen sähköpostitse, jotta hän voi aktivoida tilauksen." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Päivitä nykyinen käyttäjä" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Pitääkö olemassa olevan käyttäjän päivittää, jos hän tilaa uudelleen uutta tietoa." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="Elastic Emailin julkisen tilin tunnusta ei voitu noutaa. Tarkista API-avaimesi ja yritä tallentaa kampanja uudelleen." PK!egSSPconvertforms/elasticemail/language/en-GB/en-GB.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Convert Forms - ElasticEmail Integration" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Convert Forms - Integration with ElasticEmail Email Marketing Services." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="API Key" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Your ElasticEmail API Key" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="List ID" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="The List ID which the user should be subscribed to" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Where to find API Key?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Double Optin" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Whether the user should be informed by an email after his subscription so he can activate it." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Update existing user" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Whether an existing user should be updated if he subscribes again with new data." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="The Elastic Email Public Account ID could not be retrieved. Please check your API Key and try saving the campaign again."PK!bʇTconvertforms/elasticemail/language/en-GB/en-GB.plg_convertforms_elasticemail.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL="Convert Forms - ElasticEmail Integration" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Convert Forms - Integration with ElasticEmail Email Marketing Services."PK!onjddPconvertforms/elasticemail/language/uk-UA/uk-UA.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Перетворити форми - інтеграція ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Перетворити форми - інтеграція з маркетинговими послугами ElasticEmail." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="ключ API" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Ваш ключ API ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="список ID" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="Ідентифікатор списку, на який повинен підписатись користувач" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Де я можу знайти ключ API?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Подвійний оптин" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Чи слід повідомляти користувача електронною поштою після його підписки, щоб він міг його активувати?" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Оновити існуючого користувача" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Чи слід оновити існуючого користувача, коли він знову ввійде з новими даними?" PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="Не вдалося отримати ідентифікатор загальнодоступного еластичного електронної пошти. Перевірте ключ API і спробуйте зберегти кампанію ще раз." PK!Pconvertforms/elasticemail/language/fr-FR/fr-FR.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Convertisseur de formulaires - Intégration de ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing d'ElasticEmail." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="Clé de l'API" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Votre clé de l'API ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="ID de la liste" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="L'ID de la liste à laquelle l'utilisateur doit s'abonner" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Où trouver la clé de l'API ?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Vérification par mail" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Informe l'utilisateur après son abonnement par mail afin qu'il puisse l'activer." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Mettre à jour un utilisateur existant" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Met à jour un utilisateur existant avec de nouvelles données s'il est déjà inscrit." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="L'ID du compte public ElasticEmail n'a pas pu être récupéré. Veuillez vérifier votre clé API et réessayer d'enregistrer la campagne." PK!00_Pconvertforms/elasticemail/language/de-DE/de-DE.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Convert Forms - ElasticEmail Integration" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Convert Forms - Integration mit ElasticEmail E-Mail-Marketing-Diensten." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="API Schlüssel" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="Ihr ElasticEmail API Schlüssel" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="Listen ID" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="Die Listen ID, zu der der Benutzer hinzugefügt werden soll" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Wo findet man den API Schlüssel?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Doppeltes Opt-in" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Ob der Nutzer nach seinem Abonnement per E-Mail informiert werden soll, damit er es aktivieren kann." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Bestehenden Benutzer aktualisieren" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Ob ein bestehender Benutzer aktualisiert werden soll, wenn er sich erneut mit neuen Daten anmeldet." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="Die öffentliche Konto ID von ElasticEmail konnte nicht abgerufen werden. Bitte überprüfen Sie Ihren API-Schlüssel und versuchen Sie erneut, die Kampagne zu speichern." PK!Pconvertforms/elasticemail/language/it-IT/it-IT.plg_convertforms_elasticemail.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ELASTICEMAIL_ALIAS="ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL="Integrazione Convert Forms - ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_DESC="Integrazione Convert Forms con i servizi Email Marketing di ElasticEmail." PLG_CONVERTFORMS_ELASTICEMAIL_KEY="Chiave API" PLG_CONVERTFORMS_ELASTICEMAIL_KEY_DESC="La tua Chiave API di ElasticEmail" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID="ID elenco" PLG_CONVERTFORMS_ELASTICEMAIL_LIST_ID_DESC="L'ID elenco a cui l'utente dovrebbe essere iscritto" PLG_CONVERTFORMS_ELASTICEMAIL_FIND_API_KEY="Dove trovare la chiave API?" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN="Doppio opt-in" PLG_CONVERTFORMS_ELASTICEMAIL_DOUBLE_OPTIN_DESC="Se l'utente dovrebbe essere informato con un email dopo l'iscrizione così può attivarla." PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER="Aggiorna utente esistente" PLG_CONVERTFORMS_ELASTICEMAIL_UPDATE_EXISTING_USER_DESC="Se l'utente dovrebbe essere aggiornato con un email in caso si iscriva di nuovo con nuovi dati." PLG_CONVERTFORMS_ELASTICEMAIL_UNRETRIEVABLE_PUBLICACCOUNTID="Non si trova l'ID dell'account pubblico di ElasticEmail. Ti prego di controllare la tua chiave API e di provare a salvare di nuovo la campagna." PK!cb "convertforms/elasticemail/form.xmlnu[
    PK!x993convertforms/elasticemail/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsElasticemailInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!?*convertforms/elasticemail/elasticemail.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsElasticEmail extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ public function subscribe() { $api = new NR_ElasticEmail(array('api' => $this->lead->campaign->api)); $api->subscribe( $this->lead->email, $this->lead->campaign->list, $this->lead->campaign->publicAccountID, $this->lead->params, $this->lead->campaign->updateexisting, $this->lead->campaign->doubleoptin, $this->lead->campaign->publicAccountID ); if (!$api->success()) { throw new Exception($api->getLastError()); } } /** * Get the publicAccountID * * @param string $context The context of the content passed to the plugin (added in 1.6) * @param object $article A JTableContent object * @param bool $isNew If the content has just been created * * @return boolean */ public function onContentBeforeSave($context, $article, $isNew) { if ($context != 'com_convertforms.campaign') { return; } if (!is_object($article) || !isset($article->params) || !isset($article->service) || ($article->service != 'elasticemail')) { return; } $this->loadWrapper(); $params = json_decode($article->params); if (!isset($params->api)) { return; } try { $api = new NR_ElasticEmail(array('api' => $params->api)); $params->publicAccountID = $api->getPublicAccountID(); $article->params = json_encode($params); } catch (Exception $e) { JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); return; } return true; } }PK!,convertforms/elasticemail/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsElasticEmailInstallerScript extends PlgConvertFormsElasticEmailInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_ELASTICEMAIL'; public $alias = 'elasticemail'; public $extension_type = 'plugin'; public $plugin_folder = 'convertforms'; public $show_message = false; } PK!n88*convertforms/elasticemail/elasticemail.xmlnu[ PLG_CONVERTFORMS_ELASTICEMAIL PLG_CONVERTFORMS_ELASTICEMAIL_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c) 2011-2017 Tassos Marinos GNU General Public License version 3, or later July 2017 script.install.php language elasticemail.php form.xml script.install.helper.php PK!G!ddDconvertforms/drip/language/en-GB/en-GB.plg_convertforms_drip.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_DRIP="Convert Forms - Drip Integration" PLG_CONVERTFORMS_DRIP_DESC="Convert Forms - Integration with Drip Ecommerce CRM."PK!C@convertforms/drip/language/en-GB/en-GB.plg_convertforms_drip.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_DRIP_ALIAS="Drip" PLG_CONVERTFORMS_DRIP="Convert Forms - Drip Integration" PLG_CONVERTFORMS_DRIP_DESC="Convert Forms - Integration with Drip Ecommerce CRM." PLG_CONVERTFORMS_DRIP_KEY="API Key" PLG_CONVERTFORMS_DRIP_KEY_DESC="Your Drip API Key" PLG_CONVERTFORMS_DRIP_ACCOUNTID="Account ID" PLG_CONVERTFORMS_DRIP_ACCOUNTID_DESC="Your Drip Account ID" PLG_CONVERTFORMS_DRIP_CAMPAIGN_ID="Campaign ID" PLG_CONVERTFORMS_DRIP_CAMPAIGN_ID_DESC="The Campaign ID which the user should be subscribed to" PLG_CONVERTFORMS_DRIP_FIND_API_KEY="Where to find API Key?" PLG_CONVERTFORMS_DRIP_DOUBLE_OPTIN="Double Optin" PLG_CONVERTFORMS_DRIP_DOUBLE_OPTIN_DESC="Should the user have to click on a confirmation email before being considered as a subscriber?" PLG_CONVERTFORMS_DRIP_UPDATE_EXISTING_USER="Update existing user" PLG_CONVERTFORMS_DRIP_UPDATE_EXISTING_USER_DESC="Choose if you want to update your existing Drip user if that user resubmits your form" PLG_CONVERTFORMS_DRIP_SUBSCRIBER_ALREADY_EXISTS="You are already a subscriber."PK!לconvertforms/drip/form.xmlnu[
    PK!W{9{9+convertforms/drip/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsDripInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!:__convertforms/drip/drip.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsDrip extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ function subscribe() { $api = new NR_Drip(array( 'api' => $this->lead->campaign->api, 'account_id' => $this->lead->campaign->account_id )); $api->subscribe( $this->lead->email, $this->lead->campaign->list, isset($this->lead->params['name']) ? $this->lead->params['name'] : '', $this->lead->params, isset($this->lead->params['tags']) ? $this->lead->params['tags'] : '', $this->lead->campaign->updateexisting, $this->lead->campaign->doubleoptin ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK!![convertforms/drip/drip.xmlnu[ PLG_CONVERTFORMS_DRIP PLG_CONVERTFORMS_DRIP_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later August 2019 script.install.php language drip.php form.xml script.install.helper.php PK!/$convertforms/drip/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsDripInstallerScript extends PlgConvertFormsDripInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_DRIP'; public $alias = 'drip'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!y9=Tconvertforms/activecampaign/language/ru-RU/ru-RU.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="Активная кампания" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Преобразовать формы - интеграция в активную кампанию" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Преобразовать формы - интеграция в службы почтового маркетинга текущей кампании." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="URL API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="URL API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Где находится URL API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="Ключ API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Ключ API вашей активной кампании" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Где находится ключ API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="Список идентификаторов" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="Идентификатор списка, для которого пользователь должен быть зарегистрирован" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Где идентификатор списка?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Обновить существующего пользователя" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Выберите, должен ли пользователь текущей кампании обновляться при отправке вашей формы обратно" PK!??Tconvertforms/activecampaign/language/ca-ES/ca-ES.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Integració Convert Forms - ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="URL API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="URL API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="On trobar la URL API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="Clau API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="La teva clau API d'ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="On trobar la clau API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="ID de llista" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="L'ID del llistat al que s'hauria de subscriure l'usuari" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="On trobar l'ID de llista?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Actualitzar usuari existent" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Escull si vols actualitzar el teu usuari ActiveCampaign existent si aquest usuari torna a respondre al formulari" PK!HHTconvertforms/activecampaign/language/bg-BG/bg-BG.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms – ActiveCampaign интеграция" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms – Интеграция с ActiveCampaign имейл маркетингови услуги " PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Къде да намеря API URL?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="API ключ" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Вашият ActiveCampaign API ключ" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Къде да намеря API ключ?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="Списък ID" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="ID на списъка, за който потребителят трябва да се абонира" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Къде да намеря List ID?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Актуализирайте съществуващ потребител" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Изберете дали искате да актуализирате своя съществуващ потребител на ActiveCampaign, ако той отново изпрати формуляра ви" PK!l;;Tconvertforms/activecampaign/language/cs-CZ/cs-CZ.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms - Integrace ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms - Integrace emailových a marketingových služeb ActiveCampaign." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Kde najdu API URL?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="API klíč" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Váš ActiveCampaign API klíč" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Kde získáte API klíč?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="ID seznamu" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="ID seznamu k jehož odběru se uživatel přihlašuje" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Kde najdu ID seznamu?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Upravit stávajícího uživatele" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Zvolte pokud chcete aktualizovat stávajícího uživatele ActiveCampaign v případě, že uživatel opětovně odeslal formulář" PK!YeeTconvertforms/activecampaign/language/es-ES/es-ES.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN="\"Formas de conversión\" - Integración con ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="\"Formularios de conversión\" - Integrar con servicios de marketing de Email ActiveCampaign." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="URL de API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="URL de API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="¿Dónde encontrar la URL de API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="Clave de API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Tu clave de API Active Campaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="¿Dónde encontrar la clave de API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="Lista ID" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="La lista ID a la que el usuario debiera estar suscrito" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="¿Dónde encontrar la Lista ID?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Actualiza usuario existente" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Elige si quieres actualizar tu usuario de ActiveCampaign existente si ese usuario reenvía el formulario" PK!Ty..Tconvertforms/activecampaign/language/fi-FI/fi-FI.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms - ActiveCampaign liitäntä" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms - Integrointi ActiveCampaign Email Marketing Services -palveluun." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Mistä löytyy API URL?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="API Key" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Sinun ActiveCampaign API Key" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Mistä löytyy API Key?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="Luettelo ID" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="Luettelo ID, jonka käyttäjän tulee tilata" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Mistä löytyy luettelo ID?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Päivitä nykyinen käyttäjä" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Valitse, haluatko päivittää nykyisen ActiveCampaign-käyttäjän, jos kyseinen käyttäjä lähettää uudestaan lomakkeen" PK!{Tconvertforms/activecampaign/language/en-GB/en-GB.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms - ActiveCampaign Integration" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms - Integration with ActiveCampaign Email Marketing Services." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Where to find API URL?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="API Key" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Your ActiveCampaign API Key" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Where to find API Key?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="List ID" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="The List ID which the user should be subscribed to" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Where to find List ID?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Update existing user" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Choose if you want to update your existing ActiveCampaign user if that user resubmits your form"PK!FǰXconvertforms/activecampaign/language/en-GB/en-GB.plg_convertforms_activecampaign.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms - ActiveCampaign Integration" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms - Integration with ActiveCampaign Email Marketing Services."PK!qχ %%Tconvertforms/activecampaign/language/sv-SE/sv-SE.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms - ActiveCampaign integrering" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms - Integration med ActiveCampaign e-postmarknadsföringstjänster" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Var hittar jag API URL?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="API Nyckel" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Din ActiveCampaign API-nyckel" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Var hittar jag API nyckeln?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="List ID" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="List-ID som användaren ska prenumerera på" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Var hittar jag List ID?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Uppdatera befintlig användare" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Välj om du vill uppdatera din befintliga ActiveCampaign-användare om den användaren skickar in ditt formulär igen" PK!k[>>Tconvertforms/activecampaign/language/nl-NL/nl-NL.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="ActiveCampaign" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms - ActiveCampaign Integratie" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms - Integratie met ActiveCampaign Email Marketing Services." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Waar kan ik de API URL vinden?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="API Sleutel" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Jouw ActiveCampaign API Sleutel" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Waar kan ik de API sleutel vinden?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="Lijst ID" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="De lijst-ID waarop de gebruiker geabonneerd zou moeten zijn" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Waar kan ik de lijst-ID vinden?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Bijwerken bestaande gebruiker" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Kies om de bestaande ActiveCampaign gebruiker bij te werken als die gebruiker jouw formulier opnieuw indient." PK! Tconvertforms/activecampaign/language/uk-UA/uk-UA.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="Активна кампанія" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Перетворити форми - інтеграція в активну кампанію" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Перетворити форми - інтеграція в сервіси маркетингу електронної пошти поточної кампанії." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="URL-адреса API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="URL-адреса API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Де розташована URL-адреса API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="ключ API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Ключ API вашої активної кампанії" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Де знаходиться ключ API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="Список ідентифікаторів" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="Ідентифікатор списку, для якого повинен бути зареєстрований користувач" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Де ідентифікатор списку?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Оновити існуючого користувача" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Виберіть, чи повинен користувач поточної кампанії бути оновлений, коли він надсилає вашу форму назад" PK!?0rTconvertforms/activecampaign/language/fr-FR/fr-FR.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="Campagne active" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convertisseur de formulaire - Intégration de la campagne active" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing de la campagne active" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="URL de l'API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="URL de l'API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Où trouver l'URL de l'API ?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="Clé de l'API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Votre clé d'API de la campagne active" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Où trouver la clé de l'API ?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="ID de la liste" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="L'ID de la liste à laquelle l'utilisateur doit s'abonner" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Où trouver l'ID de la liste ?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Mettre à jour un utilisateur existant" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Choisissez si vous voulez mettre à jour l'utilisateur existant de la campagne active si cet utilisateur soumet à nouveau votre formulaire." PK!JL3XXTconvertforms/activecampaign/language/de-DE/de-DE.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="AktiveKampagne" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms - AktiveKampagne Integration" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms - Integration mit AktiveKampagne E-Mail-Marketingdiensten." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="API URL" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="Wo findet man die API URL?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="API Schlüssel" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="Ihr AktiveKampagne API Schlüssel" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Wo findet man die API URL?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="Listen ID" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="Die Listen ID, zu der der Benutzer hinzugefügt werden soll" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Wo findet man die Listen ID?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Akutalisiere existierenden Benutzer" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Wählen Sie, ob Sie Ihren bestehenden AktiveKampagne-Benutzer aktualisieren möchten, wenn dieser Benutzer Ihr Formular erneut abschickt" PK!E++Tconvertforms/activecampaign/language/it-IT/it-IT.plg_convertforms_activecampaign.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACTIVECAMPAIGN_ALIAS="CampagnaAttiva" PLG_CONVERTFORMS_ACTIVECAMPAIGN="Convert Forms - Integrazione CampagnaAttiva" PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC="Convert Forms - Integrazione con i servizi Email Marketing di CampagnaAttiva." PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL="URL API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_DESC="URL API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_API_URL_FIND="dove trovare l'URL API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY="Chiave API" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_DESC="La tua Chiave API di CampagnaAttiva" PLG_CONVERTFORMS_ACTIVECAMPAIGN_KEY_FIND="Dove trovare la chiave API?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST="Lista ID" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_DESC="La lista di ID a cui l'utente si è iscritto" PLG_CONVERTFORMS_ACTIVECAMPAIGN_LIST_FIND="Dove trovare la Lista ID?" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER="Aggiorna utenti già registrati" PLG_CONVERTFORMS_ACTIVECAMPAIGN_UPDATE_EXISTING_USER_DESC="Seleziona se vuoi aggiornare l'utente di CampagnaAttiva esistente e se lo stesso utente dovrà inviare il modulo" PK!e+CC.convertforms/activecampaign/activecampaign.xmlnu[ PLG_CONVERTFORMS_ACTIVECAMPAIGN PLG_CONVERTFORMS_ACTIVECAMPAIGN_DESC Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later November 2015 1.0 script.install.php language activecampaign.php form.xml script.install.helper.php PK!(vv$convertforms/activecampaign/form.xmlnu[
    PK!ɯq995convertforms/activecampaign/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsActivecampaignInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!Q5.convertforms/activecampaign/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsActiveCampaignInstallerScript extends PlgConvertFormsActiveCampaignInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_ACTIVECAMPAIGN'; public $alias = 'activecampaign'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!'1.convertforms/activecampaign/activecampaign.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsActiveCampaign extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ function subscribe() { // Call API $api = new NR_ActiveCampaign(array( 'api' => $this->lead->campaign->api, 'endpoint' => $this->lead->campaign->endpoint )); // Subscribe $api->subscribe( $this->lead->email, isset($this->lead->params['name']) ? $this->lead->params['name'] : '', $this->lead->campaign->list, isset($this->lead->params['tags']) ? $this->lead->params['tags'] : '', $this->lead->params, isset($this->lead->campaign->updateexisting) ? $this->lead->campaign->updateexisting : true ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK!(Lconvertforms/salesforce/language/ru-RU/ru-RU.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Преобразование форм - интеграция SalesForce с Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE_DESC="Преобразовать формы - интеграция с SalesForce CRM." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="организация ID" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Ваш идентификатор организации SalesForce" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Где я могу найти идентификатор организации?" PLG_CONVERTFORMS_SALESFORCE_ERROR="SalesForce не удалось сохранить преимущество из-за ошибки. Пожалуйста, проверьте конфигурацию своей кампании." PK!:33Lconvertforms/salesforce/language/ca-ES/ca-ES.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Integració Convert Forms - SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE_DESC="Integració entre Convert Forms i el CRM SalesForce." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="ID d'organització" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="ID de la teva organització SalesForce" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="On trobar l'ID d'organització?" PLG_CONVERTFORMS_SALESFORCE_ERROR="Un error ha evitat que SalesForce pogués guardar la pista. Comprova la configuració de la teva campanya." PK!gDLconvertforms/salesforce/language/bg-BG/bg-BG.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Convert Forms – SalesForce Web-to-Lead интегра;ия" PLG_CONVERTFORMS_SALESFORCE_DESC="Convert Forms – интеграция с SalesForce CRM." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="ID организация" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Вашият SalesForce Organization ID" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Къде да намерите ID идентификационния номер на организацията?" PLG_CONVERTFORMS_SALESFORCE_ERROR="Грешка е попречила на SalesForce да съхранява данни. Моля, проверете конфигурацията Campaign Configuration." PK!धLconvertforms/salesforce/language/cs-CZ/cs-CZ.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Convert Forms - Integrace SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE_DESC="Convert Forms - Integrace SalesForce CRM." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="ID organizace" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Vaše ID organizace u SalesForce" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Kde najdu ID organizace?" PLG_CONVERTFORMS_SALESFORCE_ERROR="Chyba znemožňuje ukládání informací z SalesForce. Zkontrolujte své nastavení kampaně." PK!YKKLconvertforms/salesforce/language/es-ES/es-ES.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="Web-to-Lead SalesForce" PLG_CONVERTFORMS_SALESFORCE="\"Formas de conversión\" - Integración con Web-to-Lead SalesForce" PLG_CONVERTFORMS_SALESFORCE_DESC="\"Formularios de conversión\" - Integración con SalesForce CRM." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="Organization ID" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Organization ID de tu SalesForce" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="¿Dónde encontrar la Organización ID?" PLG_CONVERTFORMS_SALESFORCE_ERROR="Un error ha prevenido a SalesForce grabar el Lead. Por favor revisa la configuración de tu campaña." PK!#0;  Lconvertforms/salesforce/language/fi-FI/fi-FI.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Convert Forms - SalesForce Web-to-Lead liitäntä" PLG_CONVERTFORMS_SALESFORCE_DESC="Convert Forms - Integrointi SalesForce CRM." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="Organisaation ID" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Sinun SalesForce organisaation ID" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Mistä löytyy organisaatio ID?" PLG_CONVERTFORMS_SALESFORCE_ERROR="Virhe on estänyt SalesForcea tallentamasta tietoa. Tarkista kampanjamäärityksesi." PK!91Lconvertforms/salesforce/language/en-GB/en-GB.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Convert Forms - SalesForce Web-to-Lead Integration" PLG_CONVERTFORMS_SALESFORCE_DESC="Convert Forms - Integration with SalesForce CRM." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="Organization ID" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Your SalesForce Organization ID" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Where to find Organization ID?" PLG_CONVERTFORMS_SALESFORCE_ERROR="An error has prevented SalesForce from storing the Lead. Please check your Campaign Configuration."PK!LvvPconvertforms/salesforce/language/en-GB/en-GB.plg_convertforms_salesforce.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE="Convert Forms - SalesForce Web-to-Lead Integration" PLG_CONVERTFORMS_SALESFORCE_DESC="Convert Forms - Integration with SalesForce CRM."PK!aDGLconvertforms/salesforce/language/uk-UA/uk-UA.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Перетворити форми - інтеграція веб-лідерів SalesForce" PLG_CONVERTFORMS_SALESFORCE_DESC="Перетворити форми - інтеграція з CRM SalesForce." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="ID Організації" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Ваш ідентифікатор організації SalesForce" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Де я можу знайти ідентифікатор організації?" PLG_CONVERTFORMS_SALESFORCE_ERROR="SalesForce не змогла зберегти потенційну позицію через помилку. Перевірте конфігурацію кампанії." PK!@>>Lconvertforms/salesforce/language/fr-FR/fr-FR.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Intégration de SalesForce Web-to-Lead à Convert Forms" PLG_CONVERTFORMS_SALESFORCE_DESC="Convertisseur de formulaires - Intégration avec le CRM SalesForce" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="ID d'organisation" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Votre ID d'organisation SalesForce" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Où trouver l'ID d'organisation ?" PLG_CONVERTFORMS_SALESFORCE_ERROR="Une erreur a empêché SalesForce d'enregistrer le Lead. Vérifiez la configuration de votre campagne" PK!-22Lconvertforms/salesforce/language/de-DE/de-DE.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="SalesForce Web-to-Lead" PLG_CONVERTFORMS_SALESFORCE="Convert Forms - SalesForce Web-to-Lead Integration" PLG_CONVERTFORMS_SALESFORCE_DESC="Convert Forms - Integration mit SalesForce CRM." PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="Organisation ID" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="Ihre SalesForce Organisation ID" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Wo findet man die Organisation ID?" PLG_CONVERTFORMS_SALESFORCE_ERROR="Ein Fehler hat SalesForce daran gehindert, den Lead zu speichern. Bitte überprüfen Sie Ihre Kampagnenkonfiguration." PK!HڿsHHLconvertforms/salesforce/language/it-IT/it-IT.plg_convertforms_salesforce.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SALESFORCE_ALIAS="Web-to-Lead di SalesForce" PLG_CONVERTFORMS_SALESFORCE="Integrazione Convert Forms - Web-to-Lead di SalesForce" PLG_CONVERTFORMS_SALESFORCE_DESC="Integrazione Convert Forms con il CRM di SalesForce" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID="ID organizzazione" PLG_CONVERTFORMS_SALESFORCE_ORGANIZATION_ID_DESC="il tuo ID organizzazione di SalesForce" PLG_CONVERTFORMS_SALESFORCE_FIND_ORGANIZATION_ID="Dove trovare l'ID organizzazione?" PLG_CONVERTFORMS_SALESFORCE_ERROR="Un errore ha impedito a SalesForce di memorizzare il lead. Ti prego di controllare la configurazione della tua campagna." PK!8  convertforms/salesforce/form.xmlnu[
    PK!833&convertforms/salesforce/salesforce.xmlnu[ PLG_CONVERTFORMS_SALESFORCE PLG_CONVERTFORMS_SALESFORCE_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2017 Tassos Marinos GNU General Public License version 3, or later November 2017 script.install.php language salesforce.php form.xml script.install.helper.php PK!r;991convertforms/salesforce/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsSalesforceInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!];ڸ*convertforms/salesforce/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsSalesForceInstallerScript extends PlgConvertFormsSalesForceInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_SALESFORCE'; public $alias = 'salesforce'; public $extension_type = 'plugin'; public $plugin_folder = 'convertforms'; public $show_message = false; } PK!&convertforms/salesforce/salesforce.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsSalesForce extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ public function subscribe() { $api = new NR_SalesForce($this->lead->campaign->organizationID); $api->subscribe( $this->lead->email, $this->lead->params ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK!Y.)88Vconvertforms/campaignmonitor/language/ru-RU/ru-RU.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="Монитор кампании" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Преобразование форм - интеграция Kamganen Monitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Преобразовать формы - Служба электронного маркетинга мониторинга интеграции кампании." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="Ключ API" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Ключ API вашего монитора кампании" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="Идентификатор списка" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="Идентификатор списка, в который должен войти пользователь" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Где находится ключ API?" PK!uLLVconvertforms/campaignmonitor/language/ca-ES/ca-ES.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Integració Convert Forms - Campaign Monitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic Campaign Monitor." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="Clau API" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="La clau API de la teva campanya" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="ID de llista" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="L'ID del llistat al que s'hauria de subscriure l'usuari" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="On trobar la clau API?" PK!$Vconvertforms/campaignmonitor/language/bg-BG/bg-BG.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Convert Forms – Campaign Monitor интеграция" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Convert Forms – Интеграция с Campaign Monitor имейл маркетинг услуги." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="API ключ" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Вашият Campaign Monitor API ключ" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="Списък ID" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="ID на списъка, за който потребителят трябва да се абонира" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Къде да намерите API ключ?" PK! $99Vconvertforms/campaignmonitor/language/cs-CZ/cs-CZ.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Convert Forms - Integrace Campaign Monitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Convert Forms - Integrace emailových a marketingových služeb Campaign Monitor." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="API klíč" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Váš Campaign Monitor API klíč" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="ID seznamu" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="ID seznamu k jehož odběru se uživatel přihlašuje" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Kde získáte API klíč?" PK![ZaaVconvertforms/campaignmonitor/language/es-ES/es-ES.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR="\"Formas de conversión\" - Integración con CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="\"Formularios de conversión\" - Integrar con servicios de marketing de Email CampaignMonitor." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="Clave de API" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Tu clave de API CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="Lista ID" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="La lista ID a la que el usuario debiera estar suscrito" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="¿Dónde encontrar la clave de API?" PK!qP  Vconvertforms/campaignmonitor/language/fi-FI/fi-FI.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Convert Forms - Campaign Monitor liitäntä" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Convert Forms - Integrointi Campaign Monitor Email Marketing palveluun." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="API Key" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Sinun Campaign Monitor API Key" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="Luettelo ID" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="Luettelo ID, jonka käyttäjän tulee tilata" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Mistä löytyy API Key?" PK!Ȓ1v$$Vconvertforms/campaignmonitor/language/en-GB/en-GB.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Convert Forms - Campaign Monitor Integration" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Convert Forms - Integration with Campaign Monitor Email Marketing Services." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="API Key" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Your Campaign Monitor API Key" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="List ID" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="The List ID which the user should be subscribed to" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Where to find API Key?"PK!ՐZconvertforms/campaignmonitor/language/en-GB/en-GB.plg_convertforms_campaignmonitor.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR="Convert Forms - Campaign Monitor Integration" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Convert Forms - Integration with Campaign Monitor Email Marketing Services."PK!AVconvertforms/campaignmonitor/language/uk-UA/uk-UA.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="Монітор кампанії" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Перетворити форми - інтеграція монітора Kamganen" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Перетворити форми - Моніторинг інтеграції кампанії" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="ключ API" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Ключ API монітора вашої кампанії" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="Ідентифікатор списку" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="Ідентифікатор списку, до якого повинен увійти користувач" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Де знаходиться ключ API?" PK!vDs˦Vconvertforms/campaignmonitor/language/fr-FR/fr-FR.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="Supervision de la campagne" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Convertisseur de formulaire - Intégration de la supervision de campagne" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing de la supervision de campagne." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="Clé de l'API" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Votre clé de l'API de supervision de campagne" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="ID de la liste" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="L'ID de la liste à laquelle l'utilisateur doit s'abonner" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Où trouver la clé de l'API ?" PK!МGGVconvertforms/campaignmonitor/language/de-DE/de-DE.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Convert Forms - Campaign Monitor Integration" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Convert Forms - Integration mit Campaign Monitor E-Mail-Marketingdiensten." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="API Schlüssel" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="Ihr Campaign Monitor API Schlüssel" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="Listen ID" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="Die Listen ID, zu der der Benutzer hinzugefügt werden soll" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Wo findet man den API Schlüssel?" PK!$??Vconvertforms/campaignmonitor/language/it-IT/it-IT.plg_convertforms_campaignmonitor.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_CAMPAIGNMONITOR_ALIAS="CampaignMonitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR="Integrazione Convert Forms - Campaign Monitor" PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC="Integrazione Convert Forms con i servizi di Email Marketing di Campaign Monitor." PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY="Chiave API" PLG_CONVERTFORMS_CAMPAIGNMONITOR_KEY_DESC="La tua chiave API di Campaign Monitor " PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID="ID elenco" PLG_CONVERTFORMS_CAMPAIGNMONITOR_LIST_ID_DESC="L'ID elenco a cui l'utente dovrebbe essere iscritto" PLG_CONVERTFORMS_CAMPAIGNMONITOR_FIND_API_KEY="Dove trovare la chiave API?" PK!\@xx0convertforms/campaignmonitor/campaignmonitor.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsCampaignMonitor extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ public function subscribe() { $api = new NR_CampaignMonitor(array('api' => $this->lead->campaign->api)); $api->subscribe( $this->lead->email, isset($this->lead->params['name']) ? $this->lead->params['name'] : '', $this->lead->campaign->list, $this->lead->params ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK!I=#FF0convertforms/campaignmonitor/campaignmonitor.xmlnu[ PLG_CONVERTFORMS_CAMPAIGNMONITOR PLG_CONVERTFORMS_CAMPAIGNMONITOR_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later January 2017 script.install.php language campaignmonitor.php form.xml script.install.helper.php PK! b%convertforms/campaignmonitor/form.xmlnu[
    PK!]Kg996convertforms/campaignmonitor/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsCampaignmonitorInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!HQ/convertforms/campaignmonitor/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsCampaignMonitorInstallerScript extends PlgConvertFormsCampaignMonitorInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_CAMPAIGNMONITOR'; public $alias = 'campaignmonitor'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!oPPHconvertforms/icontact/language/ru-RU/ru-RU.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Преобразование форм - интеграция с iContact" PLG_CONVERTFORMS_ICONTACT_DESC="Преобразование форм - интеграция с iContact Email Marketing Services." PLG_CONVERTFORMS_ICONTACT_APP_ID="Идентификатор приложения" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Ваш идентификатор приложения iContact" PLG_CONVERTFORMS_ICONTACT_USERNAME="Имя пользователя" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Ваше имя пользователя iContact" PLG_CONVERTFORMS_ICONTACT_APP_PASS="Пароль приложения" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="Ваш пароль приложения iContact. Это НЕ пароль вашего аккаунта iContact!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="Список ID" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="Идентификатор списка, на который пользователь должен подписаться" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Где я могу найти идентификатор приложения?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Где я могу найти пароль приложения?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Где я могу найти идентификатор списка?" PK!Q#[nHconvertforms/icontact/language/ca-ES/ca-ES.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Integració Convert Forms - iContact" PLG_CONVERTFORMS_ICONTACT_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic iContact" PLG_CONVERTFORMS_ICONTACT_APP_ID="ID d'app" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="L'ID de la teva App iContact" PLG_CONVERTFORMS_ICONTACT_USERNAME="Nom d'usuari" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="El teu nom d'usuari a iContact" PLG_CONVERTFORMS_ICONTACT_APP_PASS="Contrasenya d'App" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="La teva contrasenya de l'App iContact. Aquesta NO és la contrasenya del teu compte d'iContact!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="ID de llista" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="L'ID del llistat al que s'hauria de subscriure l'usuari" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="On trobar l'Id d'App?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="On trobar la contrasenya d'App?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="On trobar l'ID de llista?" PK!𤹙11Hconvertforms/icontact/language/bg-BG/bg-BG.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Convert Forms – iContact интеграция" PLG_CONVERTFORMS_ICONTACT_DESC="Convert Forms – интеграция с iContact имейл маркетингови услуги." PLG_CONVERTFORMS_ICONTACT_APP_ID="ID апликация" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Вашият ID на iContact апликация" PLG_CONVERTFORMS_ICONTACT_USERNAME="Име на потребител" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Вашето iContact име на потребител" PLG_CONVERTFORMS_ICONTACT_APP_PASS="Парола за приложение" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="Вашата iContact парола за приложение. Това НЕ е вашата парола за iContact Account!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="ID на списъка" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="ID на списъка, за който потребителят трябва да се абонира" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Къде да намерите ID на приложението?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Къде да намерите парола за приложение?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Къде да намерите ID идентификационния номер на списъка?" PK!eHconvertforms/icontact/language/cs-CZ/cs-CZ.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Convert Forms - Integrace iContact" PLG_CONVERTFORMS_ICONTACT_DESC="Convert Forms - Integrace emailových a marketingových služeb iContact." PLG_CONVERTFORMS_ICONTACT_APP_ID="ID aplikace" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Vaše iContact ID aplikace" PLG_CONVERTFORMS_ICONTACT_USERNAME="Uživatelské jméno" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Vaše iContact uživatelské jméno" PLG_CONVERTFORMS_ICONTACT_APP_PASS="Heslo aplikace" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="Vaše iContact heslo aplikace. Toto NENÍ heslok účtu iContact!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="ID seznamu" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="ID seznamu k jehož odběru se uživatel přihlašuje" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Kde najdu ID aplikace?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Kde najdu heslo aplikace?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Kde najdu ID seznamu?" PK!6;Hconvertforms/icontact/language/es-ES/es-ES.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="\"Formas de conversión\" - Integración con iContact" PLG_CONVERTFORMS_ICONTACT_DESC="\"Formularios de conversión\" - Integración con servicios de marketing de Email iContact." PLG_CONVERTFORMS_ICONTACT_APP_ID="App ID" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Tu ID de App iContact" PLG_CONVERTFORMS_ICONTACT_USERNAME="Nombre de usuario" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Tu nombre de usuario iContact" PLG_CONVERTFORMS_ICONTACT_APP_PASS="Contraseña de la App" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="Tu contraseña de app iContact. ¡Esta NO es to contraseña de tu cuenta iContact!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="Lista ID" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="La lista ID a la que el usuario debiera estar suscrito" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="¿Dónde encontrar la App ID?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="¿Dónde encontrar la contraseña de la App?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="¿Dónde encontrar la Lista ID?" PK!13Hconvertforms/icontact/language/fi-FI/fi-FI.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Convert Forms - iContact liitäntä" PLG_CONVERTFORMS_ICONTACT_DESC="Convert Forms - Integrointi iContact Email Marketing palveluun." PLG_CONVERTFORMS_ICONTACT_APP_ID="Sovellus ID" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Sinun iContact sovellus ID" PLG_CONVERTFORMS_ICONTACT_USERNAME="Käyttäjänimi" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Sinun iContact käyttäjänimi" PLG_CONVERTFORMS_ICONTACT_APP_PASS="Sovelluksen salasana" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="IContact-sovelluksen salasana. Tämä EI ole iContact-tilisi salasana!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="Luettelo ID" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="Luettelo ID, jonka käyttäjän tulee tilata" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Mistä löytyy sovellus ID?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Mistä löytyy sovellus salasana?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Mistä löytyy luettelo ID?" PK!|[hhHconvertforms/icontact/language/en-GB/en-GB.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Convert Forms - iContact Integration" PLG_CONVERTFORMS_ICONTACT_DESC="Convert Forms - Integration with iContact Email Marketing Services." PLG_CONVERTFORMS_ICONTACT_APP_ID="App ID" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Your iContact App ID" PLG_CONVERTFORMS_ICONTACT_USERNAME="Username" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Your iContact Username" PLG_CONVERTFORMS_ICONTACT_APP_PASS="App Password" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="Your iContact App Password. This is NOT your iContact Account Password!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="List ID" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="The List ID which the user should be subscribed to" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Where to find App ID?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Where to find App Password?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Where to find List ID?"PK!UN4wwLconvertforms/icontact/language/en-GB/en-GB.plg_convertforms_icontact.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT="Convert Forms - iContact Integration" PLG_CONVERTFORMS_ICONTACT_DESC="Convert Forms - Integration with iContact Email Marketing Services."PK!yNNHconvertforms/icontact/language/uk-UA/uk-UA.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Перетворити форми - інтеграція iContact" PLG_CONVERTFORMS_ICONTACT_DESC="Перетворити форми - інтеграція з iContact Email Marketing Services." PLG_CONVERTFORMS_ICONTACT_APP_ID="Ідентифікатор додатка" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Ваш ідентифікатор програми iContact" PLG_CONVERTFORMS_ICONTACT_USERNAME="Ім'я користувача" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Ваше ім'я користувача iContact" PLG_CONVERTFORMS_ICONTACT_APP_PASS="спеціальний пароль для програми" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="Ваш пароль програми iContact. Це НЕ пароль вашого облікового запису iContact!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="список ID" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="Ідентифікатор списку, на який повинен підписатись користувач" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Де я можу знайти ідентифікатор програми?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Де я можу знайти пароль програми?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Де я можу знайти ідентифікатор списку?" PK!G0Hconvertforms/icontact/language/fr-FR/fr-FR.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Convertisseur de formulaire - Intégration d'iContact" PLG_CONVERTFORMS_ICONTACT_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing d'iContact." PLG_CONVERTFORMS_ICONTACT_APP_ID="ID de l'appli" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Votre ID d'iContact App" PLG_CONVERTFORMS_ICONTACT_USERNAME="Nom d'utilisateur" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Votre nom d'utilisateur d'iContact" PLG_CONVERTFORMS_ICONTACT_APP_PASS="Mot de passe de l'appli" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="Le mot de passe d'iContact App. Ce N'est PAS le mot de passe de votre compte iContact !" PLG_CONVERTFORMS_ICONTACT_LIST_ID="ID de la liste" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="L'ID de la liste à laquelle l'utilisateur doit s'abonner" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Où trouver l'ID de l'appli ?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Où trouver le mot de passe de l'appli ?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Où trouver l'ID de la liste ?" PK!<Hconvertforms/icontact/language/de-DE/de-DE.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Convert Forms - iContact Integration" PLG_CONVERTFORMS_ICONTACT_DESC="Convert Forms - Integration mit iContact E-Mail-Marketing-Diensten." PLG_CONVERTFORMS_ICONTACT_APP_ID="App ID" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="Ihre iContact App ID" PLG_CONVERTFORMS_ICONTACT_USERNAME="Benutzername" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Ihr iContact Benutzername" PLG_CONVERTFORMS_ICONTACT_APP_PASS="App Passwort" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="Ihr iContact App Passwort. Dies ist NICHT das Passwort für Ihr iContact-Konto!" PLG_CONVERTFORMS_ICONTACT_LIST_ID="Listen ID" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="Die Listen ID, zu der der Benutzer hinzugefügt werden soll" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Wo findet man die App ID?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Wo findet man das App Passwort?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Wo findet man die Listen ID?" PK!h Hconvertforms/icontact/language/it-IT/it-IT.plg_convertforms_icontact.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ICONTACT_ALIAS="iContact" PLG_CONVERTFORMS_ICONTACT="Integrazione Convert Forms - iContact" PLG_CONVERTFORMS_ICONTACT_DESC="Integrazione Convert Forms con i servizi Email Marketing di iContact." PLG_CONVERTFORMS_ICONTACT_APP_ID="ID app" PLG_CONVERTFORMS_ICONTACT_APP_ID_DESC="La tua ID app di iContact" PLG_CONVERTFORMS_ICONTACT_USERNAME="Nome utente" PLG_CONVERTFORMS_ICONTACT_USERNAME_DESC="Il tuo nome utente su iContact" PLG_CONVERTFORMS_ICONTACT_APP_PASS="Password dell'app" PLG_CONVERTFORMS_ICONTACT_APP_PASS_DESC="La tua password dell'app di iContact. Questa NON è la password del tuo account iContact" PLG_CONVERTFORMS_ICONTACT_LIST_ID="ID elenco" PLG_CONVERTFORMS_ICONTACT_LIST_ID_DESC="L'ID elenco a cui l'utente dovrebbe essere iscritto" PLG_CONVERTFORMS_ICONTACT_FIND_APP_ID="Dove trovare l'ID dell'app?" PLG_CONVERTFORMS_ICONTACT_FIND_APP_PASS="Dove trovare la password dell'app?" PLG_CONVERTFORMS_ICONTACT_FIND_LIST_ID="Dove trovare l'ID elenco?" PK!2convertforms/icontact/form.xmlnu[
    PK!4@99/convertforms/icontact/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsIcontactInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!s!(("convertforms/icontact/icontact.xmlnu[ PLG_CONVERTFORMS_ICONTACT PLG_CONVERTFORMS_ICONTACT_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later March 2017 script.install.php language icontact.php form.xml script.install.helper.php PK!9X6 6 "convertforms/icontact/icontact.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsIContact extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ public function subscribe() { $api = new NR_iContact(array( 'appID' => $this->lead->campaign->appID, 'username' => $this->lead->campaign->username, 'appPassword' => $this->lead->campaign->appPassword, 'accountID' => $this->lead->campaign->accountID, 'clientFolderID' => $this->lead->campaign->clientFolderID )); $api->subscribe( $this->lead->email, $this->lead->params, $this->lead->campaign->list ); if (!$api->success()) { throw new Exception($api->getLastError()); } } /** * Retrieve the accountID and the clientFolderID * * @param string $context The context of the content passed to the plugin (added in 1.6) * @param object $article A JTableContent object * @param bool $isNew If the content has just been created * * @return boolean */ public function onContentBeforeSave($context, $article, $isNew) { if ($context != 'com_convertforms.campaign') { return; } if (!is_object($article) || !isset($article->params) || !isset($article->service) || ($article->service != 'icontact')) { return; } $params = json_decode($article->params); if (!isset($params->appID) || !isset($params->username) || !isset($params->appPassword)) { return; } $this->loadWrapper(); if (empty($params->accountID) || empty($params->clientFolderID)) { try { $api = new NR_iContact(array( 'appID' => $params->appID, 'username' => $params->username, 'appPassword' => $params->appPassword )); $params->accountID = $api->accountID; $params->clientFolderID = $api->clientFolderID; $article->params = json_encode($params); } catch (Exception $e) { JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); } } return true; } }PK!+(convertforms/icontact/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsiContactInstallerScript extends PlgConvertFormsiContactInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_ICONTACT'; public $alias = 'icontact'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!Jconvertforms/mailchimp/language/ru-RU/ru-RU.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Преобразование форм - интеграция с MailChimp" PLG_CONVERTFORMS_MAILCHIMP_DESC="Конвертировать формы - интеграция с MailChimp Email Marketing Services." PLG_CONVERTFORMS_MAILCHIMP_KEY="ключ API" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Ваш ключ API MailChimp" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="список ID" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="Идентификатор списка, на который пользователь должен подписаться" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Где я могу найти ключ API?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Двойной Optin" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Обновить существующего пользователя" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!^nJconvertforms/mailchimp/language/ca-ES/ca-ES.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Integració Convert Forms - MailChimp" PLG_CONVERTFORMS_MAILCHIMP_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic MailChimp" PLG_CONVERTFORMS_MAILCHIMP_KEY="Clau API" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="La teva clau API de MailChimp" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="ID de llista" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="L'ID del llistat al que s'hauria de subscriure l'usuari" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="On trobar la clau API?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Doble confirmació d'entrada" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Actualitzar usuari existent" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!m[Jconvertforms/mailchimp/language/bg-BG/bg-BG.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Convert Forms – MailChimp интеграция" PLG_CONVERTFORMS_MAILCHIMP_DESC="Convert Forms – интеграция с MailChimp имейл маркетинг услуги." PLG_CONVERTFORMS_MAILCHIMP_KEY="API ключ" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Вашият MailChimp API ключ" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="ID на списък" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="ID на списъка, за който потребителят трябва да се абонира" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Къде да намерите API ключ?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Double Optin регистрация" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Актуализирайте съществуващия потребител" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!6 lJconvertforms/mailchimp/language/cs-CZ/cs-CZ.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Convert Forms - integrace MailChimp" PLG_CONVERTFORMS_MAILCHIMP_DESC="Convert Forms - Integrace emailových a marketingových služeb MailChimp." PLG_CONVERTFORMS_MAILCHIMP_KEY="API klíč" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Váš MailChimp API klíč" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="ID seznamu" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="ID seznamu k jehož odběru se uživatel přihlašuje" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Kde získáte API klíč?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Dvojité potvrzení souhlasu" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Upravit stávajícího uživatele" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!2Jconvertforms/mailchimp/language/es-ES/es-ES.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="\"Formas de conversión\" - Integración con MailChimp" PLG_CONVERTFORMS_MAILCHIMP_DESC="\"Formularios de conversión\" - Integración con servicios de marketing de Email MailChimp." PLG_CONVERTFORMS_MAILCHIMP_KEY="Clave de API" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Tu clave de API MailChimp" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="Lista ID" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="La lista ID a la que el usuario debiera estar suscrito" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="¿Dónde encontrar la clave de API?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Optin doble" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Actualiza usuario existente" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!<^Jconvertforms/mailchimp/language/fi-FI/fi-FI.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Convert Forms - MailChimp liitäntä" PLG_CONVERTFORMS_MAILCHIMP_DESC="Convert Forms - Integrointi MailChimp Email Marketing palveluun." PLG_CONVERTFORMS_MAILCHIMP_KEY="API Key" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Sinun MailChimp API Key" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="Luettelo ID" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="Luettelo ID, jonka käyttäjän tulee tilata" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Mistä löytyy API Key?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Tupla varmistus" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Päivitä nykyinen käyttäjä" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!PjJconvertforms/mailchimp/language/en-GB/en-GB.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Convert Forms - MailChimp Integration" PLG_CONVERTFORMS_MAILCHIMP_DESC="Convert Forms - Integration with MailChimp Email Marketing Services." PLG_CONVERTFORMS_MAILCHIMP_KEY="API Key" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Your MailChimp API Key" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="List ID" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="The List ID which the user should be subscribed to" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Where to find API Key?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Double Optin" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Update existing user" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC=""PK!NpNconvertforms/mailchimp/language/en-GB/en-GB.plg_convertforms_mailchimp.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP="Convert Forms - MailChimp Integration" PLG_CONVERTFORMS_MAILCHIMP_DESC="Convert Forms - Integration with MailChimp Email Marketing Services."PK!kJconvertforms/mailchimp/language/uk-UA/uk-UA.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Перетворити форми - інтеграція MailChimp" PLG_CONVERTFORMS_MAILCHIMP_DESC="Перетворити форми - інтеграція з маркетинговими послугами MailChimp." PLG_CONVERTFORMS_MAILCHIMP_KEY="ключ API" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Ваш API API MailChimp" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="список ID" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="Ідентифікатор списку, на який повинен підписатись користувач" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Де я можу знайти ключ API?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Подвійний оптин" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Оновити існуючого користувача" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!EEJconvertforms/mailchimp/language/fr-FR/fr-FR.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Convertisseur de formulaires - Intégration de MailChimp" PLG_CONVERTFORMS_MAILCHIMP_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing de MailChimp." PLG_CONVERTFORMS_MAILCHIMP_KEY="Clé de l'API" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Votre clé d'API MailChimp" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="ID de la liste" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="L'ID de la liste à laquelle l'utilisateur doit s'abonner" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Où trouver la clé de l'API ?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Vérification par mail" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Mettre à jour un utilisateur existant" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!Jconvertforms/mailchimp/language/de-DE/de-DE.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Convert Forms - MailChimp Integration" PLG_CONVERTFORMS_MAILCHIMP_DESC="Convert Forms - Integration mit MailChimp E-Mail-Marketing-Diensten." PLG_CONVERTFORMS_MAILCHIMP_KEY="API Schlüssel" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="Ihr MailChimp API Schlüssel" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="Listen ID" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="Die Listen ID, zu der der Benutzer hinzugefügt werden soll" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Wo findet man den API Schlüssel?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Doppeltes Opt-in" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Bestehenden Benutzer aktualisieren" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!Jconvertforms/mailchimp/language/it-IT/it-IT.plg_convertforms_mailchimp.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_MAILCHIMP_ALIAS="MailChimp" PLG_CONVERTFORMS_MAILCHIMP="Integrazione Convert Forms - MailChimp" PLG_CONVERTFORMS_MAILCHIMP_DESC="Integrazione Convert Forms con i servizi Email Marketing di MailChimp." PLG_CONVERTFORMS_MAILCHIMP_KEY="Chiave API" PLG_CONVERTFORMS_MAILCHIMP_KEY_DESC="La tua Chiave API di MailChimp" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID="ID elenco" PLG_CONVERTFORMS_MAILCHIMP_LIST_ID_DESC="L'ID elenco a cui l'utente dovrebbe essere iscritto" PLG_CONVERTFORMS_MAILCHIMP_FIND_API_KEY="Dove trovare la chiave API?" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN="Doppio opt-in" PLG_CONVERTFORMS_MAILCHIMP_DOUBLE_OPTIN_DESC="" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER="Aggiorna utente esistente" PLG_CONVERTFORMS_MAILCHIMP_UPDATE_EXISTING_USER_DESC="" PK!5convertforms/mailchimp/form.xmlnu[
    PK!ܺr990convertforms/mailchimp/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsMailchimpInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!^d$convertforms/mailchimp/mailchimp.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsMailChimp extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ function subscribe() { $api = new NR_MailChimp(array('api' => $this->lead->campaign->api)); $api->subscribe( $this->lead->email, $this->lead->campaign->list, $this->lead->params, $this->lead->campaign->updateexisting, $this->lead->campaign->doubleoptin ); if (!$api->success()) { $error = $api->getLastError(); $error_parts = explode(' ', $error); if (function_exists('mb_strpos')) { // Make MalChimp errors translatable if (mb_strpos($error, 'is already a list member') !== false) { $error = JText::sprintf('COM_CONVERTFORMS_ERROR_USER_ALREADY_EXIST', $error_parts[0]); } if (mb_strpos($error, 'fake or invalid') !== false) { $error = JText::sprintf('COM_CONVERTFORMS_ERROR_INVALID_EMAIL_ADDRESS', $error_parts[0]); } } throw new Exception($error); } } }PK! [k>)convertforms/mailchimp/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsMailChimpInstallerScript extends PlgConvertFormsMailChimpInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_MAILCHIMP'; public $alias = 'mailchimp'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!}//$convertforms/mailchimp/mailchimp.xmlnu[ PLG_CONVERTFORMS_MAILCHIMP PLG_CONVERTFORMS_MAILCHIMP_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later November 2015 script.install.php language mailchimp.php form.xml script.install.helper.php PK!̜Fconvertforms/zohocrm/language/ru-RU/ru-RU.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Преобразование форм - интеграция с Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_DESC="Конвертировать формы - интеграция с Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Проверка подлинности фишку" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Ваш токен аутентификации Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Где я могу найти токен аутентификации?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Модуль" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="Модуль Zoho CRM, на который вы хотите отправлять свои сообщения" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Интересующиеся" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Учетные записи" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Контакты" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Обновить существующего пользователя" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Чтобы сохранить записи в режиме утверждения." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Запуск рабочего процесса" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Активируйте эту опцию, чтобы активировать правило рабочего процесса при вставке записей данных в учетную запись CRM." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Об утверждении режима" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Если эта опция активирована, записи не добавляются непосредственно в модули Zoho. Сначала они должны быть утверждены." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Датацентр" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Выберите, где размещена ваша Zoho CRM." PK!Fconvertforms/zohocrm/language/ca-ES/ca-ES.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Integració Convert Forms - Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_DESC="Integració entre Convert Forms i Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Token d'autentificació" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="El teu token d'autentificació Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="On trobar el token d'autentificació?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Mòdul" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="El mòdul Zoho CRM al que t'agradaria enviar les teves respostes" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Pistes" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Comptes" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Contactes" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Actualitzar usuari existent" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Activa-ho per mantenir els registres en mode aprovació" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Iniciar flux de treball" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Activa-ho per disparar la regla de flux de treball mentre s'insereixen registres al compte CRM." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Mode d'aprovació" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Quan aquesta opció està activada, els registres no s'afegeixen directament als mòduls Zoho. Primer cal activar-los." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Centre de dades" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Escull on s'hospeda el teu Zoho CRM" PK!6Fconvertforms/zohocrm/language/bg-BG/bg-BG.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Convert Forms – Zoho CRM интеграция" PLG_CONVERTFORMS_ZOHOCRM_DESC="Convert Forms – интеграция със Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Токен за удостоверяване" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Вашият Zoho CRM токен за удостоверяване" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Къде да намерите токен за удостоверяване?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Модул" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="Zoho CRM модул, на който искате да изпращате вашите заявки" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Интерисуващи" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Регистрации" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Контакти" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Актуализирайте съществуващия потребител" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Активирайте за запазване на записите в режим на одобрение." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Активирай работен поток" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Активирайте тази опция за задействане на правилото за работния процес, докато вмъквате записи в CRM акаунт." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Режим на одобрение" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Когато тази опция е активирана, записите не се добавят директно към модулите Zoho. Записите трябва първо да бъдат одобрени." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Център за данни" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Изберете къде се хоства вашият Zoho CRM." PK!A||Fconvertforms/zohocrm/language/cs-CZ/cs-CZ.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Convert Forms - Integrace Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_DESC="Convert Forms - Integrace Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Autorizační token" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Váš autorizační token Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Kde najdu autorizační token?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Modul" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="Modul Zoho CRM, do kterého chcete předávat záznamy" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Leads" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Účty" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Kontakty" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Upravit stávajícího uživatele" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Zapněte možnost ukládání záznamů v potvrzovacím režimu." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Spouštěcí workflow" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Zapněte spouštěč, které ovlivní postup zpracování při ukládání záznamů do CRM účtu." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Režim schvalování" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Pokud povolíte tuto možnost, záznamy se nebudou ukládat přímo do modulů Zoho. Budou vyžadovat neprve potrvzení." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Datacentrum" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Vyberte, kde je hostovaná vaše instalace Zoho CRM." PK!Fconvertforms/zohocrm/language/es-ES/es-ES.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="CRM de Zoho" PLG_CONVERTFORMS_ZOHOCRM="\"Formularios de conversión\" - Integración Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_DESC="\"Formularios de conversión\" - Integración con Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Señal de autentificación" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Tu señal de autentificación de CRM de Zoho" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="¿Dónde encontrar la señal de autentificación?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Módulo" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="El módulo Zoho CRM al que le gustaría enviar sus envíos" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Leads" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Cuentas" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Contactos" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Actualiza usuario existente" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Habilita para retener registros en modo de aprobación." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Activa flujos de trabajo." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Habilita para activar la regla de flujo de trabajo mientras se ingresan registros a la cuenta CRM." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Modo de aprobación" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Cuando esta opción esta habilitada, los registros no se agregan directamente a los módulos de Zoho. Necesitan estar aprobados primero." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Centro de datos" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Elija dónde está alojado su Zoho CRM." PK! [CbEEFconvertforms/zohocrm/language/fi-FI/fi-FI.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Convert Forms - Zoho CRM liitäntä" PLG_CONVERTFORMS_ZOHOCRM_DESC="Convert Forms - Integrointi Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Todennustunnus" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Sinun Zoho CRM todennustunnus" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Mistä löytyy todennustunnus?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Moduuli" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="Zoho CRM -moduuli, johon haluat lähettää lähetyksesi" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Leads" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Tilit" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Yhteystiedot" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Päivitä nykyinen käyttäjä" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Mahdollistaa tietueiden pitämisen hyväksyntätilassa." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Käynnistä työnkulku" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Mahdollistaa työnkulkusäännön käynnistämisen lisäämällä tietueita CRM-tiliin." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Hyväksyntätila" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Kun tämä vaihtoehto on käytössä, tietueita ei lisätä suoraan Zoho-moduuleihin. Ne on ensin hyväksyttävä." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Datakeskus" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Valitse missä Zoho CRM toimii." PK!*A66Fconvertforms/zohocrm/language/en-GB/en-GB.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Convert Forms - Zoho CRM Integration" PLG_CONVERTFORMS_ZOHOCRM_DESC="Convert Forms - Integration with Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Authentication Token" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Your Zoho CRM Authentication Token" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Where to find Authentication Token?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Module" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="The Zoho CRM module you'd like to send your submissions to" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Leads" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Accounts" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Contacts" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Update existing user" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Enable to keep the records in approval mode." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Trigger workflow" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Enable to trigger the workflow rule while inserting records into CRM account." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Approval Mode" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="When this option is enabled, records are not added directly to the Zoho modules. They need to be approved first." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Datacenter" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Choose where your Zoho CRM is hosted."PK!YҀ\\Jconvertforms/zohocrm/language/en-GB/en-GB.plg_convertforms_zohocrm.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM="Convert Forms - Zoho CRM Integration" PLG_CONVERTFORMS_ZOHOCRM_DESC="Convert Forms - Integration with Zoho CRM."PK!BV(Fconvertforms/zohocrm/language/uk-UA/uk-UA.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Перетворити форми - інтеграція Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_DESC="Перетворити форми - інтеграція з Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Перевірка автентичності фішку" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Ваш маркер аутентифікації Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Де я можу знайти маркер аутентифікації?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Модуль" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="Модуль Zoho CRM, на який потрібно відправляти свої повідомлення" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Потенційні клієнти" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Облікові записи" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Контакти" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Оновити існуючого користувача" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Для збереження записів у режимі затвердження." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Тригер робочого процесу" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Активуйте цю опцію, щоб запустити правило робочого процесу під час вставки записів у CRM-акаунт." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Про затвердження режиму" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Якщо цей параметр активований, записи не додаються безпосередньо до модулів Zoho. Вони повинні бути затверджені спочатку." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Датацентр" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Виберіть, де розміщується ваш Zoho CRM." PK!C,QFconvertforms/zohocrm/language/fr-FR/fr-FR.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="CRM Zoho" PLG_CONVERTFORMS_ZOHOCRM="Convertisseur de formulaire - Intégration du CRM Zoho" PLG_CONVERTFORMS_ZOHOCRM_DESC="Convertisseur de formulaires - Intégration avec le CRM Zoho." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Token d'authentification" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Votre token d'authentification du CRM Zoho" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Où trouver le token d'authentification ?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Module" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="Le module CRM Zoho auquel vous voulez envoyer les soumissions" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Leads" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Comptes" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Contacts" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Mettre à jour un utilisateur existant" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Activez pour conserver les enregistrements dans le mode de validation." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Déclencher le flux de travail" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Activez pour déclencher la règle de flux de travail lors de l'enregistrement dans le compte CRM." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Mode de validation" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Lorsque cette option est activée, les enregistrements ne sont pas ajoutés directement aux modules Zoho. Ils doivent d'abord être approuvés." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Datacenter" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Choisissez où votre CRM Zoho est hébergé" PK!MB}Fconvertforms/zohocrm/language/de-DE/de-DE.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Convert Forms - Zoho CRM Integration" PLG_CONVERTFORMS_ZOHOCRM_DESC="Convert Forms - Integration mit Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Authentifizierungs-Token" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Ihr Zoho CRM Authentifizierungs-Token" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Wo findet man den Authentifizierungs-Token?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Modul" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="Das Zoho CRM-Modul, an das Sie Ihre Eingaben senden möchten" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Leads" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Konten" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Kontakte" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Bestehenden Benutzer aktualisieren" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Aktivieren Sie diese Option, um die Datensätze im Genehmigungsmodus zu halten." PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Arbeitsablauf auslösen" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Aktivieren Sie diese Option, um die Arbeitsablauf-Regel beim Einfügen von Datensätzen in das CRM-Konto auszulösen." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Genehmigungsmodus" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Wenn diese Option aktiviert ist, werden die Datensätze nicht direkt zu den Zoho-Modulen hinzugefügt. Sie müssen zuerst genehmigt werden." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Rechenzentrum" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Wählen Sie, wo Ihr Zoho CRM gehostet wird." PK!ץFconvertforms/zohocrm/language/it-IT/it-IT.plg_convertforms_zohocrm.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2017 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ZOHOCRM_ALIAS="Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM="Integrazione Convert Forms - Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_DESC="Integrazione Convert Forms con Zoho CRM." PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN="Token di autenticazione" PLG_CONVERTFORMS_ZOHOCRM_AUTHENTICATIONTOKEN_DESC="Il tuo token di autenticazione di Zoho CRM" PLG_CONVERTFORMS_ZOHOCRM_FIND_AUTHENTICATIONTOKEN="Dove trovare il token di autenticazione?" PLG_CONVERTFORMS_ZOHOCRM_MODULE="Modulo" PLG_CONVERTFORMS_ZOHOCRM_MODULE_DESC="Il modulo di Zoho CRM a cui vorresti mandare i tuoi invii" PLG_CONVERTFORMS_ZOHOCRM_LEADS="Lead" PLG_CONVERTFORMS_ZOHOCRM_ACCOUNTS="Account" PLG_CONVERTFORMS_ZOHOCRM_CONTACTS="Contatti" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER="Aggiorna utente esistente" PLG_CONVERTFORMS_ZOHOCRM_UPDATE_EXISTING_USER_DESC="Abilita per tenere le registrazioni in modalità approvazione" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW="Flusso di lavoro dell'attivatore" PLG_CONVERTFORMS_ZOHOCRM_TRIGGER_WORKFLOW_DESC="Abilita per attivare la regola del flusso di lavoro mentre inserisci registrazioni nell'account del CRM." PLG_CONVERTFORMS_ZOHOCRM_APPROVAL="Modalità approvazione" PLG_CONVERTFORMS_ZOHOCRM_APPROVAL_DESC="Quando qeusta opzione è abilitata, le registrazioni non vengono inserite direttamente nei moduli di Zoho. Devono essere approvate in precedenza." PLG_CONVERTFORMS_ZOHOCRM_DATACENTER="Datacenter" PLG_CONVERTFORMS_ZOHOCRM_DATACENTER_DESC="Scegli dove è situato l'host di Zoho CRM." PK!>S S convertforms/zohocrm/form.xmlnu[
    PK!X~9~9.convertforms/zohocrm/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsZohocrmInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!5&& convertforms/zohocrm/zohocrm.xmlnu[ PLG_CONVERTFORMS_ZOHOCRM PLG_CONVERTFORMS_ZOHOCRM_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2017 Tassos Marinos GNU General Public License version 3, or later October 2017 script.install.php language zohocrm.php form.xml script.install.helper.php PK!yU'convertforms/zohocrm/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsZohoCRMInstallerScript extends PlgConvertFormsZohoCRMInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_ZOHOCRM'; public $alias = 'zohocrm'; public $extension_type = 'plugin'; public $plugin_folder = 'convertforms'; public $show_message = false; } PK!&NAZ convertforms/zohocrm/zohocrm.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); /** * Zoho CRM Convert Forms Plugin * * Note: Zoho CRM is using spaces in their custom field names (First Name, Last Name e.t.c). * Therefore we can't apply any filtering that strips away spaces on the Field Key * option during form saving in the backend as we can end up with a broken form. * * Commit regression: 13d8dc4 * https://bitbucket.org/tassosm/convertforms/commits/13d8dc475816a83c697ec81e5558d4680dfb4dcd */ class plgConvertFormsZohoCRM extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ public function subscribe() { $api = new NR_ZohoCRM(array( 'authenticationToken' => $this->lead->campaign->authenticationToken, 'datacenter' => isset($this->lead->campaign->dc) ? $this->lead->campaign->dc : null )); $api->subscribe( $this->lead->email, $this->lead->params, $this->lead->campaign->zohomodule, $this->lead->campaign->updateexisting, $this->lead->campaign->triggerworkflow, $this->lead->campaign->approval ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK![4E``Nconvertforms/getresponse/language/ru-RU/ru-RU.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Преобразование форм - интеграция GetResponse" PLG_CONVERTFORMS_GETRESPONSE_DESC="Преобразование форм - интеграция с сервисами почтового маркетинга GetResponse." PLG_CONVERTFORMS_GETRESPONSE_KEY="ключ API" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Ваш ключ API GetResponse" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Где я могу найти ключ API?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Токен кампании" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="Токен кампании, на который должен подписаться пользователь" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Обновить существующего пользователя" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Выберите, хотите ли вы обновить существующего пользователя GetResponse, когда этот пользователь снова отправит вашу форму." PK!Ԕ77Nconvertforms/getresponse/language/ca-ES/ca-ES.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Integració Convert Forms - Get response" PLG_CONVERTFORMS_GETRESPONSE_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic GetResponse." PLG_CONVERTFORMS_GETRESPONSE_KEY="Clau API" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="La teva clau API de GetResponse" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="On trobar la clau API?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Token de la campanya" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="El token de la campanya a la que s'hauria de subscriure l'usuari" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Actualitzar usuari existent" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Escull si vols actualitzar el teu usuari GetResponseexistent si aquest usuari torna a respondre al formulari" PK!e<<Nconvertforms/getresponse/language/bg-BG/bg-BG.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Convert Forms – GetResponse интегррация" PLG_CONVERTFORMS_GETRESPONSE_DESC="Convert Forms – интеграция с GetResponse имейл маркетингови услуги." PLG_CONVERTFORMS_GETRESPONSE_KEY="API ключ" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Вашия GetResponse API ключ" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Къде да намерите API ключ?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Токен на Кампания" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="Токен на кампанията, за който потребителят трябва да бъде абониран" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Актуализиране съществуващ потребител" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Изберете дали искате да актуализирате съществуващия си потребител на GetResponse, ако той отново изпрати формуляра си" PK!YUNconvertforms/getresponse/language/cs-CZ/cs-CZ.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Convert Forms - Integrace GetResponse" PLG_CONVERTFORMS_GETRESPONSE_DESC="Convert Forms - Integrace GetResponse." PLG_CONVERTFORMS_GETRESPONSE_KEY="API klíč" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Váš GetResponse API klíč" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Kde získáte API klíč?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Token kampaně" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="Token kampaně, ke které se uživatel přihlašuje" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Upravit stávajícího uživatele" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Vyberte si zda chcete aktualizovat existující uživatele GetResponse v případě, že uživatel opakovaně odešle formulář" PK!R=BBNconvertforms/getresponse/language/es-ES/es-ES.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="\"Formas de conversión\" - Integración con GetResponse" PLG_CONVERTFORMS_GETRESPONSE_DESC="\"Formularios de conversión\" - Integración con servicios de marketing de Email GetResponse." PLG_CONVERTFORMS_GETRESPONSE_KEY="Clave de API" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Tu clave de API GetResponse" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="¿Dónde encontrar la clave de API?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Seña de campaña" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="La seña de campaña a la que el usuario se debe suscribir" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Actualiza usuario existente" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Elige si quieres actualizar tu usuario de GetResponse existente si ese usuario reenvía el formulario" PK!p$:Nconvertforms/getresponse/language/fi-FI/fi-FI.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Convert Forms - GetResponse liitäntä" PLG_CONVERTFORMS_GETRESPONSE_DESC="Convert Forms - Integrointi GetResponse Email Marketing palveluun" PLG_CONVERTFORMS_GETRESPONSE_KEY="API Key" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Sinun GetResponse API Key" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Mistä löytyy API Key?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Kampanjan merkki" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="Kampanjan merkki, jonka käyttäjän tulee tilata" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Päivitä nykyinen käyttäjä" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Valitse, haluatko päivittää nykyisen GetResponse-käyttäjän, jos kyseinen käyttäjä lähettää uudestaan lomakkeen" PK!|.Nconvertforms/getresponse/language/en-GB/en-GB.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Convert Forms - GetResponse Integration" PLG_CONVERTFORMS_GETRESPONSE_DESC="Convert Forms - Integration with GetResponse Email Marketing Services." PLG_CONVERTFORMS_GETRESPONSE_KEY="API Key" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Your GetResponse API Key" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Where to find API Key?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Campaign Token" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="The Campaign Token which the user should be subscribed to" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Update existing user" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Choose if you want to update your existing GetResponse user if that user resubmits your form"PK!)Rconvertforms/getresponse/language/en-GB/en-GB.plg_convertforms_getresponse.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE="Convert Forms - GetResponse Integration" PLG_CONVERTFORMS_GETRESPONSE_DESC="Convert Forms - Integration with GetResponse Email Marketing Services." PK!@ Nconvertforms/getresponse/language/nl-NL/nl-NL.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="KrijgAntwoord" PLG_CONVERTFORMS_GETRESPONSE="Convert Forms - KrijgAntwoord Integratie" PLG_CONVERTFORMS_GETRESPONSE_DESC="Convert Forms - Integratie met KrijgAntwoord E-mail Marketing Diensten." PLG_CONVERTFORMS_GETRESPONSE_KEY="API Sleutel" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Uw KrijgAntwoord API Sleutel" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Waar vindt u de API Sleutel?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Campagne Token" ; PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="The Campaign Token which the user should be subscribed to" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Bijwerken bestaande gebruiker" ; PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Choose if you want to update your existing GetResponse user if that user resubmits your form" PK!LUI((Nconvertforms/getresponse/language/uk-UA/uk-UA.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Перетворити форми - інтеграція GetResponse" PLG_CONVERTFORMS_GETRESPONSE_DESC="Перетворити форми - інтеграція з маркетинговими послугами GetResponse." PLG_CONVERTFORMS_GETRESPONSE_KEY="ключ API" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Ваш ключ API GetResponse" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Де я можу знайти ключ API?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Идентифікатор листа" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="Маркер кампанії, на який повинен підписатися користувач" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Оновити існуючого користувача" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Виберіть, чи бажаєте ви оновити існуючого користувача GetResponse, коли той користувач знову подасть форму." PK!Rda=Nconvertforms/getresponse/language/fr-FR/fr-FR.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Convertisseur de formulaire - Intégration de GetResponse" PLG_CONVERTFORMS_GETRESPONSE_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing de GetResponse" PLG_CONVERTFORMS_GETRESPONSE_KEY="Clé de l'API" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Votre clé de l'API GetResponse" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Où trouver la clé de l'API ?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Token de la campagne" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="Le token de la campagne à laquelle l'utilisateur doit s'abonner" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Mettre à jour un utilisateur existant" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Choisissez si vous voulez mettre à jour l'utilisateur existant de GetResponse si cet utilisateur soumet à nouveau votre formulaire." PK!6IINconvertforms/getresponse/language/de-DE/de-DE.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Convert Forms - GetResponse Integration" PLG_CONVERTFORMS_GETRESPONSE_DESC="Convert Forms - Integration mit GetResponse E-Mail-Marketing-Diensten." PLG_CONVERTFORMS_GETRESPONSE_KEY="API Schlüssel" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="Ihr GetResponse API Schlüssel" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Wo findet man den API Schlüssel?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Kampagnen-Token" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="Der Kampagnen-Token, bei dem der Benutzer hinzugefügt werden soll" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Bestehenden Benutzer aktualisieren" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Wählen Sie, ob Sie Ihren bestehenden GetResponse-Benutzer aktualisieren möchten, wenn dieser Benutzer Ihr Formular erneut abschickt" PK!#ȴNNconvertforms/getresponse/language/it-IT/it-IT.plg_convertforms_getresponse.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_GETRESPONSE_ALIAS="GetResponse" PLG_CONVERTFORMS_GETRESPONSE="Integrazione Convert Forms - GetResponse" PLG_CONVERTFORMS_GETRESPONSE_DESC="Integrazione Convert Forms con i servizi Email Marketing di GetResponse." PLG_CONVERTFORMS_GETRESPONSE_KEY="Chiave API" PLG_CONVERTFORMS_GETRESPONSE_KEY_DESC="La tua chiave API di GetResponse" PLG_CONVERTFORMS_GETRESPONSE_FIND_API_KEY="Dove trovare la chiave API?" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID="Token campagna" PLG_CONVERTFORMS_GETRESPONSE_LIST_ID_DESC="Il token campagna a cui l'utente dovrebbe essere iscritto" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER="Aggiorna utente esistente" PLG_CONVERTFORMS_GETRESPONSE_UPDATE_EXISTING_USER_DESC="Seleziona se vuoi aggiornare il tuo utente esistente di GetResponse se quell'utente reinvia il modulo" PK!Cww!convertforms/getresponse/form.xmlnu[
    PK!6$ڂ992convertforms/getresponse/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsGetresponseInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!YSb(convertforms/getresponse/getresponse.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsGetResponse extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ function subscribe() { $api = new NR_GetResponse(array('api' => $this->lead->campaign->api)); $api->subscribe( $this->lead->email, $this->findKey('name', $this->lead->params), // I don't like this line $this->lead->campaign->list, $this->lead->params, isset($this->lead->campaign->updateexisting) ? $this->lead->campaign->updateexisting : true ); if (!$api->success()) { throw new Exception($api->getLastError()); } } }PK!g V77(convertforms/getresponse/getresponse.xmlnu[ PLG_CONVERTFORMS_GETRESPONSE PLG_CONVERTFORMS_GETRESPONSE_DESC Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later November 2015 1.0 script.install.php language getresponse.php form.xml script.install.helper.php PK!+convertforms/getresponse/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsGetResponseInstallerScript extends PlgConvertFormsGetResponseInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_GETRESPONSE'; public $alias = 'getresponse'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!SENconvertforms/errorlogger/language/ru-RU/ru-RU.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Конструктор форм - Журнал ошибок" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Сохраняет в журнал ошибки, возникающие при отправке заявок или создании форм" PK!@ߧNconvertforms/errorlogger/language/ca-ES/ca-ES.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Registre d'errors" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Registra els errors produïts durant la tramesa i el renderitzat de formularis a un arxiu de registre." PK!@k5Nconvertforms/errorlogger/language/bg-BG/bg-BG.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms – Дневник на грешките" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Дневник на грешките при регистрация, грешки при подаване на формуляра и при показване на формуляр в сайта." PK!{Nconvertforms/errorlogger/language/cs-CZ/cs-CZ.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Záznam chyb" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Logovat chyby, která nastanou v průběhu vyplňování nebo odesílání formuláře a ukládat je do souboru." PK!0ɦNconvertforms/errorlogger/language/es-ES/es-ES.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convertir formularios - Registro de errores" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Errores de registro de errores producidos durante el envío del formulario y la representación del formulario en un archivo de registro de errores." PK!͜Nconvertforms/errorlogger/language/fi-FI/fi-FI.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Virherekisteröinti" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Virhelogiin liitetyt virheet, jotka on tuotettu lomakkeen lähettämisen ja lomakkeen palautuksen yhteydessä." PK!xdNconvertforms/errorlogger/language/en-GB/en-GB.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Error Logger" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Log errors errors produced during form submission and form rendering to an error log file."PK!xdRconvertforms/errorlogger/language/en-GB/en-GB.plg_convertforms_errorlogger.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Error Logger" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Log errors errors produced during form submission and form rendering to an error log file."PK!KNconvertforms/errorlogger/language/nl-NL/nl-NL.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Fouten Logboek" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Fouten die zich voordoen bij de werking en bij het inzenden van een formulier worden in een logbestand bewaard. " PK!_VNconvertforms/errorlogger/language/uk-UA/uk-UA.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Перетворити форми - журнал помилок" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Помилки журналу, які виникають під час подання форми та коли форма надається в файл журналу помилок." PK!dNconvertforms/errorlogger/language/fr-FR/fr-FR.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Enregistrement des erreurs" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Enregistre dans un fichier log les erreurs qui se produisent lors de la soumission ou du remplissage d'un formulaire." PK!:|Nconvertforms/errorlogger/language/de-DE/de-DE.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Fehlerprotokoll" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Protokolliert Fehler, die während der Formularübermittlung und Formularwiedergabe erzeugt wurden, in einer Fehlerprotokolldatei. " PK!@dNconvertforms/errorlogger/language/it-IT/it-IT.plg_convertforms_errorlogger.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2019 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ERRORLOGGER="Convert Forms - Logger Errori" PLG_CONVERTFORMS_ERRORLOGGER_DESC="Trascrive su un file gli errori che avvengono quando si inviano moduli." PK!jV992convertforms/errorlogger/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsErrorloggerInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!A?9 9 (convertforms/errorlogger/errorlogger.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); use NRFramework\WebClient; use ConvertForms\Form; class plgConvertFormsErrorLogger extends JPlugin { /** * Joomla Application Object * * @var object */ protected $app; /** * Add plugin fields to the form * * @param JForm $form * @param object $data * * @return boolean */ public function onConvertFormsError($error, $category, $form_id, $data = null) { // Only on front-end if ($this->app->isClient('administrator')) { return; } if (isset($data['skip_error_logger'])) { return; } $user = JFactory::getUser(); // Get form's name $form_data = Form::load($form_id); $form_name = isset($form_data['name']) ? $form_data['name'] : 'Unknown Form'; $form_name .= ' (' . $form_id . ')'; $error_message = ' Identity --------------------------------------------------------------------------- Date Time: ' . JFactory::getDate() . ' Error Category: ' . $category . ' Error message: ' . $error . ' Form: ' . $form_name . ' Session ID: ' . JFactory::getSession()->getId() . ' IP Address: ' . $this->app->input->server->get('REMOTE_ADDR') . ' User Agent: ' . WebClient::getClient()->userAgent . ' Device: ' . WebClient::getDeviceType() . ' Logged In Username: ' . $user->username . ' Logged In Name: ' . $user->name . ' Data --------------------------------------------------------------------------- ' . print_r($data, true) . ' Request Headers --------------------------------------------------------------------------- ' . print_r($this->app->input->server->getArray(), true) . ' '; try { JLog::add($error_message, JLog::ERROR, 'convertforms_errors'); } catch (\Throwable $th) { } } }PK!+convertforms/errorlogger/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsErrorLoggerInstallerScript extends PlgConvertFormsErrorLoggerInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_ERRORLOGGER'; public $alias = 'errorlogger'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!w(convertforms/errorlogger/errorlogger.xmlnu[ PLG_CONVERTFORMS_ERRORLOGGER PLG_CONVERTFORMS_ERRORLOGGER_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c) 2011-2019 Tassos Marinos GNU General Public License version 3, or later January 2019 script.install.php language errorlogger.php script.install.helper.php PK!GffLconvertforms/acymailing/language/ru-RU/ru-RU.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Преобразовать формы - интеграция AcyMailing" PLG_CONVERTFORMS_ACYMAILING_DESC="Преобразование форм - интеграция с расширением Joomla! Acymailing." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="Список идентификаторов" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Выберите списки, для которых пользователь должен быть зарегистрирован в качестве подписки." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Двойная проверка" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="Нужно ли пользователю нажимать подтверждение по электронной почте перед регистрацией в качестве подписки?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Пользователь не может быть создан." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Пожалуйста, выберите список в настройках кампании." PK!aRLconvertforms/acymailing/language/ca-ES/ca-ES.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Integració Convert Forms - AcyMailing" PLG_CONVERTFORMS_ACYMAILING_DESC="Integració entre Convert Forms i l'extensió de Joomla! AcyMailing." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="ID de llista" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Escull les llistes a les que s'hauria de subscriure l'usuari" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Doble confirmació d'entrada" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="L'usuari hauria de clicar a un correu de confirmació abans de ser considerat subscriptor?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="No es pot crear l'usuari." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Escull una llista a la configuració de la campanya" PK!+?uLconvertforms/acymailing/language/bg-BG/bg-BG.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Convert Forms – AcyMailing Integration" PLG_CONVERTFORMS_ACYMAILING_DESC="Convert Forms – интеграция с Acymailing Joomla! разширение." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="Списък ID" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Изберете списъците, за които потребителят трябва да се абонира." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="В две стъпки" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="Трябва ли потребителят да щракне линка в имейла за потвърждение, преди да бъде считан за абонат?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Потребителят не може да бъде създаден." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Моля, изберете списък в настройките на кампанията" PK! KLconvertforms/acymailing/language/cs-CZ/cs-CZ.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Convert Forms - integrace AcyMailing" PLG_CONVERTFORMS_ACYMAILING_DESC="Convert Forms - Integrace s rozšířením Acymailing pro Joomla!" PLG_CONVERTFORMS_ACYMAILING_LIST_ID="Seznam ID" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Vyberte seznamy k jejiž odběru se uživatel přihlašuje." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Dvojité potvrzení souhlasu" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="Měl by uživatel potvrdit kliknutím na odkaz v potvrzovacím e-mailu souhlas s odběrem?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Nevytvářet uživatele." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Prosím zvolte seznam v nastavení kampaní" PK!)DLconvertforms/acymailing/language/es-ES/es-ES.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="Acymailing" PLG_CONVERTFORMS_ACYMAILING="\"Formas de conversión\" - Integración con AcyMailing" PLG_CONVERTFORMS_ACYMAILING_DESC="\"Formularios de conversión\" - Integrar con extensión de Joomla! Acymailing." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="Lista ID" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Selecciona las listas a la que el usuario debe estar suscrito." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Optin doble" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="¿Debe el usuario hacer click en un email de confirmación antes de ser considerado subscriptor?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="No se puede crear el usuario" PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Por favor, seleccione una lista en la configuración de campaña" PK! 5;Lconvertforms/acymailing/language/fi-FI/fi-FI.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Convert Forms - AcyMailing liitäntä" PLG_CONVERTFORMS_ACYMAILING_DESC="Convert Forms -integrointi Acymailing Joomla! laajennukseen." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="Luettelo ID" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Valitse luettelo ID, jonka käyttäjän tulee tilata" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Tupla varmistus" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="Pitääkö käyttäjän avata vahvistusviesti ennen kuin hänet hyväksytään tilaajana?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Käyttäjää ei voi luoda." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Valitse luettelosta kampanja-asetuksissa" PK!kHppLconvertforms/acymailing/language/en-GB/en-GB.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Convert Forms - AcyMailing Integration" PLG_CONVERTFORMS_ACYMAILING_DESC="Convert Forms - Integration with Acymailing Joomla! Extension." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="List ID" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Select the lists which the user should be subscribed to." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Double Optin" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="Should the user have to click on a confirmation email before being considered as a subscriber?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Can't create user." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Please select a list in the campaign settings" PLG_CONVERTFORMS_ACYMAILING_HELPER_CLASS_ERROR="AcyMailing %d helper class not found. Make sure AcyMailing is installed and you've selected the correct AcyMailing list in the campaign settings."PK!pqPconvertforms/acymailing/language/en-GB/en-GB.plg_convertforms_acymailing.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING="Convert Forms - AcyMailing Integration" PLG_CONVERTFORMS_ACYMAILING_DESC="Convert Forms - Integration with Acymailing Joomla! Extension."PK!$Lconvertforms/acymailing/language/sv-SE/sv-SE.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="Acymailing" PLG_CONVERTFORMS_ACYMAILING="Convert Forms - AcyMailing Integration" PLG_CONVERTFORMS_ACYMAILING_DESC="Convert Forms - Integration med Acymailing Joomla! Komponent." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="List ID" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Välj listan användaren skall bli prenumerant till." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Dubbel Optin" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="Skall användaren behöva klicka på ett konfirmation email innan han anses bli en prenumerant?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Kan inte skapa användare." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Vänligen välj en lista i kampanj inställningen" PK!H_00Lconvertforms/acymailing/language/uk-UA/uk-UA.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Перетворити форми - інтеграція AcyMailing" PLG_CONVERTFORMS_ACYMAILING_DESC="Перетворити форми - інтеграція з розширенням Acymailing Joomla!" PLG_CONVERTFORMS_ACYMAILING_LIST_ID="Список ідентифікаторів" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Виберіть списки, для яких користувач повинен бути зареєстрований як підписка." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Подвійна перевірка" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="Чи повинен користувач натиснути електронний лист для підтвердження, перш ніж зареєструватися як підписка?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Користувача не можна створити." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Виберіть список у налаштуваннях кампанії." PK!:ݥLconvertforms/acymailing/language/fr-FR/fr-FR.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Convertisseur de formulaires - Intégration de AcyMailing" PLG_CONVERTFORMS_ACYMAILING_DESC="Convertisseur de formulaires - Intégration avec l'extension Joomla! AcyMailing." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="ID de la liste" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Sélectionnez les listes auxquelles l'utilisateur doit s'abonner." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Vérification par mail" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="L'utilisateur doit-il cliquer sur un mail de confirmation avant d'être considéré comme abonné ?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Impossible de créer un utilisateur" PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Merci de choisir une liste dans les réglages de la campagne" PK!&,Lconvertforms/acymailing/language/de-DE/de-DE.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Convert Forms - AcyMailing Integration" PLG_CONVERTFORMS_ACYMAILING_DESC="Convert Forms - Integration mit der Acymailing Joomla! Erweiterung." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="Listen ID" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Wählen Sie die Listen aus, zu denen der Benutzer hinzugefügt werden soll." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Doppeltes Opt-in" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="Sollte der Nutzer auf einen Bestätigungs-Link in einer E-Mail klicken müssen, bevor er als Abonnent betrachtet wird?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Der Benutzer kann nicht erstellt werden." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Bitte eine Liste in den Kampagnen-Einstellungen auswählen" PK!D6Lconvertforms/acymailing/language/it-IT/it-IT.plg_convertforms_acymailing.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_ACYMAILING_ALIAS="AcyMailing" PLG_CONVERTFORMS_ACYMAILING="Integrazione Convert Forms - AcyMailing" PLG_CONVERTFORMS_ACYMAILING_DESC="Integrazione Convert Forms con l'estensione di Joomla! Acymailing." PLG_CONVERTFORMS_ACYMAILING_LIST_ID="ID elenco" PLG_CONVERTFORMS_ACYMAILING_LIST_ID_DESC="Seleziona le liste a cui l'utente dovrebbe essere iscritto." PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN="Doppio Opt-in" PLG_CONVERTFORMS_ACYMAILING_DOUBLEOPTIN_DESC="L'utente dovrebbe fare clic su una mail di conferma prima di essere considerato un iscritto?" PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER="Non posso creare l'utente." PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED="Seleziona una lista nelle impostazioni di campagna" PK!  convertforms/acymailing/form.xmlnu[
    PK! 991convertforms/acymailing/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsAcymailingInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!&convertforms/acymailing/acymailing.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsAcyMailing extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ public function subscribe() { // Make sure there's a list selected if (!isset($this->lead->campaign->list) || empty($this->lead->campaign->list)) { throw new Exception(JText::_('PLG_CONVERTFORMS_ACYMAILING_NO_LIST_SELECTED')); } $lists = $this->lead->campaign->list; $lists_v5 = []; $lists_v6 = []; // Discover lists for each version. v6 lists starts with 6: prefix. foreach ($lists as $list) { // Is a v5 list if (strpos($list, '6:') === false) { $lists_v5[] = $list; continue; } // Is a v6 list $lists_v6[] = str_replace('6:', '', $list); } require_once __DIR__ . '/helper.php'; // Add user to AcyMailing 5 lists if (!empty($lists_v5)) { ConvertFormsAcyMailingHelper::subscribe_v5($this->lead->email, $this->lead->params, $lists_v5, $this->lead->campaign->doubleoptin); } // Add user to AcyMailing 6 lists if (!empty($lists_v6)) { ConvertFormsAcyMailingHelper::subscribe_v6($this->lead->email, $this->lead->params, $lists_v6, $this->lead->campaign->doubleoptin); } } /** * Disable service wrapper * * @return boolean */ protected function loadWrapper() { return true; } }PK!T6#*convertforms/acymailing/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsAcyMailingInstallerScript extends PlgConvertFormsAcyMailingInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_ACYMAILING'; public $alias = 'acymailing'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!T4(kk"convertforms/acymailing/helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class ConvertFormsAcyMailingHelper { /** * Subscribe method for AcyMailing v6 * * @param array $lists * * @return void */ public static function subscribe_v6($email, $params, $lists, $doubleOptin = true) { if (!@include_once(JPATH_ADMINISTRATOR . '/components/com_acym/helpers/helper.php')) { throw new Exception(JText::sprintf('PLG_CONVERTFORMS_ACYMAILING_HELPER_CLASS_ERROR', 6)); } // Create user object $user = new stdClass(); $user->email = $email; $user->confirmed = $doubleOptin ? 0 : 1; $user_fields = array_change_key_case($params); $user->name = isset($user_fields['name']) ? $user_fields['name'] : ''; // Load User Class $acym = acym_get('class.user'); // Check if exists $existing_user = $acym->getOneByEmail($email); if ($existing_user) { $user->id = $existing_user->id; } else { // Save user to database only if it's a new user. if (!$user->id = $acym->save($user)) { throw new Exception(JText::_('PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER')); } } // Save Custom Fields $fieldClass = acym_get('class.field'); // getAllfields was removed in 7.7.4 and we must use getAll moving forward. $acy_fields_method = method_exists($fieldClass, 'getAllfields') ? 'getAllfields' : 'getAll'; $acy_fields = $fieldClass->$acy_fields_method(); unset($user_fields['name']); // Name is already used during user creation. $fields_to_store = []; foreach ($user_fields as $paramKey => $paramValue) { // Check if paramKey it's a custom field $field_found = array_filter($acy_fields, function($field) use($paramKey) { return (strtolower($field->name) == $paramKey || $field->id == $paramKey); }); if ($field_found) { // Get the 1st occurence $field = array_shift($field_found); // AcyMailing 6 needs field's ID to recognize a field. $fields_to_store[$field->id] = $paramValue; // $paramValue output: array(1) { [0]=> string(2) "gr" } // AcyMailing will get the key as the value instead of "gr" // We combine to remove the keys in order to keep the values if (is_array($paramValue)) { $fields_to_store[$field->id] = array_combine($fields_to_store[$field->id], $fields_to_store[$field->id]); } } } if ($fields_to_store) { $fieldClass->store($user->id, $fields_to_store); } // Subscribe user to AcyMailing lists return $acym->subscribe($user->id, $lists); } /** * Subscribe method for AcyMailing v5 * * @param array $lists * * @return void */ public static function subscribe_v5($email, $params, $lists, $doubleOptin = true) { if (!@include_once(JPATH_ADMINISTRATOR . '/components/com_acymailing/helpers/helper.php')) { throw new Exception(JText::sprintf('PLG_CONVERTFORMS_ACYMAILING_HELPER_CLASS_ERROR', 5)); } // Create user object $user = new stdClass(); $user->email = $email; $user->confirmed = $doubleOptin ? false : true; // Get Custrom Fields $db = JFactory::getDbo(); $customFields = $db->setQuery( $db->getQuery(true) ->select($db->quoteName('namekey')) ->from($db->quoteName('#__acymailing_fields')) )->loadColumn(); if (is_array($customFields) && count($customFields)) { foreach ($params as $key => $param) { if (in_array($key, $customFields)) { $user->$key = $param; } } } $acymailing = acymailing_get('class.subscriber'); $userid = $acymailing->subid($email); // AcyMailing sends account confirmation e-mails even if the user exists, so we need // to run save() method only if the user actually is new. if (is_null($userid)) { // Save user to database if (!$userid = $acymailing->save($user)) { throw new Exception(JText::_('PLG_CONVERTFORMS_ACYMAILING_CANT_CREATE_USER')); } } // Subscribe user to AcyMailing lists $lead = []; foreach($lists as $listId) { $lead[$listId] = ['status' => 1]; } return $acymailing->saveSubscription($userid, $lead); } }PK!#fWWW&convertforms/acymailing/acymailing.xmlnu[ PLG_CONVERTFORMS_ACYMAILING PLG_CONVERTFORMS_ACYMAILING_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c) 2020 Tassos Marinos GNU General Public License version 3, or later November 2015 script.install.php language acymailing.php form.xml script.install.helper.php helper.php PK!?4TTDconvertforms/emails/language/ru-RU/ru-RU.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Преобразовать формы - Уведомление по электронной почте" PLG_CONVERTFORMS_EMAILS_DESC="Отправить уведомление по электронной почте, когда пользователь отправляет форму" PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Поле обязательно для заполнения" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Неизвестный смарт-тег: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Неверный адрес электронной почты: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED=" Отправка электронной почты деактивирована!
    Чтобы иметь возможность отправлять электронную почту, в настройках электронной почты в глобальной конфигурации Joomla! Должен быть установлен параметр Отправить электронную почту. быть активированным. " PK!'ԏDconvertforms/emails/language/ca-ES/ca-ES.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms - Notificacions per correu electrònic" PLG_CONVERTFORMS_EMAILS_DESC="Envia notificacions per correu electrònic quan els usuaris responen a un formulari." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Camp requerit" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Etiqueta intel·ligent desconeguda: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Adreça de correu electrònic invàlida: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="L'enviament de correus electrònics està desactivat!
    Per poder enviar correus electrònics, la opció Enviar Correu electrònic dins la configuració Global de Joomla! ha d'estar activada." PK!}kkDconvertforms/emails/language/pt-BR/pt-BR.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Plugin Formulários de Conversão - Notificações de E-mail" PLG_CONVERTFORMS_EMAILS_DESC="Envia notificações por e-mail quando os usuários enviarem um formulário." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Campo obrigatório" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Smart Tag desconhecida: 1%s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Endereço de email inválido: 1%s" ; PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="Mail sending is turned off!
    In order to be able to send emails, the Send Mail option found under the Mail Settings in the Joomla! Global Configuration must be enabled." PK!\AADconvertforms/emails/language/bg-BG/bg-BG.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms – имейл нотификации" PLG_CONVERTFORMS_EMAILS_DESC="Изпращайте известия по имейл, когато потребителите изпратят формуляр." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Задължително поле" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Неизвестен смарт таг: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Невалиден имейл адрес: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="Изпращането на поща е изключено!
    За да можете да изпращате имейли, опцията за изпращане на поща в глобалните настройките за поща на Joomla!, трябва да бъде активирана." PK!IffDconvertforms/emails/language/cs-CZ/cs-CZ.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms - E-mailová upozornění" PLG_CONVERTFORMS_EMAILS_DESC="Poslat upozornění e-mailem, pokud uživatel odešle formulář" PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Pole je povinné" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Neznámý chytrý štítek: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Nemplatný e-mailová adresa: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="Odesílání e-mailů je vypnuté!
    Pokud chcete odesílání e-mailů zprovoznit, musíte aktivovat volbu Odesílat e-maily, kterou najdete v sekci Nastavení mailu v Globálním nastavení Joomla!" PK!,rrDconvertforms/emails/language/es-ES/es-ES.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="\"Formas de conversión\" - Notificaciones por email" PLG_CONVERTFORMS_EMAILS_DESC="Envíe notificación por email cuando los usuarios envíen un formulario." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Campo requerido" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Smart Tag desconocido «%s»" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Email incorrecto «%s»" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="¡El envío de correo está desactivado! Para poder enviar correos electrónicos, la opción Enviar correo se encuentra en la Configuración de correo en Joomla! La configuración global debe estar habilitada." PK!+mIIDconvertforms/emails/language/fi-FI/fi-FI.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms - Sähköposti-ilmoitukset" PLG_CONVERTFORMS_EMAILS_DESC="Lähetä sähköposti-ilmoitus, kun käyttäjä lähettää lomakkeen." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Kenttä vaaditaan" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Tuntematon Smart Tag: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Virheellinen sähköpostiosoite: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="Sähköpostien lähettäminen on kytketty pois päältä!
    Jotta voisit lähettää sähköpostia, Joomlan globaalit sähköpostiasetukset on otettava käyttöön." PK!<G%%Dconvertforms/emails/language/en-GB/en-GB.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms - Email Notifications" PLG_CONVERTFORMS_EMAILS_DESC="Send email notifications when users submit a form." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Field is required" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Unknown Smart Tag: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Invalid email address: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="Mail sending is turned off!
    In order to be able to send emails, the Send Mail option found under the Mail Settings in the Joomla! Global Configuration must be enabled."PK!u7iiHconvertforms/emails/language/en-GB/en-GB.plg_convertforms_emails.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms - Email Notifications" PLG_CONVERTFORMS_EMAILS_DESC="Send email notifications when users submit a form."PK!` 44Dconvertforms/emails/language/nl-NL/nl-NL.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms - E-mail Notificaties" PLG_CONVERTFORMS_EMAILS_DESC="Stuur e-mail notificaties als gebruikers een formulier inzenden." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Dit veld is vereist" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Onbekende Smart Tag: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Ongeldig e-mailadres: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="Sturen van mail is uitgeschakeld!
    Om e-mails te kunnen sturen moet de Send Mail optie in de Mail Instellingen in de Joomla! Global Configuration ingeschakeld zijn." PK!Dconvertforms/emails/language/uk-UA/uk-UA.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Перетворити форми - повідомлення електронною поштою" PLG_CONVERTFORMS_EMAILS_DESC="Надіслати сповіщення електронною поштою, коли користувач подає форму" PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Поле обов'язкове" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Невідомий смарт-тег: %s " PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Недійсна адреса електронної пошти: %s " PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED=" Електронна пошта вимкнена!
    Щоб мати змогу надсилати електронні листи, у глобальній конфігурації Joomla! Потрібно встановити параметр"_QQ_" Надіслати електронну пошту "_QQ_". бути активованим. " PK!Z4@@Dconvertforms/emails/language/fr-FR/fr-FR.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convertisseur de formulaires - Notifications par mail" PLG_CONVERTFORMS_EMAILS_DESC="Envoyer une notification par mail aux utilisateurs complétant le formulaire." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Ce champ est requis" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Smart tag inconnu : %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Adresse de messagerie incorrecte : %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="L'envoi de mails est désactivé !
    Pour pouvoir les envoyer, vous devez activer l'option dans la Configuration générale de Joomla!" PK!UUDconvertforms/emails/language/de-DE/de-DE.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms - Email Benachrichtigung" PLG_CONVERTFORMS_EMAILS_DESC="Email Benachrichtigung senden, wenn Benutzer ein Formular abschickt" PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Feld ist erforderlich" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Unbekanntes Smart Tag: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Ungültige E-Mail-Adresse: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED=" E-Mail-Versand ist deaktiviert!
    Um E-Mails versenden zu können, muss die Option E-Mail senden in den E-Mail-Einstellungen in der globalen Joomla! -Konfiguration aktiviert sein." PK!z[JJDconvertforms/emails/language/it-IT/it-IT.plg_convertforms_emails.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_EMAILS="Convert Forms - Notifiche Email" PLG_CONVERTFORMS_EMAILS_DESC="Invia una notifica via email quando un utente invia un modulo." PLG_CONVERTFORMS_EMAILS_ERROR_BLANK="Campo richiesto" PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG="Smart Tag sconosciuta: %s" PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS="Indirizzo eMail errato: %s" PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED="L'invio di email è disabilitato!Per abilitare la funzione di invio email, l'ozpione Invia Email deve essere attivata nel pannello di controllo di Joomla, alla voce Configurazione Globale." PK!9}9}9-convertforms/emails/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsEmailsInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!   convertforms/emails/emails.xmlnu[ PLG_CONVERTFORMS_EMAILS PLG_CONVERTFORMS_EMAILS_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later January 2017 script.install.php language form emails.php script.install.helper.php PK!Wd&convertforms/emails/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsEmailsInstallerScript extends PlgConvertFormsEmailsInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_EMAILS'; public $alias = 'emails'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!a]o!o!convertforms/emails/emails.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsEmails extends JPlugin { /** * Form Object * * @var object */ private $form; /** * Auto loads the plugin language file * * @var boolean */ protected $autoloadLanguage = true; /** * Add plugin fields to the form * * @param JForm $form * @param object $data * * @return boolean */ public function onConvertFormsFormPrepareForm($form, $data) { $form->loadFile(__DIR__ . '/form/form.xml', false); return true; } /** * Event triggered during fieldset rendering in the form editing page in the backend. * * @param string $fieldset_name The name of the fieldset is going to be rendered * @param string $fieldset The HTML output of the fieldset * * @return void */ public function onConvertFormsBackendFormPrepareFieldset($fieldset_name, &$fieldset) { if ($this->_name != $fieldset_name) { return; } // Proceed only if Mail Sending is disabled. if ((bool) \JFactory::getConfig()->get('mailonline')) { return; } $warning = '
    ' . \JText::_('PLG_CONVERTFORMS_EMAILS_ERROR_MAIL_SENDING_DISABLED') . '
    '; $fieldset = $warning . $fieldset; } /** * Create the final credentials with the auth code * * @param string $context The context of the content passed to the plugin (added in 1.6) * @param object $article A JTableContent object * @param bool $isNew If the content has just been created * * @return boolean */ public function onContentBeforeSave($context, $form, $isNew) { if ($context != 'com_convertforms.form') { return; } if (!is_object($form) || !isset($form->params)) { return; } $params = json_decode($form->params); if (!isset($params->emails)) { return true; } // Proceed only if Send Notifications option is enabled if ($params->sendnotifications != '1') { return true; } $this->form = clone $form; $this->form->params = $params; foreach ($params->emails as $key => $email) { $keyToID = ((int) str_replace('emails', '', $key)) + 1; $error = JText::_('COM_CONVERTFORMS_EMAILS') . ' #' . $keyToID . ' - '; $options = [ 'recipient' => ['COM_CONVERTFORMS_EMAILS_RECIPIENT', true, true], 'subject' => ['COM_CONVERTFORMS_EMAILS_SUBJECT', false, true], 'from_name' => ['COM_CONVERTFORMS_EMAILS_FROM', false, true], 'from_email' => ['COM_CONVERTFORMS_EMAILS_FROM_EMAIL', true, true], 'reply_to' => ['COM_CONVERTFORMS_EMAILS_REPLY_TO', true, false], 'reply_to_name' => ['COM_CONVERTFORMS_EMAILS_REPLY_TO_NAME', false, false], 'body' => ['COM_CONVERTFORMS_EMAILS_BODY', false, true], 'attachments' => ['COM_CONVERTFORMS_EMAILS_ATTACHMENT', false, false] ]; foreach ($options as $key => $option) { $acceptsCommaSeparatedValues = $option[1]; $optionValues = $acceptsCommaSeparatedValues ? explode(',', $email->$key) : (array) $email->$key; foreach ($optionValues as $optionValue) { $result = $this->validateOption($optionValue, $option[1], $option[2]); if (is_string($result)) { $form->setError($error . JText::_($option[0]) . ' - ' . $result); return false; break; } } } } return true; } /** * Validates string as an Email Notification option. * * @param string $string The option name as found in the xml file * @param bool $validateAsEmail If enabled, the option should be validated as an Email Address * @param bool $required If enabled, string should not be left blank * * @return void */ private function validateOption($string, $validateAsEmail = true, $required = true) { // Check if it's empty if ($required && (empty($string) || is_null($string))) { return JText::sprintf('PLG_CONVERTFORMS_EMAILS_ERROR_BLANK', $string); } $string = trim($string); // Check if has a valid field-based Smart Tag in the form: {field.field-name} $pattern = "#\{field.([^{}]*)\}#s"; preg_match_all($pattern, $string, $result); if (!empty($result[1]) && count($result[1]) > 0) { foreach ($result[1] as $key => $match) { // Keep only the actual field name list($field_name, $options) = explode('--', $result[1][$key]) + ['', '']; if (!$this->formHasField(trim($field_name))) { return JText::sprintf('PLG_CONVERTFORMS_EMAILS_ERROR_UNKNOWN_SMART_TAG', $result[0][$key]); break; } } return true; } // Check if has a valid Email Address info@mail.com if ($validateAsEmail && !empty($string)) { // Check common email-based Smart Tags if (in_array($string, ['{user.email}', '{site.email}'])) { return true; } if (!ConvertForms\Validate::email($string)) { return JText::sprintf('PLG_CONVERTFORMS_EMAILS_ERROR_INVALID_EMAIL_ADDRESS', $string); } } return true; } /** * Check if given name exists as a form field * * @param string $name * * @return bool */ private function formHasField($name) { $name = strtolower($name); foreach ($this->form->params->fields as $field) { if (!isset($field->name)) { continue; } if (strtolower($field->name) == $name) { return true; } // In case a sub Smart Tag is being used. Eg: {field.dropdown.label} to get dropdown's selected text. if (stripos($name, $field->name . '.') !== false) { return true; } } return false; } /** * Content is passed by reference, but after the save, so no changes will be saved. * * @param string $submission The submission information object * * @return void */ public function onConvertFormsSubmissionAfterSave($submission) { if (!isset($submission->form->sendnotifications) || !$submission->form->sendnotifications) { return; } if (!isset($submission->form->emails) || !is_array($submission->form->emails)) { return; } // Send email queue foreach ($submission->form->emails as $key => $email) { // Trigger Content Plugins $email['body'] = \JHtml::_('content.prepare', $email['body']); // Replace {variables} $email = ConvertForms\SmartTags::replace($email, $submission); // Send mail $mailer = new NRFramework\Email($email); if (!$mailer->send()) { throw new \Exception($mailer->error); } } } }PK!tww#convertforms/emails/form/fields.xmlnu[
    PK! R4UU!convertforms/emails/form/form.xmlnu[
    PK!P:**-convertforms/emails/form/fields/cfsubform.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); JFormHelper::loadFieldClass('subform'); class JFormFieldCFSubform extends JFormFieldSubform { /** * Method to get the field input markup. * * @return string The field input markup. * * @since 3.6 */ protected function getInput() { // The following script toggles the required attribute for all Email Notification options. JFactory::getDocument()->addScriptDeclaration(' jQuery(function($) { $("input[name=\'jform[sendnotifications]\']").on("change", function() { var enabled = $(this).is(":checked"); var exclude_fields = $("input[id*=reply_to], input[id$=attachments]"); var fields = $("#behavior-emails .subform-repeatable-group").find("input, textarea").not(exclude_fields); if (enabled) { fields.attr("required", "required").addClass("required"); } else { fields.removeAttr("required").removeClass("required"); } }); }); '); return parent::getInput(); } } PK!FLconvertforms/sendinblue/language/ru-RU/ru-RU.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Преобразование форм - интеграция с SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_DESC="Конвертировать формы - интеграция с почтовыми маркетинговыми сервисами SendinBlue." PLG_CONVERTFORMS_SENDINBLUE_KEY="Ключ API" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Ваш ключ API SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Где я могу найти ключ API?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="Список ID" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="Идентификатор списка, на который пользователь должен подписаться. Это может быть разделенный запятыми список для нескольких списков." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Где я могу найти идентификатор списка?" PK!wVLconvertforms/sendinblue/language/ca-ES/ca-ES.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Integració Convert Forms - SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_DESC="Integració entre Convert Forms i els serveis de màrqueting per correu electrònic SendinBlue." PLG_CONVERTFORMS_SENDINBLUE_KEY="Clau API" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="La teva clau API de SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="On trobar la clau API?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="ID de llista" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="L'ID del llistat al qual s'hauria de subscriure l'usuari. Pot ser un llistat separat per comes si són múltiples llistes." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="On trobar l'ID de llista?" PK!lrLconvertforms/sendinblue/language/bg-BG/bg-BG.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Convert Forms – SendinBlue интеграция" PLG_CONVERTFORMS_SENDINBLUE_DESC="Convert Forms – интеграция с SendinBlue имейл маркетинг услуги." PLG_CONVERTFORMS_SENDINBLUE_KEY="API ключ" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Вашият SendinBlue API ключ" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Къде да намерите API ключ?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="ID списък" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="ID на списъка, за който потребителят трябва да се абонира. Може чрез разделени със запетая ID-та, потребителят да бъде добавен в няколко списъка." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Къде да намерите идентификационния номер на списъка?" PK!睝Lconvertforms/sendinblue/language/cs-CZ/cs-CZ.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Convert Forms - Integrace SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_DESC="Convert Forms - Integrace emailových a marketingových služeb SendinBlue." PLG_CONVERTFORMS_SENDINBLUE_KEY="API klíč" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Váš SendinBlue API klíč" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Kde získáte API klíč?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="ID seznamu" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="ID seznamu k jehož odběru se uživatel přihlašuje. Může to být seznam oddělený čárkami v případě potřeby více seznamů." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Kde najdu ID seznamu?" PK!ɱLconvertforms/sendinblue/language/es-ES/es-ES.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="\"Formas de conversión\" - Integración con SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_DESC="\"Formularios de conversión\" - Integración con servicios de marketing de Email SendinBlue." PLG_CONVERTFORMS_SENDINBLUE_KEY="Clave de API" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Tu clave de API SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="¿Dónde encontrar la clave de API?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="Lista ID" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="La lista ID a la que el usuario debiera estar suscrito. Puede ser una lista separada por comas para listas múltiples." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="¿Dónde encontrar la Lista ID?" PK!(iiLconvertforms/sendinblue/language/fi-FI/fi-FI.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Convert Forms - SendinBlue liitäntä" PLG_CONVERTFORMS_SENDINBLUE_DESC="Convert Forms - Integrointi with SendinBlue Email Marketing palveluun." PLG_CONVERTFORMS_SENDINBLUE_KEY="API Key" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Sinun SendinBlue API Key" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Mistä löytyy API Key?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="Luettelo ID" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="Luettelo ID, jonka käyttäjän tulee tilata. Se voi olla pilkuilla erotettu luettelo useille luetteloille." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Mistä löytyy luettelo ID?" PK!cl0Pconvertforms/sendinblue/language/en-GB/en-GB.plg_convertforms_sendinblue.sys.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE="Convert Forms - SendinBlue Integration" PLG_CONVERTFORMS_SENDINBLUE_DESC="Convert Forms - Integration with SendinBlue Email Marketing Services."PK!oLconvertforms/sendinblue/language/en-GB/en-GB.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Convert Forms - SendinBlue Integration" PLG_CONVERTFORMS_SENDINBLUE_DESC="Convert Forms - Integration with SendinBlue Email Marketing Services." PLG_CONVERTFORMS_SENDINBLUE_KEY="API Key" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Your SendinBlue API Key" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Where to find API Key?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="List ID" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="The List ID which the user should be subscribed to. It can be a comma separated list for multiple lists." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Where to find List ID?" PLG_CONVERTFORMS_SENDINBLUE_VERSION="API Version" PLG_CONVERTFORMS_SENDINBLUE_VERSION_DESC="Select the API Version." PLG_CONVERTFORMS_SENDINBLUE_V2_DEPRECATION="API v2 Deprecation Notice" PLG_CONVERTFORMS_SENDINBLUE_V2_DEPRECATION_DESC="On June 25th 2020 Sendinblue's API v2 started its official deprecation process. Its sunset date has been scheduled for June 25th 2021. You're kindly requested to switch over to API v3." PLG_CONVERTFORMS_SENDINBLUE_UPDATE_EXISTING_USER="Update existing user" PLG_CONVERTFORMS_SENDINBLUE_UPDATE_EXISTING_USER_DESC=""PK!Lo>Lconvertforms/sendinblue/language/uk-UA/uk-UA.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Перетворити форми - інтеграція SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_DESC="Перетворити форми - інтеграція з маркетинговими послугами електронної пошти SendinBlue." PLG_CONVERTFORMS_SENDINBLUE_KEY="ключ API" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Ваш API API SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Де я можу знайти ключ API?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="список ID" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="Ідентифікатор списку, на який повинен підписатись користувач. Це може бути розділений комою список для кількох списків." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Де я можу знайти ідентифікатор списку?" PK!PYLconvertforms/sendinblue/language/fr-FR/fr-FR.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Convertisseur de formulaire - Intégration de SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_DESC="Convertisseur de formulaires - Intégration avec les services de Marketing et d'E-mailing de SendinBlue." PLG_CONVERTFORMS_SENDINBLUE_KEY="Clé de l'API" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Votre clé de l'API SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Où trouver la clé de l'API ?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="ID de la liste" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="L'ID de la liste à laquelle l'utilisateur doit s'abonner. Séparé par un tiret pour plusieurs listes." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Où trouver l'ID de la liste ?" PK!͖Lconvertforms/sendinblue/language/de-DE/de-DE.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Convert Forms - SendinBlue Integration" PLG_CONVERTFORMS_SENDINBLUE_DESC="Convert Forms - Integration mit SendInBlue E-Mail-Marketing-Diensten." PLG_CONVERTFORMS_SENDINBLUE_KEY="API Schlüssel" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="Ihr SendinBlue API Schlüssel" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Wo findet man den API Schlüssel?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="Listen ID" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="Die Listen ID, zu der der Benutzer hinzugefügt werden soll. Für mehreren Listen kann es eine durch Komma getrennte Liste sein." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Wo findet man die Listen ID?" PK!P5}}Lconvertforms/sendinblue/language/it-IT/it-IT.plg_convertforms_sendinblue.ininu[; @package Convert Forms ; @version 3.2.4 Pro ; ; @author Tassos Marinos - http://www.tassos.gr ; @copyright Copyright (c) 2016 Tassos Marinos. All rights reserved. ; @license http://www.tassos.gr PLG_CONVERTFORMS_SENDINBLUE_ALIAS="SendinBlue" PLG_CONVERTFORMS_SENDINBLUE="Integrazione Convert Forms - SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_DESC="Integrazione Convert Forms con i servizi Email Marketing di SendinBlue." PLG_CONVERTFORMS_SENDINBLUE_KEY="Chiave API" PLG_CONVERTFORMS_SENDINBLUE_KEY_DESC="La tua chiave API di SendinBlue" PLG_CONVERTFORMS_SENDINBLUE_FIND_API_KEY="Dove trovare la chiave API?" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID="ID elenco" PLG_CONVERTFORMS_SENDINBLUE_LIST_ID_DESC="L'ID elenco a cui l'utente dovrebbe essere iscritto. Può essere un elenco separato da virgola per liste multiple." PLG_CONVERTFORMS_SENDINBLUE_FIND_LIST="Dove trovare l'ID elenco?" PK!sRR convertforms/sendinblue/form.xmlnu[
    PK!!#991convertforms/sendinblue/script.install.helper.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2016 Tassos Marinos All Rights Reserved * @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL */ defined('_JEXEC') or die; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); class PlgConvertformsSendinblueInstallerScriptHelper { public $name = ''; public $alias = ''; public $extname = ''; public $extension_type = ''; public $plugin_folder = 'system'; public $module_position = 'status'; public $client_id = 1; public $install_type = 'install'; public $show_message = true; public $autopublish = true; public $db = null; public $app = null; public $installedVersion; public function __construct(&$params) { $this->extname = $this->extname ?: $this->alias; $this->db = JFactory::getDbo(); $this->app = JFactory::getApplication(); $this->installedVersion = $this->getVersion($this->getInstalledXMLFile()); } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function preflight($route, $adapter) { if (!in_array($route, array('install', 'update'))) { return; } JFactory::getLanguage()->load('plg_system_novaraininstaller', JPATH_PLUGINS . '/system/novaraininstaller'); if ($this->show_message && $this->isInstalled()) { $this->install_type = 'update'; } if ($this->onBeforeInstall() === false) { return false; } } /** * Preflight event * * @param string * @param JAdapterInstance * * @return boolean */ public function postflight($route, $adapter) { JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); if (!in_array($route, array('install', 'update'))) { return; } if ($this->onAfterInstall() === false) { return false; } if ($route == 'install' && $this->autopublish) { $this->publishExtension(); } if ($this->show_message) { $this->addInstalledMessage(); } JFactory::getCache()->clean('com_plugins'); JFactory::getCache()->clean('_system'); } public function isInstalled() { if (!is_file($this->getInstalledXMLFile())) { return false; } $query = $this->db->getQuery(true) ->select('extension_id') ->from('#__extensions') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); $this->db->setQuery($query, 0, 1); $result = $this->db->loadResult(); return empty($result) ? false : true; } public function getMainFolder() { switch ($this->extension_type) { case 'plugin' : return JPATH_SITE . '/plugins/' . $this->plugin_folder . '/' . $this->extname; case 'component' : return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; case 'module' : return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; case 'library' : return JPATH_SITE . '/libraries/' . $this->extname; } } public function getInstalledXMLFile() { return $this->getXMLFile($this->getMainFolder()); } public function getCurrentXMLFile() { return $this->getXMLFile(__DIR__); } public function getXMLFile($folder) { switch ($this->extension_type) { case 'module' : return $folder . '/mod_' . $this->extname . '.xml'; default : return $folder . '/' . $this->extname . '.xml'; } } public function foldersExist($folders = array()) { foreach ($folders as $folder) { if (is_dir($folder)) { return true; } } return false; } public function publishExtension() { switch ($this->extension_type) { case 'plugin' : $this->publishPlugin(); case 'module' : $this->publishModule(); } } public function publishPlugin() { $query = $this->db->getQuery(true) ->update('#__extensions') ->set($this->db->quoteName('enabled') . ' = 1') ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); $this->db->setQuery($query); $this->db->execute(); } public function publishModule() { // Get module id $query = $this->db->getQuery(true) ->select('id') ->from('#__modules') ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); $this->db->setQuery($query, 0, 1); $id = $this->db->loadResult(); if (!$id) { return; } // check if module is already in the modules_menu table (meaning is is already saved) $query->clear() ->select('moduleid') ->from('#__modules_menu') ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); $this->db->setQuery($query, 0, 1); $exists = $this->db->loadResult(); if ($exists) { return; } // Get highest ordering number in position $query->clear() ->select('ordering') ->from('#__modules') ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) ->order('ordering DESC'); $this->db->setQuery($query, 0, 1); $ordering = $this->db->loadResult(); $ordering++; // publish module and set ordering number $query->clear() ->update('#__modules') ->set($this->db->quoteName('published') . ' = 1') ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) ->where($this->db->quoteName('id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); // add module to the modules_menu table $query->clear() ->insert('#__modules_menu') ->columns(array($this->db->quoteName('moduleid'), $this->db->quoteName('menuid'))) ->values((int) $id . ', 0'); $this->db->setQuery($query); $this->db->execute(); } public function addInstalledMessage() { JFactory::getApplication()->enqueueMessage( JText::sprintf( JText::_($this->install_type == 'update' ? 'NRI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'NRI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), '' . JText::_($this->name) . '', '' . $this->getVersion() . '', $this->getFullType() ) ); } public function getPrefix() { switch ($this->extension_type) { case 'plugin'; return JText::_('plg_' . strtolower($this->plugin_folder)); case 'component': return JText::_('com'); case 'module': return JText::_('mod'); case 'library': return JText::_('lib'); default: return $this->extension_type; } } public function getElementName($type = null, $extname = null) { $type = is_null($type) ? $this->extension_type : $type; $extname = is_null($extname) ? $this->extname : $extname; switch ($type) { case 'component' : return 'com_' . $extname; case 'module' : return 'mod_' . $extname; case 'plugin' : default: return $extname; } } public function getFullType() { return JText::_('NRI_' . strtoupper($this->getPrefix())); } public function isPro() { $versionFile = __DIR__ . "/version.php"; // If version file does not exist we assume a PRO version if (!JFile::exists($versionFile)) { return true; } // Load version file require_once $versionFile; return (bool) $NR_PRO; } public function getVersion($file = '') { $file = $file ?: $this->getCurrentXMLFile(); if (!is_file($file)) { return ''; } $xml = JInstaller::parseXMLInstallFile($file); if (!$xml || !isset($xml['version'])) { return ''; } return $xml['version']; } /** * Checks wether the extension can be installed or not * * @return boolean */ public function canInstall() { // The extension is not installed yet. Accept Install. if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } // Path to extension's version file $versionFile = $this->getMainFolder() . "/version.php"; $NR_PRO = true; // If version file does not exist we assume we have a PRO version installed if (file_exists($versionFile)) { require_once($versionFile); } // The free version is installed. Accept install. if (!(bool)$NR_PRO) { return true; } // Current package is a PRO version. Accept install. if ($this->isPro()) { return true; } // User is trying to update from PRO version to FREE. Do not accept install. JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); JFactory::getApplication()->enqueueMessage( JText::_('NRI_ERROR_PRO_TO_FREE'), 'error' ); JFactory::getApplication()->enqueueMessage( html_entity_decode( JText::sprintf( 'NRI_ERROR_UNINSTALL_FIRST', '', '', JText::_($this->name) ) ), 'error' ); return false; } /** * Checks if current version is newer than the installed one * Used for Novarain Framework * * @return boolean [description] */ public function isNewer() { if (!$installed_version = $this->getVersion($this->getInstalledXMLFile())) { return true; } $package_version = $this->getVersion(); return version_compare($installed_version, $package_version, '<='); } /** * Helper method triggered before installation * * @return bool */ public function onBeforeInstall() { if (!$this->canInstall()) { return false; } } /** * Helper method triggered after installation */ public function onAfterInstall() { } /** * Delete files * * @param array $folders */ public function deleteFiles($files = array()) { foreach ($files as $key => $file) { JFile::delete($file); } } /** * Deletes folders * * @param array $folders */ public function deleteFolders($folders = array()) { foreach ($folders as $folder) { if (!is_dir($folder)) { continue; } JFolder::delete($folder); } } public function dropIndex($table, $index) { $db = $this->db; // Check if index exists first $query = 'SHOW INDEX FROM ' . $db->quoteName('#__' . $table) . ' WHERE KEY_NAME = ' . $db->quote($index); $db->setQuery($query); $db->execute(); if (!$db->loadResult()) { return; } // Remove index $query = 'ALTER TABLE ' . $db->quoteName('#__' . $table) . ' DROP INDEX ' . $db->quoteName($index); $db->setQuery($query); $db->execute(); } public function dropUnwantedTables($tables) { if (!$tables) { return; } foreach ($tables as $table) { $query = "DROP TABLE IF EXISTS #__".$this->db->escape($table); $this->db->setQuery($query); $this->db->execute(); } } public function dropUnwantedColumns($table, $columns) { if (!$columns || !$table) { return; } $db = $this->db; // Check if columns exists in database function qt($n) { return(JFactory::getDBO()->quote($n)); } $query = 'SHOW COLUMNS FROM #__'.$table.' WHERE Field IN ('.implode(",", array_map("qt", $columns)).')'; $db->setQuery($query); $rows = $db->loadColumn(0); // Abort if we don't have any rows if (!$rows) { return; } // Let's remove the columns $q = ""; foreach ($rows as $key => $column) { $comma = (($key+1) < count($rows)) ? "," : ""; $q .= "drop ".$this->db->escape($column).$comma; } $query = "alter table #__".$table." $q"; $db->setQuery($query); $db->execute(); } public function fetch($table, $columns = "*", $where = null, $singlerow = false) { if (!$table) { return; } $db = $this->db; $query = $db->getQuery(true); $query ->select($columns) ->from("#__$table"); if (isset($where)) { $query->where("$where"); } $db->setQuery($query); return ($singlerow) ? $db->loadObject() : $db->loadObjectList(); } /** * Load the Novarain Framework * * @return boolean */ public function loadFramework() { if (is_file(JPATH_PLUGINS . '/system/nrframework/autoload.php')) { include_once JPATH_PLUGINS . '/system/nrframework/autoload.php'; } } /** * Re-orders plugin after passed array of plugins * * @param string $plugin Plugin element name * @param array $lowerPluginOrder Array of plugin element names * * @return boolean */ public function pluginOrderAfter($lowerPluginOrder) { if (!is_array($lowerPluginOrder) || !count($lowerPluginOrder)) { return; } $db = $this->db; // Get plugins max order $query = $db->getQuery(true); $query ->select($db->quoteName('b.ordering')) ->from($db->quoteName('#__extensions', 'b')) ->where($db->quoteName('b.element') . ' IN ("'.implode("\",\"",$lowerPluginOrder).'")') ->order('b.ordering desc'); $db->setQuery($query); $maxOrder = $db->loadResult(); if (is_null($maxOrder)) { return; } // Get plugin details $query ->clear() ->select(array($db->quoteName('extension_id'), $db->quoteName('ordering'))) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('element') . ' = ' . $db->quote($this->alias)); $db->setQuery($query); $pluginInfo = $db->loadObject(); if (!isset($pluginInfo->ordering) || $pluginInfo->ordering > $maxOrder) { return; } // Update the new plugin order $object = new stdClass(); $object->extension_id = $pluginInfo->extension_id; $object->ordering = ($maxOrder + 1); try { $db->updateObject('#__extensions', $object, 'extension_id'); } catch (Exception $e) { return $e->getMessage(); } } } PK!{*convertforms/sendinblue/script.install.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2020 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); require_once __DIR__ . '/script.install.helper.php'; class PlgConvertFormsSendinBlueInstallerScript extends PlgConvertFormsSendinBlueInstallerScriptHelper { public $name = 'PLG_CONVERTFORMS_SENDINBLUE'; public $alias = 'sendinblue'; public $extension_type = 'plugin'; public $plugin_folder = "convertforms"; public $show_message = false; } PK!^00&convertforms/sendinblue/sendinblue.xmlnu[ PLG_CONVERTFORMS_SENDINBLUE PLG_CONVERTFORMS_SENDINBLUE_DESC 1.0 Tassos Marinos info@tassos.gr http://www.tassos.gr Copyright (c)2011-2016 Tassos Marinos GNU General Public License version 3, or later March 2017 script.install.php language sendinblue.php form.xml script.install.helper.php PK! &convertforms/sendinblue/sendinblue.phpnu[ * @link http://www.tassos.gr * @copyright Copyright © 2021 Tassos Marinos All Rights Reserved * @license GNU GPLv3 or later */ defined('_JEXEC') or die('Restricted access'); class plgConvertFormsSendInBlue extends \ConvertForms\Plugin { /** * Main method to store data to service * * @return void */ public function subscribe() { $class_name = $this->getCampaignIntegration($this->lead->campaign); $api = new $class_name([ 'api' => $this->lead->campaign->api ]); $api->subscribe( $this->lead->email, $this->lead->params, $this->lead->campaign->list, (bool) $this->lead->campaign->updateexisting ); if (!$api->success()) { throw new Exception($api->getLastError()); } } /** * Returns the campaign integration. * Loads the exact version we have specified in the campaign settings. * * @param array $campaignData * * @return string */ protected function getCampaignIntegration($campaignData) { $campaignData = (array) $campaignData; return parent::getCampaignIntegration($campaignData) . $this->getSuffix($campaignData['version']); } /** * Get integration suffix * * @param string $version * * @return mixed */ private function getSuffix($version) { return (int) $version == 3 ? 3 : ''; } }PK! %privacy/content/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Privacy\Content\Extension\Content; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Content( $dispatcher, (array) PluginHelper::getPlugin('privacy', 'content') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!)privacy/content/src/Extension/Content.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Privacy\Content\Extension; use Joomla\CMS\User\User; use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin; use Joomla\Component\Privacy\Administrator\Table\RequestTable; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Privacy plugin managing Joomla user content data * * @since 3.9.0 */ final class Content extends PrivacyPlugin { /** * Processes an export request for Joomla core user content data * * This event will collect data for the content core table * * - Content custom fields * * @param RequestTable $request The request record being processed * @param User $user The user account associated with this request if available * * @return \Joomla\Component\Privacy\Administrator\Export\Domain[] * * @since 3.9.0 */ public function onPrivacyExportRequest(RequestTable $request, User $user = null) { if (!$user) { return []; } $domains = []; $domain = $this->createDomain('user_content', 'joomla_user_content_data'); $domains[] = $domain; $db = $this->getDatabase(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__content')) ->where($db->quoteName('created_by') . ' = ' . (int) $user->id) ->order($db->quoteName('ordering') . ' ASC'); $items = $db->setQuery($query)->loadObjectList(); foreach ($items as $item) { $domain->addItem($this->createItemFromArray((array) $item)); } $domains[] = $this->createCustomFieldsDomain('com_content.article', $items); return $domains; } } PK!2"n``privacy/content/content.xmlnu[ plg_privacy_content Joomla! Project 2018-07 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_PRIVACY_CONTENT_XML_DESCRIPTION Joomla\Plugin\Privacy\Content services src language/en-GB/plg_privacy_content.ini language/en-GB/plg_privacy_content.sys.ini PK!!NNprivacy/user/user.xmlnu[ plg_privacy_user Joomla! Project 2018-05 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_PRIVACY_USER_XML_DESCRIPTION Joomla\Plugin\Privacy\User services src language/en-GB/plg_privacy_user.ini language/en-GB/plg_privacy_user.sys.ini PK!ޒu$"privacy/user/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Privacy\User\Extension\UserPlugin; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new UserPlugin( $dispatcher, (array) PluginHelper::getPlugin('privacy', 'user') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!֔)privacy/user/src/Extension/UserPlugin.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Privacy\User\Extension; use Joomla\CMS\Language\Text; use Joomla\CMS\Table\User as TableUser; use Joomla\CMS\User\User; use Joomla\CMS\User\UserHelper; use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin; use Joomla\Component\Privacy\Administrator\Removal\Status; use Joomla\Component\Privacy\Administrator\Table\RequestTable; use Joomla\Database\ParameterType; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Privacy plugin managing Joomla user data * * @since 3.9.0 */ final class UserPlugin extends PrivacyPlugin { /** * Performs validation to determine if the data associated with a remove information request can be processed * * This event will not allow a super user account to be removed * * @param RequestTable $request The request record being processed * @param User $user The user account associated with this request if available * * @return Status * * @since 3.9.0 */ public function onPrivacyCanRemoveData(RequestTable $request, User $user = null) { $status = new Status(); if (!$user) { return $status; } if ($user->authorise('core.admin')) { $status->canRemove = false; $status->reason = Text::_('PLG_PRIVACY_USER_ERROR_CANNOT_REMOVE_SUPER_USER'); } return $status; } /** * Processes an export request for Joomla core user data * * This event will collect data for the following core tables: * * - #__users (excluding the password, otpKey, and otep columns) * - #__user_notes * - #__user_profiles * - User custom fields * * @param RequestTable $request The request record being processed * @param User $user The user account associated with this request if available * * @return \Joomla\Component\Privacy\Administrator\Export\Domain[] * * @since 3.9.0 */ public function onPrivacyExportRequest(RequestTable $request, User $user = null) { if (!$user) { return []; } /** @var TableUser $userTable */ $userTable = User::getTable(); $userTable->load($user->id); $domains = []; $domains[] = $this->createUserDomain($userTable); $domains[] = $this->createNotesDomain($userTable); $domains[] = $this->createProfileDomain($userTable); $domains[] = $this->createCustomFieldsDomain('com_users.user', [$userTable]); return $domains; } /** * Removes the data associated with a remove information request * * This event will pseudoanonymise the user account * * @param RequestTable $request The request record being processed * @param User $user The user account associated with this request if available * * @return void * * @since 3.9.0 */ public function onPrivacyRemoveData(RequestTable $request, User $user = null) { // This plugin only processes data for registered user accounts if (!$user) { return; } $pseudoanonymisedData = [ 'name' => 'User ID ' . $user->id, 'username' => bin2hex(random_bytes(12)), 'email' => 'UserID' . $user->id . 'removed@email.invalid', 'block' => true, ]; $user->bind($pseudoanonymisedData); $user->save(); // Destroy all sessions for the user account UserHelper::destroyUserSessions($user->id); } /** * Create the domain for the user notes data * * @param TableUser $user The TableUser object to process * * @return \Joomla\Component\Privacy\Administrator\Export\Domain * * @since 3.9.0 */ private function createNotesDomain(TableUser $user) { $domain = $this->createDomain('user_notes', 'joomla_user_notes_data'); $db = $this->getDatabase(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__user_notes')) ->where($db->quoteName('user_id') . ' = :userid') ->bind(':userid', $user->id, ParameterType::INTEGER); $items = $db->setQuery($query)->loadAssocList(); // Remove user ID columns foreach (['user_id', 'created_user_id', 'modified_user_id'] as $column) { $items = ArrayHelper::dropColumn($items, $column); } foreach ($items as $item) { $domain->addItem($this->createItemFromArray($item, $item['id'])); } return $domain; } /** * Create the domain for the user profile data * * @param TableUser $user The TableUser object to process * * @return \Joomla\Component\Privacy\Administrator\Export\Domain * * @since 3.9.0 */ private function createProfileDomain(TableUser $user) { $domain = $this->createDomain('user_profile', 'joomla_user_profile_data'); $db = $this->getDatabase(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__user_profiles')) ->where($db->quoteName('user_id') . ' = :userid') ->order($db->quoteName('ordering') . ' ASC') ->bind(':userid', $user->id, ParameterType::INTEGER); $items = $db->setQuery($query)->loadAssocList(); foreach ($items as $item) { $domain->addItem($this->createItemFromArray($item)); } return $domain; } /** * Create the domain for the user record * * @param TableUser $user The TableUser object to process * * @return \Joomla\Component\Privacy\Administrator\Export\Domain * * @since 3.9.0 */ private function createUserDomain(TableUser $user) { $domain = $this->createDomain('users', 'joomla_users_data'); $domain->addItem($this->createItemForUserTable($user)); return $domain; } /** * Create an item object for a TableUser object * * @param TableUser $user The TableUser object to convert * * @return \Joomla\Component\Privacy\Administrator\Export\Item * * @since 3.9.0 */ private function createItemForUserTable(TableUser $user) { $data = []; $exclude = ['password', 'otpKey', 'otep']; foreach (array_keys($user->getFields()) as $fieldName) { if (!in_array($fieldName, $exclude)) { $data[$fieldName] = $user->$fieldName; } } return $this->createItemFromArray($data, $user->id); } } PK!I1b%privacy/message/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Privacy\Message\Extension\Message; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Message( $dispatcher, (array) PluginHelper::getPlugin('privacy', 'message') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!{ ``privacy/message/message.xmlnu[ plg_privacy_message Joomla! Project 2018-07 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_PRIVACY_MESSAGE_XML_DESCRIPTION Joomla\Plugin\Privacy\Message services src language/en-GB/plg_privacy_message.ini language/en-GB/plg_privacy_message.sys.ini PK!q')privacy/message/src/Extension/Message.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Privacy\Message\Extension; use Joomla\CMS\User\User; use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin; use Joomla\Component\Privacy\Administrator\Table\RequestTable; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Privacy plugin managing Joomla user messages * * @since 3.9.0 */ final class Message extends PrivacyPlugin { /** * Processes an export request for Joomla core user message * * This event will collect data for the message table * * @param RequestTable $request The request record being processed * @param User $user The user account associated with this request if available * * @return \Joomla\Component\Privacy\Administrator\Export\Domain[] * * @since 3.9.0 */ public function onPrivacyExportRequest(RequestTable $request, User $user = null) { if (!$user) { return []; } $domain = $this->createDomain('user_messages', 'joomla_user_messages_data'); $db = $this->getDatabase(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__messages')) ->where($db->quoteName('user_id_from') . ' = :useridfrom') ->extendWhere('OR', $db->quoteName('user_id_to') . ' = :useridto') ->order($db->quoteName('date_time') . ' ASC') ->bind([':useridfrom', ':useridto'], $user->id, ParameterType::INTEGER); $items = $db->setQuery($query)->loadAssocList(); foreach ($items as $item) { $domain->addItem($this->createItemFromArray($item)); } return [$domain]; } } PK!@Cc%privacy/contact/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Privacy\Contact\Extension\Contact; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Contact( $dispatcher, (array) PluginHelper::getPlugin('privacy', 'contact') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!L```privacy/contact/contact.xmlnu[ plg_privacy_contact Joomla! Project 2018-07 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_PRIVACY_CONTACT_XML_DESCRIPTION Joomla\Plugin\Privacy\Contact services src language/en-GB/plg_privacy_contact.ini language/en-GB/plg_privacy_contact.sys.ini PK!Sݒ  )privacy/contact/src/Extension/Contact.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Privacy\Contact\Extension; use Joomla\CMS\User\User; use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin; use Joomla\Component\Privacy\Administrator\Table\RequestTable; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Privacy plugin managing Joomla user contact data * * @since 3.9.0 */ final class Contact extends PrivacyPlugin { /** * Processes an export request for Joomla core user contact data * * This event will collect data for the contact core tables: * * - Contact custom fields * * @param RequestTable $request The request record being processed * @param User $user The user account associated with this request if available * * @return \Joomla\Component\Privacy\Administrator\Export\Domain[] * * @since 3.9.0 */ public function onPrivacyExportRequest(RequestTable $request, User $user = null) { if (!$user && !$request->email) { return []; } $domains = []; $domain = $this->createDomain('user_contact', 'joomla_user_contact_data'); $domains[] = $domain; $db = $this->getDatabase(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__contact_details')) ->order($db->quoteName('ordering') . ' ASC'); if ($user) { $query->where($db->quoteName('user_id') . ' = :id') ->bind(':id', $user->id, ParameterType::INTEGER); } else { $query->where($db->quoteName('email_to') . ' = :email') ->bind(':email', $request->email); } $items = $db->setQuery($query)->loadObjectList(); foreach ($items as $item) { $domain->addItem($this->createItemFromArray((array) $item)); } $domains[] = $this->createCustomFieldsDomain('com_contact.contact', $items); return $domains; } } PK!*3rr!privacy/actionlogs/actionlogs.xmlnu[ plg_privacy_actionlogs Joomla! Project 2018-07 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_PRIVACY_ACTIONLOGS_XML_DESCRIPTION Joomla\Plugin\Privacy\Actionlogs services src language/en-GB/plg_privacy_actionlogs.ini language/en-GB/plg_privacy_actionlogs.sys.ini PK!H(privacy/actionlogs/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Privacy\Actionlogs\Extension\Actionlogs; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Actionlogs( $dispatcher, (array) PluginHelper::getPlugin('privacy', 'actionlogs') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!U  /privacy/actionlogs/src/Extension/Actionlogs.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Privacy\Actionlogs\Extension; use Joomla\CMS\User\User; use Joomla\Component\Actionlogs\Administrator\Helper\ActionlogsHelper; use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin; use Joomla\Component\Privacy\Administrator\Table\RequestTable; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Privacy plugin managing Joomla actionlogs data * * @since 3.9.0 */ final class Actionlogs extends PrivacyPlugin { /** * Processes an export request for Joomla core actionlog data * * @param RequestTable $request The request record being processed * @param User $user The user account associated with this request if available * * @return \Joomla\Component\Privacy\Administrator\Export\Domain[] * * @since 3.9.0 */ public function onPrivacyExportRequest(RequestTable $request, User $user = null) { if (!$user) { return []; } $domain = $this->createDomain('user_action_logs', 'joomla_user_action_logs_data'); $db = $this->getDatabase(); $userId = (int) $user->id; $query = $db->getQuery(true) ->select(['a.*', $db->quoteName('u.name')]) ->from($db->quoteName('#__action_logs', 'a')) ->join('INNER', $db->quoteName('#__users', 'u'), $db->quoteName('a.user_id') . ' = ' . $db->quoteName('u.id')) ->where($db->quoteName('a.user_id') . ' = :id') ->bind(':id', $userId, ParameterType::INTEGER); $db->setQuery($query); $data = $db->loadObjectList(); if (!count($data)) { return []; } $data = ActionlogsHelper::getCsvData($data); $isFirst = true; foreach ($data as $item) { if ($isFirst) { $isFirst = false; continue; } $domain->addItem($this->createItemFromArray($item)); } return [$domain]; } } PK!,p&privacy/consents/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\DatabaseInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\Privacy\Consents\Extension\Consents; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Consents( $dispatcher, (array) PluginHelper::getPlugin('privacy', 'consents') ); $plugin->setApplication(Factory::getApplication()); $plugin->setDatabase($container->get(DatabaseInterface::class)); return $plugin; } ); } }; PK!;ffprivacy/consents/consents.xmlnu[ plg_privacy_consents Joomla! Project 2018-07 (C) 2018 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.9.0 PLG_PRIVACY_CONSENTS_XML_DESCRIPTION Joomla\Plugin\Privacy\Consents services src language/en-GB/plg_privacy_consents.ini language/en-GB/plg_privacy_consents.sys.ini PK!1+privacy/consents/src/Extension/Consents.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Privacy\Consents\Extension; use Joomla\CMS\User\User; use Joomla\Component\Privacy\Administrator\Plugin\PrivacyPlugin; use Joomla\Component\Privacy\Administrator\Table\RequestTable; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Privacy plugin managing Joomla user consent data * * @since 3.9.0 */ final class Consents extends PrivacyPlugin { /** * Processes an export request for Joomla core user consent data * * This event will collect data for the core `#__privacy_consents` table * * @param RequestTable $request The request record being processed * @param User $user The user account associated with this request if available * * @return \Joomla\Component\Privacy\Administrator\Export\Domain[] * * @since 3.9.0 */ public function onPrivacyExportRequest(RequestTable $request, User $user = null) { if (!$user) { return []; } $domain = $this->createDomain('consents', 'joomla_consent_data'); $db = $this->getDatabase(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__privacy_consents')) ->where($db->quoteName('user_id') . ' = :id') ->order($db->quoteName('created') . ' ASC') ->bind(':id', $user->id, ParameterType::INTEGER); $items = $db->setQuery($query)->loadAssocList(); foreach ($items as $item) { $domain->addItem($this->createItemFromArray($item)); } return [$domain]; } } PK!iMM&search/sppagebuilder/sppagebuilder.phpnu[ 'SP_PAGEBUILDER_SEARCH_AREAS' ); return $areas; } /** * Search content (SP Pagebuilder). * * The SQL must return the following fields that are used in a common display * routine: href, title, section, created, text, browsernav. * * @param string $text Target search string. * @param string $phrase Matching option (possible values: exact|any|all). Default is "any". * @param string $ordering Ordering option (possible values: newest|oldest|popular|alpha|category). Default is "newest". * @param mixed $areas An array if the search is to be restricted to areas or null to search all areas. * * @return array Search results. * */ public function onContentSearch( $text, $phrase = '', $ordering = '', $areas = null ) { $db = Factory::getDbo(); $limit = $this->params->def('search_limit', 50); $tag = Factory::getLanguage()->getTag(); if (is_array($areas)) { if (!array_intersect($areas, array_keys($this->onContentSearchAreas()))) { return array(); } } $text = trim($text); if ($text == '') { return array(); } JLoader::register('SppagebuilderRouter', JPATH_SITE . '/components/com_sppagebuilder/route.php'); switch ($phrase) { case 'exact': case 'all': case 'any': default: $text = $db->quote('%' . $db->escape($text, true) . '%', false); $wheres1 = array(); $wheres1[] = 's.title LIKE ' . $text; $wheres1[] = 's.text LIKE ' . $text; $where = '((' . implode(') OR (', $wheres1) . ')) AND s.published = 1'; break; } switch ($ordering) { case 'oldest': $order = 's.created_time ASC'; break; case 'alpha': $order = 's.title ASC'; break; case 'newest': case 'category': case 'popular': default: $order = 's.created_on DESC'; break; } $query = $db->getQuery(true); if ( $limit > 0 ) { $query->clear(); $query->select('s.id as id, s.title AS title, s.created_on as created, s.language as language'); $query->from($db->quoteName('#__sppagebuilder', 's')); $query->where($db->quoteName('s.extension') . ' = ' . $db->quote('com_sppagebuilder')); $query->where($where); if ($this->app->isClient('site') && Multilanguage::isEnabled()) { $query->where('s.language in (' . $db->quote($tag) . ',' . $db->quote('*') . ')'); } $query->order($order); $db->setQuery($query, 0, $limit); } try { $list = $db->loadObjectList(); if (isset($list)) { foreach ($list as $key => $item) { $menuItem = $this->getActiveMenu($item->id); // if(isset($menuItem->title) && $menuItem->title) { // $list[$key]->title = $menuItem->title; // } $itemId = ''; if(isset($menuItem->id) && $menuItem->id) { $itemId = '&Itemid=' . $menuItem->id; } $list[$key]->href = Route::_('index.php?option=com_sppagebuilder&view=page&id='.$item->id.((($item->language != '*'))? '&lang='.$item->language:'') . $itemId); } } } catch (RuntimeException $e) { $list = array(); $this->app->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); } return $list; } public static function getActiveMenu($pageId) { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select(array('title, id')); $query->from($db->quoteName('#__menu')); $query->where($db->quoteName('link') . ' LIKE '. $db->quote('%option=com_sppagebuilder&view=page&id='. $pageId .'%')); $query->where($db->quoteName('published') . ' = '. $db->quote('1')); $db->setQuery($query); $item = $db->loadObject(); return $item; } } PK!oHYY&search/sppagebuilder/sppagebuilder.xmlnu[ plg_search_sppagebuilder JoomShaper July 2015 Copyright (C) 2015 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt support@joomshaper.com www.joomshaper.com 4.0.8 PLG_SEARCH_SPPAGEBUILDER_DESCRIPTION sppagebuilder.php language/en-GB.plg_search_sppagebuilder.ini language/en-GB.plg_search_sppagebuilder.sys.ini PK!i-:#nnsearch/easyblog/easyblog.xmlnu[ Search - Easy Blog StackIdeas Private Limited 25 April 2017 Copyright 2010 - 2017 StackIdeas. All rights reserved. GPL License support@stackideas.com https://stackideas.com 5.1.0 Allows user to search for blog entries created from Easy Blog easyblog.php index.html
    https://stackideas.com/joomla4compat.xml
    PK!ja&&search/easyblog/easyblog.phpnu[my = JFactory::getUser(); if ($this->exists()) { $this->config = EB::config(); } parent::__construct($subject, $params); } /** * Retrieves the list of search areas * * @since 5.0.36 * @access public */ public function onContentSearchAreas() { // Check if EasyBlog exists and is installed if (!self::exists()) { return array(); } // Load site's language EB::loadLanguages(); $areas = array('blogs' => JText::_('PLG_EASYBLOG_SEARCH_BLOGS')); return $areas; } /** * When user performs a search * * @since 5.0.36 * @access public */ public function onContentSearch($text, $phrase='', $ordering='', $areas=null) { $plugin = JPluginHelper::getPlugin('search', 'easyblog'); $params = EB::registry($plugin->params); // Check if EasyBlog exists and is installed if (!self::exists()) { return array(); } // Get the list of search areas $searchAreas = self::onContentSearchAreas(); if (is_array($areas) && !array_intersect($areas, array_keys($searchAreas))) { return array(); } $text = trim($text); if ($text == '') { return array(); } // Get search results $results = $this->getResult($text, $phrase, $ordering); if (!$results) { return array(); } $newRows = array(); foreach ($results as $row) { // combine the blog title $content = $row->title . ' ' . $row->text; // Remove all the HTML content $content = preg_replace('/\s+/', ' ', strip_tags($content)); // Determine if the search term still exist into the stripped HTML content $searchTermsExist = $this->searchTermsExist($content, $text); // Assign to the new array if search term exist into the blog content (stripped HTML) if ($searchTermsExist) { $newRows[] = $row; } } if (!$newRows) { return array(); } $posts = array(); foreach ($newRows as &$row) { $post = EB::post($row->id); $row->section = JText::sprintf('PLG_EASYBLOG_SEARCH_BLOGS_SECTION', $post->getPrimaryCategory()->title); $row->href = $post->getPermalink(); $row->image = $post->getImage('large', false, true); } return $newRows; } /** * Determines if EasyBlog exists on the site. * * @since 5.0.36 * @access public */ public function exists() { $file = JPATH_ADMINISTRATOR . '/components/com_easyblog/includes/easyblog.php'; $enabled = JComponentHelper::isEnabled('com_easyblog'); if (!JFile::exists($file) || !$enabled) { return false; } require_once($file); if (!EB::isFoundryEnabled()) { return false; } return true; } /** * Performs the real searching for blog posts here. * * @since 5.0.36 * @access public */ public function getResult($text, $phrase, $ordering) { $db = EB::db(); $where = array(); $where2 = array(); // used for privacy $queryWhere = ''; $queryExclude = ''; $queryExcludePending = ''; $excludeCats = array(); $languageTag = FH::getCurrentLanguageTag(); $isSiteMultilingualEnabled = FH::isMultiLingual(); // Exact matches if ($phrase == 'exact') { $searchText = $db->Quote('%' . $db->escape($text, true) . '%', false); $where[] = 'a.`title` LIKE ' . $searchText; $where[] = 'a.`content` LIKE ' . $searchText; $where[] = 'a.`intro` LIKE ' . $searchText; $where2 = '(t.`title` LIKE ' . $searchText . ')'; $where = '(' . implode(') OR (', $where) . ')'; } else { $text = $this->normalizeTerms($text); $words = explode(' ', $text); $wheres = array(); $where2 = array(); $wheres2 = array(); foreach ($words as $word) { $word = $db->Quote( '%'. $db->escape($word, true) .'%', false ); $where[] = 'a.`title` LIKE ' . $word; $where[] = 'a.`content` LIKE ' . $word; $where[] = 'a.`intro` LIKE ' . $word; $where2[] = 't.title LIKE ' . $word; $wheres[] = implode(' OR ', $where ); $wheres2[] = implode(' OR ', $where2); } $where = '(' . implode( ($phrase == 'all' ? ') AND (' : ') OR ('), $wheres ) . ')'; $where2 = '(' . implode( ($phrase == 'all' ? ') AND (' : ') OR ('), $wheres2 ) . ')'; } $isJSGrpPluginInstalled = JPluginHelper::isEnabled('system', 'groupeasyblog'); $isEventPluginInstalled = JPluginHelper::isEnabled('system', 'eventeasyblog'); // Need to check if the site installed jomsocial. $isJSInstalled = EB::jomsocial()->exists(); $includeJSGrp = ($isJSGrpPluginInstalled && $isJSInstalled) ? true : false; $includeJSEvent = ($isEventPluginInstalled && $isJSInstalled ) ? true : false; // Get teamblogs id. $query = ''; // contribution type sql $contributor = EB::contributor(); $contributeSQL = ' AND ( (a.`source_type` = ' . $db->Quote(EASYBLOG_POST_SOURCE_SITEWIDE) . ') '; if ($this->config->get('main_includeteamblogpost')) { $contributeSQL .= $contributor::genAccessSQL(EASYBLOG_POST_SOURCE_TEAM, 'a'); } if ($includeJSEvent) { $contributeSQL .= $contributor::genAccessSQL(EASYBLOG_POST_SOURCE_JOMSOCIAL_EVENT, 'a'); } if ($includeJSGrp) { $contributeSQL .= $contributor::genAccessSQL(EASYBLOG_POST_SOURCE_JOMSOCIAL_GROUP, 'a'); } if (EB::easysocial()->exists()) { if (EB::easysocial()->isBlogAppInstalled('group')) { $contributeSQL .= $contributor::genAccessSQL(EASYBLOG_POST_SOURCE_EASYSOCIAL_GROUP, 'a'); } if (EB::easysocial()->isBlogAppInstalled('page')) { $contributeSQL .= $contributor::genAccessSQL(EASYBLOG_POST_SOURCE_EASYSOCIAL_PAGE, 'a'); } if (EB::easysocial()->isBlogAppInstalled('event')) { $contributeSQL .= $contributor::genAccessSQL(EASYBLOG_POST_SOURCE_EASYSOCIAL_EVENT, 'a'); } } $contributeSQL .= ')'; $queryWhere .= $contributeSQL; // category access here $config = EB::config(); if ($config->get('main_category_privacy')) { $catLib = EB::category(); $catAccessSQL = $catLib->genAccessSQL('a.`id`'); $queryWhere .= ' AND (' . $catAccessSQL . ')'; } // Comment out this sorted by score (title, intro and content), if the search query match with the blog title, it will put the high score. #2486 // $query = 'SELECT * from ('; // $query .= 'SELECT a.*, CONCAT(a.`content`, a.`intro`) AS text, "2" as browsernav,'; // $textquery = $db->Quote('%'.$db->getEscaped($text, true).'%', false); // $caseQuery = '((CASE WHEN a.`title` = ' . $db->Quote($text) . ' THEN 4 ELSE 0 END) + (CASE WHEN a.`title` LIKE ' . $textquery . ' THEN 3 ELSE 0 END)'; // $caseQuery .= ' + (CASE WHEN a.`content` LIKE ' . $textquery . ' THEN 2 ELSE 0 END) + (CASE WHEN a.`intro` LIKE ' . $textquery . ' THEN 2 ELSE 0 END)) as score'; // $query .= $caseQuery; $query = 'SELECT a.*, CONCAT(a.`content` , a.`intro`) AS text , "2" as browsernav'; $query .= ' FROM `#__easyblog_post` as a USE INDEX (`easyblog_post_searchnew`) '; $query .= ' WHERE (' . $where; $query .= ' OR a.`id` IN( '; $query .= ' SELECT tp.`post_id` FROM `#__easyblog_tag` AS t '; $query .= ' INNER JOIN `#__easyblog_post_tag` AS tp ON tp.`tag_id` = t.`id` '; $query .= ' WHERE ' . $where2; $query .= '))'; // Guests should only see public post. if ($this->my->guest) { $query .= ' AND a.`access` = ' . $db->Quote('0'); } // Do not render unpublished posts $query .= ' AND a.' . $db->qn('published') . '=' . $db->Quote(EASYBLOG_POST_PUBLISHED); $query .= ' AND a.' . $db->qn('state') . '=' . $db->Quote(EASYBLOG_POST_NORMAL); // Filter by language. if (!FH::isFromAdmin() && $isSiteMultilingualEnabled) { $query .= ' AND a.' . $db->qn('language') . '=' . $db->Quote($languageTag); } $query .= $queryWhere; // Base on score result // $query .= ' ) as x'; if ($ordering == 'oldest') { // Base on score result // $query .= ' ORDER BY `score` ASC'; // $query .= ' ORDER BY x.`publish_up` ASC, x.`score` ASC'; $query .= ' ORDER BY a.`created` ASC'; } if ($ordering == 'newest') { // Base on score result // $query .= ' ORDER BY `score` DESC'; // $query .= ' ORDER BY x.`publish_up` DESC, x.`score` DESC'; $query .= ' ORDER BY a.`created` DESC'; } $db->setQuery($query); $result = $db->loadObjectList(); return $result; } /** * Checks an object content and see whether still contain those search term (after stripping blog content of HTML). * * @since 5.4.2 * @access public */ public function searchTermsExist($content, $searchTerms, $phrase = '') { if ($phrase != 'exact') { $searchTerms = explode(' ', $searchTerms); } $model = EB::model('Search'); $searchTermsExist = $model->searchTermsExist($content, $searchTerms, $phrase); return $searchTermsExist; } /** * Normalize the search term * * @since 5.4.3 * @access public */ public function normalizeTerms($terms) { $db = EB::db(); $badchars = array('#', '>', '<', '\\', '=', '(', ')', '*', ',', '.', '%', '\''); // Replace for those bad characters $terms = trim(str_replace($badchars, '', $terms)); // Ensure the terms convert to lowercase and support UTF-8 $terms = trim(EBString::strtolower($terms)); // Escapes a string for usage in an SQL statement $terms = $db->getEscaped($terms); return $terms; } } PK!Vsearch/easyblog/index.htmlnu[ PK!V66)media-action/resize/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\MediaAction\Resize\Extension\Resize; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Resize( $dispatcher, (array) PluginHelper::getPlugin('media-action', 'resize') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!ݦmedia-action/resize/resize.xmlnu[ plg_media-action_resize Joomla! Project 2017-01 (C) 2017 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.0.0 PLG_MEDIA-ACTION_RESIZE_XML_DESCRIPTION Joomla\Plugin\MediaAction\Resize form services src language/en-GB/plg_media-action_resize.ini language/en-GB/plg_media-action_resize.sys.ini
    PK!,Q!!,media-action/resize/src/Extension/Resize.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\MediaAction\Resize\Extension; use Joomla\CMS\Image\Image; use Joomla\Component\Media\Administrator\Plugin\MediaActionPlugin; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Media Manager Resize Action * * @since 4.0.0 */ final class Resize extends MediaActionPlugin { /** * The save event. * * @param string $context The context * @param object $item The item * @param boolean $isNew Is new item * @param array $data The validated data * * @return void * * @since 4.0.0 */ public function onContentBeforeSave($context, $item, $isNew, $data = []) { if ($context != 'com_media.file') { return; } if (!$this->params->get('batch_width') && !$this->params->get('batch_height')) { return; } if (!in_array($item->extension, ['jpg', 'jpeg', 'png', 'gif'])) { return; } $imgObject = new Image(imagecreatefromstring($item->data)); if ($imgObject->getWidth() < $this->params->get('batch_width', 0) && $imgObject->getHeight() < $this->params->get('batch_height', 0)) { return; } $imgObject->resize( $this->params->get('batch_width', 0), $this->params->get('batch_height', 0), false, Image::SCALE_INSIDE ); $type = IMAGETYPE_JPEG; switch ($item->extension) { case 'gif': $type = IMAGETYPE_GIF; break; case 'png': $type = IMAGETYPE_PNG; } ob_start(); $imgObject->toFile(null, $type); $item->data = ob_get_contents(); ob_end_clean(); } } PK!HAA#media-action/resize/form/resize.xmlnu[
    PK!X66)media-action/rotate/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\MediaAction\Rotate\Extension\Rotate; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Rotate( $dispatcher, (array) PluginHelper::getPlugin('media-action', 'rotate') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!\0Amedia-action/rotate/rotate.xmlnu[ plg_media-action_rotate Joomla! Project 2017-01 (C) 2017 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.0.0 PLG_MEDIA-ACTION_ROTATE_XML_DESCRIPTION Joomla\Plugin\MediaAction\Rotate form services src language/en-GB/plg_media-action_rotate.ini language/en-GB/plg_media-action_rotate.sys.ini PK!a`BB,media-action/rotate/src/Extension/Rotate.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\MediaAction\Rotate\Extension; use Joomla\Component\Media\Administrator\Plugin\MediaActionPlugin; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Media Manager Rotate Action * * @since 4.0.0 */ final class Rotate extends MediaActionPlugin { } PK!4XX#media-action/rotate/form/rotate.xmlnu[
    PK!H*media-action/crop/crop.xmlnu[ plg_media-action_crop Joomla! Project 2017-01 (C) 2017 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 4.0.0 PLG_MEDIA-ACTION_CROP_XML_DESCRIPTION Joomla\Plugin\MediaAction\Crop form services src language/en-GB/plg_media-action_crop.ini language/en-GB/plg_media-action_crop.sys.ini PK!6,,'media-action/crop/services/provider.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Joomla\Plugin\MediaAction\Crop\Extension\Crop; return new class () implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * * @param Container $container The DI container. * * @return void * * @since 4.4.0 */ public function register(Container $container): void { $container->set( PluginInterface::class, function (Container $container) { $dispatcher = $container->get(DispatcherInterface::class); $plugin = new Crop( $dispatcher, (array) PluginHelper::getPlugin('media-action', 'crop') ); $plugin->setApplication(Factory::getApplication()); return $plugin; } ); } }; PK!}(media-action/crop/src/Extension/Crop.phpnu[ * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\MediaAction\Crop\Extension; use Joomla\CMS\Application\CMSWebApplicationInterface; use Joomla\Component\Media\Administrator\Plugin\MediaActionPlugin; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Media Manager Crop Action * * @since 4.0.0 */ final class Crop extends MediaActionPlugin { /** * Load the javascript files of the plugin. * * @return void * * @since 4.0.0 */ protected function loadJs() { parent::loadJs(); if (!$this->getApplication() instanceof CMSWebApplicationInterface) { return; } $this->getApplication()->getDocument()->getWebAssetManager()->useScript('cropperjs'); } /** * Load the CSS files of the plugin. * * @return void * * @since 4.0.0 */ protected function loadCss() { parent::loadCss(); if (!$this->getApplication() instanceof CMSWebApplicationInterface) { return; } $this->getApplication()->getDocument()->getWebAssetManager()->useStyle('cropperjs'); } } PK!{ { media-action/crop/form/crop.xmlnu[
    PK!(vv(system/httpheaders/services/provider.phpnu[PK!*}9!!/system/httpheaders/postinstall/introduction.phpnu[PK! --"N system/httpheaders/httpheaders.xmlnu[PK!mW{<{<0J;system/httpheaders/src/Extension/Httpheaders.phpnu[PK!7{/,%%xsystem/remember/services/provider.phpnu[PK!YY!~system/remember/remember.xmlnu[PK!~[***Ɓsystem/remember/src/Extension/Remember.phpnu[PK!K44&Jsystem/highlight/services/provider.phpnu[PK!*e}ffԖsystem/highlight/highlight.xmlnu[PK!u&^^,system/highlight/src/Extension/Highlight.phpnu[PK!ƏrBsystem/stats/stats.xmlnu[PK!z:"|system/stats/services/provider.phpnu[PK!W%88 fsystem/stats/layouts/message.phpnu[PK!'system/stats/layouts/field/uniqueid.phpnu[PK!q^  #Csystem/stats/layouts/field/data.phpnu[PK!3-iisystem/stats/layouts/stats.phpnu[PK!BZDZD$Usystem/stats/src/Extension/Stats.phpnu[PK!933$system/stats/src/Field/DataField.phpnu[PK!\Jy-!system/stats/src/Field/AbstractStatsField.phpnu[PK!t8c(%system/stats/src/Field/UniqueidField.phpnu[PK!"?)system/log/log.xmlnu[PK! >.system/log/services/provider.phpnu[PK!j 3system/log/src/Extension/Log.phpnu[PK!OW iiB;system/nrframework/language/hu-HU/hu-HU.plg_system_nrframework.ininu[PK!uNBsystem/nrframework/language/ru-RU/ru-RU.plg_system_nrframework.ininu[PK!#ZZB3system/nrframework/language/ca-ES/ca-ES.plg_system_nrframework.ininu[PK!vSSB3system/nrframework/language/sl-SI/sl-SI.plg_system_nrframework.ininu[PK!gBsystem/nrframework/language/pt-BR/pt-BR.plg_system_nrframework.ininu[PK!6BMosystem/nrframework/language/bg-BG/bg-BG.plg_system_nrframework.ininu[PK!NN,BFsystem/nrframework/language/cs-CZ/cs-CZ.plg_system_nrframework.ininu[PK!Bsystem/nrframework/language/tr-TR/tr-TR.plg_system_nrframework.ininu[PK!w^ƠƠBsystem/nrframework/language/es-ES/es-ES.plg_system_nrframework.ininu[PK!,sRRB%system/nrframework/language/et-EE/et-EE.plg_system_nrframework.ininu[PK!șșBsystem/nrframework/language/fi-FI/fi-FI.plg_system_nrframework.ininu[PK!,ʗʗBWsystem/nrframework/language/en-GB/en-GB.plg_system_nrframework.ininu[PK![[„F/system/nrframework/language/en-GB/en-GB.plg_system_nrframework.sys.ininu[PK!:fῠB)system/nrframework/language/pt-PT/pt-PT.plg_system_nrframework.ininu[PK!7=9BZ system/nrframework/language/sv-SE/sv-SE.plg_system_nrframework.ininu[PK!.foHHBV- system/nrframework/language/nl-NL/nl-NL.plg_system_nrframework.ininu[PK! ouLLB system/nrframework/language/uk-UA/uk-UA.plg_system_nrframework.ininu[PK!] B΅ system/nrframework/language/fr-FR/fr-FR.plg_system_nrframework.ininu[PK!X:YO~~B, system/nrframework/language/fa-IR/fa-IR.plg_system_nrframework.ininu[PK!88B system/nrframework/language/el-GR/el-GR.plg_system_nrframework.ininu[PK!)ЩBzk system/nrframework/language/de-DE/de-DE.plg_system_nrframework.ininu[PK!8PɡɡBysystem/nrframework/language/it-IT/it-IT.plg_system_nrframework.ininu[PK!2G%system/nrframework/fields/ajaxify.phpnu[PK!Fu#system/nrframework/fields/users.phpnu[PK!HBB.system/nrframework/fields/nrdjcfcategories.phpnu[PK![J!system/nrframework/fields/geo.phpnu[PK!uK 2system/nrframework/fields/nrhikashopcategories.phpnu[PK!l  1system/nrframework/fields/nrjeventscategories.phpnu[PK!6Csystem/nrframework/fields/nreventbookingcategories.phpnu[PK!YY'>system/nrframework/fields/smarttags.phpnu[PK!F%system/nrframework/fields/modules.phpnu[PK!F "Ssystem/nrframework/fields/rate.phpnu[PK!g֦&1 system/nrframework/fields/freetext.phpnu[PK!B49 9 *-system/nrframework/fields/geodbchecker.phpnu[PK!?[ H H "system/nrframework/fields/time.phpnu[PK!m+Z&system/nrframework/fields/rulevaluehint.phpnu[PK!̺")system/nrframework/fields/nrk2.phpnu[PK!Yt79system/nrframework/fields/nrsppagebuildercategories.phpnu[PK!EE-h>system/nrframework/fields/nrzoocategories.phpnu[PK! " Csystem/nrframework/fields/well.phpnu[PK!sh'Msystem/nrframework/fields/nrmodules.phpnu[PK!zJ&Rsystem/nrframework/fields/nrnumber.phpnu[PK!*W^"QWsystem/nrframework/fields/nros.phpnu[PK!f=F331[system/nrframework/fields/nrgridboxcategories.phpnu[PK!r@4,`system/nrframework/fields/nrdjcatalog2categories.phpnu[PK!tF (dsystem/nrframework/fields/treeselect.phpnu[PK! &rsystem/nrframework/fields/nrtoggle.phpnu[PK!fS%zz(zsystem/nrframework/fields/akeebasubs.phpnu[PK!ibb3system/nrframework/fields/nrjshoppingcategories.phpnu[PK! ~^^&system/nrframework/fields/nrdevice.phpnu[PK!+3̼(bsystem/nrframework/fields/comparator.phpnu[PK!Yj  1vsystem/nrframework/fields/nrjcalprocategories.phpnu[PK!*ii5system/nrframework/fields/jshoppingcomponentitems.phpnu[PK!Gn "system/nrframework/fields/gmap.phpnu[PK! KAA&system/nrframework/fields/password.phpnu[PK!eѮ08system/nrframework/fields/nrrsblogcategories.phpnu[PK!?ѻ<<1system/nrframework/fields/nrsobiprocategories.phpnu[PK!j:%5system/nrframework/fields/nrfonts.phpnu[PK!:*system/nrframework/fields/nrgrouplevel.phpnu[PK!,X -system/nrframework/fields/tfinputrepeater.phpnu[PK!``1@system/nrframework/fields/assignmentselection.phpnu[PK!C H1system/nrframework/fields/nrresponsivecontrol.phpnu[PK!o>((system/nrframework/fields/currencies.phpnu[PK!f6wsystem/nrframework/fields/virtuemartcomponentitems.phpnu[PK!J]/|system/nrframework/fields/nreshopcategories.phpnu[PK!!<u system/nrframework/fields/nrjbusinessdirectorycategories.phpnu[PK!\[ (system/nrframework/fields/acymailing.phpnu[PK!4system/nrframework/fields/nrvirtuemartcategories.phpnu[PK!# system/nrframework/fields/nrurl.phpnu[PK!DYU``$&system/nrframework/fields/inline.phpnu[PK! **system/nrframework/fields/smarttagsbox.phpnu[PK!8*8system/nrframework/fields/nrconditions.phpnu[PK!='Ksystem/nrframework/fields/nrbrowser.phpnu[PK! $xOsystem/nrframework/fields/nrtext.phpnu[PK!]<2Zsystem/nrframework/fields/nreasyblogcategories.phpnu[PK!jȻ]%^system/nrframework/fields/content.phpnu[PK!;r, , .fsystem/nrframework/fields/nrimagesselector.phpnu[PK!,BCC2qsystem/nrframework/fields/nrdjeventscategories.phpnu[PK!YY*+usystem/nrframework/fields/nrcomponents.phpnu[PK!a#ބsystem/nrframework/fields/block.phpnu[PK!K"K[A A .ōsystem/nrframework/fields/conditionbuilder.phpnu[PK!n/dsystem/nrframework/fields/nrmodulepositions.phpnu[PK!~_rr,ssystem/nrframework/fields/componentitems.phpnu[PK!+& )Asystem/nrframework/fields/nrmenuitems.phpnu[PK!2Dss!~system/nrframework/fields/pro.phpnu[PK!\L+|9|9,Bsystem/nrframework/script.install.helper.phpnu[PK!5system/nrframework/layouts/conditionbuilder_group.phpnu[PK!:??6system/nrframework/layouts/responsive_control_item.phpnu[PK!>9771<system/nrframework/layouts/outdated_extension.phpnu[PK!qž1system/nrframework/layouts/responsive_control.phpnu[PK! #5 system/nrframework/layouts/well.phpnu[PK!||-G$system/nrframework/layouts/imagesselector.phpnu[PK!)k, )system/nrframework/layouts/updatechecker.phpnu[PK!p2+0system/nrframework/layouts/smarttagsbox.phpnu[PK!NO O 3H3system/nrframework/layouts/conditionbuilder_row.phpnu[PK!U̱YY+<system/nrframework/layouts/proonlymodal.phpnu[PK!e/Lsystem/nrframework/layouts/conditionbuilder.phpnu[PK! :&&='Usystem/nrframework/layouts/widgets/gallerymanager/default.phpnu[PK!u5v|system/nrframework/layouts/widgets/rating/default.phpnu[PK!-:system/nrframework/layouts/widgets/colorpicker/default.phpnu[PK!~u u <"system/nrframework/layouts/widgets/openstreetmap/default.phpnu[PK!!3Ksystem/nrframework/helpers/wrappers/getresponse.phpnu[PK!!48system/nrframework/helpers/wrappers/elasticemail.phpnu[PK!5V%1' system/nrframework/helpers/wrappers/mailchimp.phpnu[PK![.0"system/nrframework/helpers/wrappers/icontact.phpnu[PK!;7#system/nrframework/helpers/wrappers/constantcontact.phpnu[PK!kى2%system/nrframework/helpers/wrappers/salesforce.phpnu[PK!VÆ/'system/nrframework/helpers/wrappers/zohocrm.phpnu[PK!E2)system/nrframework/helpers/wrappers/sendinblue.phpnu[PK!G*6+system/nrframework/helpers/wrappers/activecampaign.phpnu[PK!g认/-system/nrframework/helpers/wrappers/hubspot.phpnu[PK!hLZ Z $/system/nrframework/helpers/field.phpnu[PK!D看(-:system/nrframework/helpers/fieldlist.phpnu[PK!kˋ==4@system/nrframework/helpers/vendors/Mobile_Detect.phpnu[PK!tU+q~system/nrframework/NRFramework/Executer.phpnu[PK!A_}::(system/nrframework/NRFramework/Mimes.phpnu[PK! )Q Q &system/nrframework/NRFramework/URL.phpnu[PK!nY.Y..system/nrframework/NRFramework/Assignments.phpnu[PK!7 /| system/nrframework/NRFramework/VisitorToken.phpnu[PK!F 8system/nrframework/NRFramework/Widgets/OpenStreetMap.phpnu[PK!3z46%system/nrframework/NRFramework/Widgets/ColorPicker.phpnu[PK!}#xx4(system/nrframework/NRFramework/Widgets/Countdown.phpnu[PK!L4^4^2uDsystem/nrframework/NRFramework/Widgets/Gallery.phpnu[PK!uff6 system/nrframework/NRFramework/Widgets/RangeSlider.phpnu[PK!j 'שsystem/nrframework/NRFramework/File.phpnu[PK!˅,system/nrframework/NRFramework/SmartTags.phpnu[PK!']>system/nrframework/NRFramework/Conditions/ConditionsHelper.phpnu[PK!.΀@@Esystem/nrframework/NRFramework/Conditions/Conditions/ConvertForms.phpnu[PK!?>>?system/nrframework/NRFramework/Conditions/Conditions/Device.phpnu[PK! R  <2system/nrframework/NRFramework/Conditions/Conditions/URL.phpnu[PK!VCsystem/nrframework/NRFramework/Conditions/Conditions/AkeebaSubs.phpnu[PK!\llBsystem/nrframework/NRFramework/Conditions/Conditions/Pageviews.phpnu[PK!&CC@system/nrframework/NRFramework/Conditions/Conditions/URLBase.phpnu[PK!Ea^^IHsystem/nrframework/NRFramework/Conditions/Conditions/Joomla/Component.phpnu[PK!Dsystem/nrframework/NRFramework/Conditions/Conditions/Joomla/Menu.phpnu[PK!Ԯ3 HD system/nrframework/NRFramework/Conditions/Conditions/Joomla/Language.phpnu[PK!yKna((Ffsystem/nrframework/NRFramework/Conditions/Conditions/Joomla/UserID.phpnu[PK!r쵗Isystem/nrframework/NRFramework/Conditions/Conditions/Joomla/UserGroup.phpnu[PK!cxKsystem/nrframework/NRFramework/Conditions/Conditions/Joomla/AccessLevel.phpnu[PK!^ooC1system/nrframework/NRFramework/Conditions/Conditions/TimeOnSite.phpnu[PK!99@#system/nrframework/NRFramework/Conditions/Conditions/Browser.phpnu[PK!Z;%system/nrframework/NRFramework/Conditions/Conditions/OS.phpnu[PK!! iR*system/nrframework/NRFramework/Conditions/Conditions/Component/JCalProCategory.phpnu[PK!NI-system/nrframework/NRFramework/Conditions/Conditions/Component/SobiProBase.phpnu[PK!бٍQ4system/nrframework/NRFramework/Conditions/Conditions/Component/EasyBlogSingle.phpnu[PK!? L7system/nrframework/NRFramework/Conditions/Conditions/Component/ZooSingle.phpnu[PK! WP:system/nrframework/NRFramework/Conditions/Conditions/Component/SobiProSingle.phpnu[PK!-33O=system/nrframework/NRFramework/Conditions/Conditions/Component/EasyBlogBase.phpnu[PK!qSBsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJEventsCategory.phpnu[PK!몙HEsystem/nrframework/NRFramework/Conditions/Conditions/Component/K2Tag.phpnu[PK! )<<OHsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJEventsBase.phpnu[PK!Ř..^LMsystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryEventBase.phpnu[PK!SA..^Ssystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryOfferBase.phpnu[PK!y )NXsystem/nrframework/NRFramework/Conditions/Conditions/Component/J2StoreBase.phpnu[PK!$#fVQ_system/nrframework/NRFramework/Conditions/Conditions/Component/SPPageBuilderSingle.phpnu[PK!ܙJnbsystem/nrframework/NRFramework/Conditions/Conditions/Component/ZooBase.phpnu[PK!Rfcisystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryBusinessSingle.phpnu[PK!*[*Qmsystem/nrframework/NRFramework/Conditions/Conditions/Component/RSBlogCategory.phpnu[PK! Mosystem/nrframework/NRFramework/Conditions/Conditions/Component/K2Pagetype.phpnu[PK!$>66T3ssystem/nrframework/NRFramework/Conditions/Conditions/Component/SPPageBuilderBase.phpnu[PK!mUwsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJCatalog2Category.phpnu[PK!PAmTPzsystem/nrframework/NRFramework/Conditions/Conditions/Component/JShoppingBase.phpnu[PK!P݀system/nrframework/NRFramework/Conditions/Conditions/Component/GridboxSingle.phpnu[PK!EKsystem/nrframework/NRFramework/Conditions/Conditions/Component/QuixBase.phpnu[PK!"wmDDb~system/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryOfferCategory.phpnu[PK!\JJeTsystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryBusinessCategory.phpnu[PK!!ćO3system/nrframework/NRFramework/Conditions/Conditions/Component/HikashopBase.phpnu[PK!']ˍQ9system/nrframework/NRFramework/Conditions/Conditions/Component/HikashopSingle.phpnu[PK!/WGsystem/nrframework/NRFramework/Conditions/Conditions/Component/EventBookingCategory.phpnu[PK!6 nasystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryBusinessBase.phpnu[PK!—N5system/nrframework/NRFramework/Conditions/Conditions/Component/EshopSingle.phpnu[PK!~&`:system/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryOfferSingle.phpnu[PK!m)Rusystem/nrframework/NRFramework/Conditions/Conditions/Component/ContentCategory.phpnu[PK!<Ssystem/nrframework/NRFramework/Conditions/Conditions/Component/EasyBlogCategory.phpnu[PK!Qsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJEventsSingle.phpnu[PK!Msystem/nrframework/NRFramework/Conditions/Conditions/Component/QuixSingle.phpnu[PK!4.ZOsystem/nrframework/NRFramework/Conditions/Conditions/Component/RSBlogSingle.phpnu[PK!@Usystem/nrframework/NRFramework/Conditions/Conditions/Component/EventBookingSingle.phpnu[PK!+eiRsystem/nrframework/NRFramework/Conditions/Conditions/Component/JShoppingSingle.phpnu[PK!KPзsystem/nrframework/NRFramework/Conditions/Conditions/Component/ComponentBase.phpnu[PK!CmDDbFsystem/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryEventCategory.phpnu[PK!ɉqSsystem/nrframework/NRFramework/Conditions/Conditions/Component/VirtueMartSingle.phpnu[PK!":ĺM0system/nrframework/NRFramework/Conditions/Conditions/Component/K2Category.phpnu[PK!DSsystem/nrframework/NRFramework/Conditions/Conditions/Component/HikashopCategory.phpnu[PK!^TAwwY6system/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryBase.phpnu[PK!}22N6system/nrframework/NRFramework/Conditions/Conditions/Component/GridboxBase.phpnu[PK!aΑSsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJCatalog2Single.phpnu[PK!c$Vsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJClassifiedsSingle.phpnu[PK!DOOSsystem/nrframework/NRFramework/Conditions/Conditions/Component/EventBookingBase.phpnu[PK!vRsystem/nrframework/NRFramework/Conditions/Conditions/Component/GridboxCategory.phpnu[PK!`?cNsystem/nrframework/NRFramework/Conditions/Conditions/Component/ZooCategory.phpnu[PK!WPsystem/nrframework/NRFramework/Conditions/Conditions/Component/J2StoreSingle.phpnu[PK!Rsystem/nrframework/NRFramework/Conditions/Conditions/Component/J2StoreCategory.phpnu[PK!ͦ|88Msystem/nrframework/NRFramework/Conditions/Conditions/Component/RSBlogBase.phpnu[PK!n IBsystem/nrframework/NRFramework/Conditions/Conditions/Component/K2Base.phpnu[PK!hm##X system/nrframework/NRFramework/Conditions/Conditions/Component/DJClassifiedsCategory.phpnu[PK!אQKsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJCatalog2Base.phpnu[PK!XPsystem/nrframework/NRFramework/Conditions/Conditions/Component/EshopCategory.phpnu[PK!2rBBNDsystem/nrframework/NRFramework/Conditions/Conditions/Component/JCalProBase.phpnu[PK!q^__Nsystem/nrframework/NRFramework/Conditions/Conditions/Component/ContentView.phpnu[PK!T Z88Tsystem/nrframework/NRFramework/Conditions/Conditions/Component/DJClassifiedsBase.phpnu[PK! ~"P$system/nrframework/NRFramework/Conditions/Conditions/Component/JCalProSingle.phpnu[PK!.LHHHN'system/nrframework/NRFramework/Conditions/Conditions/Component/ContentBase.phpnu[PK!KZQn/system/nrframework/NRFramework/Conditions/Conditions/Component/ContentArticle.phpnu[PK!:]X2system/nrframework/NRFramework/Conditions/Conditions/Component/SPPageBuilderCategory.phpnu[PK!l7 IA5system/nrframework/NRFramework/Conditions/Conditions/Component/K2Item.phpnu[PK!͞׫`=system/nrframework/NRFramework/Conditions/Conditions/Component/JBusinessDirectoryEventSingle.phpnu[PK!sQ@system/nrframework/NRFramework/Conditions/Conditions/Component/VirtueMartBase.phpnu[PK!sҢ##TFsystem/nrframework/NRFramework/Conditions/Conditions/Component/JShoppingCategory.phpnu[PK!ACGGLKsystem/nrframework/NRFramework/Conditions/Conditions/Component/EshopBase.phpnu[PK!f RKPsystem/nrframework/NRFramework/Conditions/Conditions/Component/SobiProCategory.phpnu[PK!Jj88URsystem/nrframework/NRFramework/Conditions/Conditions/Component/VirtueMartCategory.phpnu[PK!'tBUsystem/nrframework/NRFramework/Conditions/Conditions/Date/Date.phpnu[PK!XF\system/nrframework/NRFramework/Conditions/Conditions/Date/DateBase.phpnu[PK!᮱/Aesystem/nrframework/NRFramework/Conditions/Conditions/Date/Day.phpnu[PK![8Clsystem/nrframework/NRFramework/Conditions/Conditions/Date/Month.phpnu[PK!%k!!Gosystem/nrframework/NRFramework/Conditions/Conditions/Date/Scheduler.phpnu[PK!M@B/system/nrframework/NRFramework/Conditions/Conditions/Date/Time.phpnu[PK!7uA`system/nrframework/NRFramework/Conditions/Conditions/Referrer.phpnu[PK!'Bsystem/nrframework/NRFramework/Conditions/Conditions/EngageBox.phpnu[PK!}7 7 CҔsystem/nrframework/NRFramework/Conditions/Conditions/AcyMailing.phpnu[PK!yk D|system/nrframework/NRFramework/Conditions/Conditions/Geo/GeoBase.phpnu[PK!^IKTTFsystem/nrframework/NRFramework/Conditions/Conditions/Geo/Continent.phpnu[PK! WAsystem/nrframework/NRFramework/Conditions/Conditions/Geo/City.phpnu[PK!WD system/nrframework/NRFramework/Conditions/Conditions/Geo/Country.phpnu[PK!Mp77Csystem/nrframework/NRFramework/Conditions/Conditions/Geo/Region.phpnu[PK!{{{?Bsystem/nrframework/NRFramework/Conditions/Conditions/Cookie.phpnu[PK!{IT T ;,system/nrframework/NRFramework/Conditions/Conditions/IP.phpnu[PK!N`<system/nrframework/NRFramework/Conditions/Conditions/PHP.phpnu[PK![~!~!7 system/nrframework/NRFramework/Conditions/Condition.phpnu[PK!E>6system/nrframework/NRFramework/Conditions/Migrator.phpnu[PK!Y~]-]-> system/nrframework/NRFramework/Conditions/ConditionBuilder.phpnu[PK!':system/nrframework/NRFramework/User.phpnu[PK!#UU-Csystem/nrframework/NRFramework/Continents.phpnu[PK!|~\3\3,uIsystem/nrframework/NRFramework/Extension.phpnu[PK!}3 ,-}system/nrframework/NRFramework/WebClient.phpnu[PK!H(system/nrframework/NRFramework/Fonts.phpnu[PK!7\*+system/nrframework/NRFramework/Factory.phpnu[PK!Y\ .system/nrframework/NRFramework/Updatesites.phpnu[PK!6system/nrframework/NRFramework/Rules/nrcoordinates.phpnu[PK!bNf/system/nrframework/NRFramework/Rules/nrdate.phpnu[PK!Cf f (system/nrframework/NRFramework/Cache.phpnu[PK!@ /Žsystem/nrframework/NRFramework/CacheManager.phpnu[PK!軼8||0system/nrframework/NRFramework/SmartTags/URL.phpnu[PK!y>EE6system/nrframework/NRFramework/SmartTags/SmartTags.phpnu[PK!41system/nrframework/NRFramework/SmartTags/User.phpnu[PK!*kGD4!system/nrframework/NRFramework/SmartTags/Article.phpnu[PK!|`--1&system/nrframework/NRFramework/SmartTags/Date.phpnu[PK!4GY:1+system/nrframework/NRFramework/SmartTags/Page.phpnu[PK!5y2system/nrframework/NRFramework/SmartTags/Language.phpnu[PK!OKK88system/nrframework/NRFramework/SmartTags/QueryString.phpnu[PK!YL0{<system/nrframework/NRFramework/SmartTags/Day.phpnu[PK!-((3>system/nrframework/NRFramework/SmartTags/Client.phpnu[PK!45_Csystem/nrframework/NRFramework/SmartTags/RandomID.phpnu[PK!sO2Esystem/nrframework/NRFramework/SmartTags/Month.phpnu[PK!_13Hsystem/nrframework/NRFramework/SmartTags/Year.phpnu[PK!9S 5Jsystem/nrframework/NRFramework/SmartTags/SmartTag.phpnu[PK!2``1Vsystem/nrframework/NRFramework/SmartTags/Site.phpnu[PK! (--5lZsystem/nrframework/NRFramework/SmartTags/Referrer.phpnu[PK!Ƙ݋1\system/nrframework/NRFramework/SmartTags/Time.phpnu[PK!е/c_system/nrframework/NRFramework/SmartTags/IP.phpnu[PK!*( :asystem/nrframework/NRFramework/Integrations/ConvertKit.phpnu[PK!d"";,psystem/nrframework/NRFramework/Integrations/Integration.phpnu[PK!ð?system/nrframework/NRFramework/Integrations/CampaignMonitor.phpnu[PK!@q*, , 9system/nrframework/NRFramework/Integrations/ReCaptcha.phpnu[PK!E3jTT:!system/nrframework/NRFramework/Integrations/Salesforce.phpnu[PK!0I< 8߶system/nrframework/NRFramework/Integrations/HCaptcha.phpnu[PK!?g*&*&>system/nrframework/NRFramework/Integrations/ActiveCampaign.phpnu[PK!"!!9system/nrframework/NRFramework/Integrations/MailChimp.phpnu[PK!/4 system/nrframework/NRFramework/Integrations/Zoho.phpnu[PK!9% ; system/nrframework/NRFramework/Integrations/SendInBlue3.phpnu[PK!7 "system/nrframework/NRFramework/Integrations/ZohoCRM.phpnu[PK!I942system/nrframework/NRFramework/Integrations/Drip.phpnu[PK!Q4kk;Nsystem/nrframework/NRFramework/Integrations/GetResponse.phpnu[PK!$o(/(/:system/nrframework/NRFramework/Helpers/Widgets/Gallery.phpnu[PK! 63Asystem/nrframework/NRFramework/Helpers/CustomField.phpnu[PK!\㎿,Esystem/nrframework/NRFramework/URLHelper.phpnu[PK!;aBB,`system/nrframework/NRFramework/Functions.phpnu[PK!ͷ(system/nrframework/NRFramework/Image.phpnu[PK!WHyy%system/nrframework/script.install.phpnu[PK!K GGиsystem/nrframework/autoload.phpnu[PK!:,"fsystem/nrframework/nrframework.xmlnu[PK!R"system/nrframework/nrframework.phpnu[PK!Y,$system/nrframework/xml/conditions/device.xmlnu[PK!`/system/nrframework/xml/conditions/engagebox.xmlnu[PK! fU02system/nrframework/xml/conditions/date/month.xmlnu[PK!::.Ssystem/nrframework/xml/conditions/date/day.xmlnu[PK!Ņ/system/nrframework/xml/conditions/date/date.xmlnu[PK!L/?system/nrframework/xml/conditions/date/time.xmlnu[PK!;)xsystem/nrframework/xml/conditions/php.xmlnu[PK!t,ss>system/nrframework/xml/conditions/component/contentarticle.xmlnu[PK!ovv:xsystem/nrframework/xml/conditions/component/k2pagetype.xmlnu[PK! ``;Xsystem/nrframework/xml/conditions/component/contentview.xmlnu[PK!JǓ?#system/nrframework/xml/conditions/component/contentcategory.xmlnu[PK! ii5% system/nrframework/xml/conditions/component/k2tag.xmlnu[PK!JX**6system/nrframework/xml/conditions/component/k2item.xmlnu[PK!:system/nrframework/xml/conditions/component/k2category.xmlnu[PK!ǕjRR0system/nrframework/xml/conditions/timeonsite.xmlnu[PK!V㥄JJ0]system/nrframework/xml/conditions/akeebasubs.xmlnu[PK!W.system/nrframework/xml/conditions/geo/city.xmlnu[PK!ιYY0 system/nrframework/xml/conditions/geo/region.xmlnu[PK!l1#system/nrframework/xml/conditions/geo/country.xmlnu[PK!=;3%system/nrframework/xml/conditions/geo/continent.xmlnu[PK!&N-K(system/nrframework/xml/conditions/browser.xmlnu[PK!k)K*system/nrframework/xml/conditions/url.xmlnu[PK!=72-system/nrframework/xml/conditions/convertforms.xmlnu[PK!/>ކ6/system/nrframework/xml/conditions/joomla/component.xmlnu[PK!Pxll61system/nrframework/xml/conditions/joomla/usergroup.xmlnu[PK!z&ĕ8h3system/nrframework/xml/conditions/joomla/accesslevel.xmlnu[PK!\J 73e5system/nrframework/xml/conditions/joomla/userid.xmlnu[PK!17system/nrframework/xml/conditions/joomla/menu.xmlnu[PK!dii5<system/nrframework/xml/conditions/joomla/language.xmlnu[PK!ؤ../>system/nrframework/xml/conditions/pageviews.xmlnu[PK!P(,Bsystem/nrframework/xml/conditions/ip.xmlnu[PK!d-ʃ( Esystem/nrframework/xml/conditions/os.xmlnu[PK!ނ.Fsystem/nrframework/xml/conditions/referrer.xmlnu[PK!**,Isystem/nrframework/xml/conditions/cookie.xmlnu[PK!'Dbb0hPsystem/nrframework/xml/conditions/acymailing.xmlnu[PK!M0*Rsystem/nrframework/xml/conditionbuilder/base.xmlnu[PK!OFZZ_Ssystem/debug/debug.xmlnu[PK!"lsystem/debug/services/provider.phpnu[PK!bY 3orsystem/debug/src/DataCollector/SessionCollector.phpnu[PK!Aum**;s~system/debug/src/DataCollector/LanguageStringsCollector.phpnu[PK!ff5 2system/debug/src/DataCollector/MemoryCollector.phpnu[PK!g6 :Fsystem/debug/src/DataCollector/LanguageErrorsCollector.phpnu[PK!FHu{{7?system/debug/src/DataCollector/RequestDataCollector.phpnu[PK!1||0!system/debug/src/DataCollector/UserCollector.phpnu[PK!oP  9system/debug/src/DataCollector/LanguageFilesCollector.phpnu[PK!vSS1~system/debug/src/DataCollector/QueryCollector.phpnu[PK!*^f`!`!32system/debug/src/DataCollector/ProfileCollector.phpnu[PK!d0system/debug/src/DataCollector/InfoCollector.phpnu[PK!øe: : "system/debug/src/DataFormatter.phpnu[PK! A6= = %&system/debug/src/JoomlaHttpDriver.phpnu[PK!)iZ Z *1system/debug/src/AbstractDataCollector.phpnu[PK!*\\$:system/debug/src/Extension/Debug.phpnu[PK!v(system/debug/src/Storage/FileStorage.phpnu[PK!OQ'system/debug/src/JavascriptRenderer.phpnu[PK!h/8system/updatenotification/services/provider.phpnu[PK!C9psystem/updatenotification/postinstall/updatecachetime.phpnu[PK!Eo44>system/updatenotification/src/Extension/UpdateNotification.phpnu[PK!)0system/updatenotification/updatenotification.xmlnu[PK!._"_" system/jchatlogin/jchatlogin.phpnu[PK!|r;||*M(system/jchatlogin/social/twitter/login.phpnu[PK!$>iiii*#Hsystem/jchatlogin/social/twitter/OAuth.phpnu[PK!V+system/jchatlogin/social/twitter/index.htmlnu[PK! 8`system/jchatlogin/social/facebook/fb_ca_chain_bundle.crtnu[PK! E88*system/jchatlogin/social/facebook/base.phpnu[PK!jR R /8Dsystem/jchatlogin/social/facebook/exception.phpnu[PK!T) ) .Nsystem/jchatlogin/social/facebook/facebook.phpnu[PK!k!!,pYsystem/jchatlogin/social/facebook/index.htmlnu[PK! 97 )Ysystem/jchatlogin/social/google/login.phpnu[PK!V* gsystem/jchatlogin/social/google/index.htmlnu[PK!b(gsystem/jchatlogin/social/google/user.phpnu[PK!#o,,#xsystem/jchatlogin/social/index.htmlnu[PK!J7(wysystem/jchatlogin/connectors/twitter.phpnu[PK!jaP'ґsystem/jchatlogin/connectors/google.phpnu[PK!25++*system/jchatlogin/connectors/connector.phpnu[PK!BvSS)0system/jchatlogin/connectors/facebook.phpnu[PK!k!!'system/jchatlogin/connectors/index.htmlnu[PK!#o,,Tsystem/jchatlogin/index.htmlnu[PK!Al7!! system/jchatlogin/jchatlogin.xmlnu[PK!Q))&=system/sppagebuilder/sppagebuilder.phpnu[PK!:&h system/sppagebuilder/assets/js/init.jsnu[PK!o,&= system/sppagebuilder/sppagebuilder.xmlnu[PK!5`CC) system/languagecode/services/provider.phpnu[PK!h$>" system/languagecode/languagecode.xmlnu[PK!߈82& system/languagecode/src/Extension/LanguageCode.phpnu[PK!ھ : system/tgeoip/tgeoip.phpnu[PK!P 8F system/tgeoip/language/en-GB/en-GB.plg_system_tgeoip.ininu[PK!Ю<T system/tgeoip/language/en-GB/en-GB.plg_system_tgeoip.sys.ininu[PK!1Lt!system/tgeoip/vendor/geoip2/geoip2/src/Exception/AuthenticationException.phpnu[PK!)D!system/tgeoip/vendor/geoip2/geoip2/src/Exception/GeoIp2Exception.phpnu[PK!ŴLw !system/tgeoip/vendor/geoip2/geoip2/src/Exception/InvalidRequestException.phpnu[PK!SwM !system/tgeoip/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.phpnu[PK!HX$B !system/tgeoip/vendor/geoip2/geoip2/src/Exception/HttpException.phpnu[PK!Գ(g g :%!system/tgeoip/vendor/geoip2/geoip2/src/Database/Reader.phpnu[PK!x</!system/tgeoip/vendor/geoip2/geoip2/src/Model/AnonymousIp.phpnu[PK!9D?"6!system/tgeoip/vendor/geoip2/geoip2/src/Model/ConnectionType.phpnu[PK! ??5w9!system/tgeoip/vendor/geoip2/geoip2/src/Model/City.phpnu[PK!{A;J!system/tgeoip/vendor/geoip2/geoip2/src/Model/Enterprise.phpnu[PK!WtHH4qS!system/tgeoip/vendor/geoip2/geoip2/src/Model/Isp.phpnu[PK!~1k22>Y!system/tgeoip/vendor/geoip2/geoip2/src/Model/AbstractModel.phpnu[PK!@v v 8]!system/tgeoip/vendor/geoip2/geoip2/src/Model/Country.phpnu[PK!xPX7g!system/tgeoip/vendor/geoip2/geoip2/src/Model/Domain.phpnu[PK!1~9j!system/tgeoip/vendor/geoip2/geoip2/src/Model/Insights.phpnu[PK!9uBt!system/tgeoip/vendor/geoip2/geoip2/src/Compat/JsonSerializable.phpnu[PK!X`09v!system/tgeoip/vendor/geoip2/geoip2/src/Record/MaxMind.phpnu[PK!55;x!system/tgeoip/vendor/geoip2/geoip2/src/Record/Continent.phpnu[PK!j""6-}!system/tgeoip/vendor/geoip2/geoip2/src/Record/City.phpnu[PK!pN8!system/tgeoip/vendor/geoip2/geoip2/src/Record/Traits.phpnu[PK!X1<<9!system/tgeoip/vendor/geoip2/geoip2/src/Record/Country.phpnu[PK!ˇ/}=S!system/tgeoip/vendor/geoip2/geoip2/src/Record/Subdivision.phpnu[PK!A2ArrE!system/tgeoip/vendor/geoip2/geoip2/src/Record/AbstractPlaceRecord.phpnu[PK! SD!system/tgeoip/vendor/geoip2/geoip2/src/Record/RepresentedCountry.phpnu[PK!~^^:!system/tgeoip/vendor/geoip2/geoip2/src/Record/Location.phpnu[PK!:0KK8H!system/tgeoip/vendor/geoip2/geoip2/src/Record/Postal.phpnu[PK!>(..@!system/tgeoip/vendor/geoip2/geoip2/src/Record/AbstractRecord.phpnu[PK!OK<!system/tgeoip/vendor/geoip2/geoip2/src/ProviderInterface.phpnu[PK!{aP&P&<!system/tgeoip/vendor/geoip2/geoip2/src/WebService/Client.phpnu[PK!Ȝqq5!system/tgeoip/vendor/splitbrain/php-archive/README.mdnu[PK!A*9u!system/tgeoip/vendor/splitbrain/php-archive/composer.jsonnu[PK!C݇7x!system/tgeoip/vendor/splitbrain/php-archive/.travis.ymlnu[PK!^7f!system/tgeoip/vendor/splitbrain/php-archive/phpunit.xmlnu[PK!zjI;!system/tgeoip/vendor/splitbrain/php-archive/src/Archive.phpnu[PK!ڠquuF( "system/tgeoip/vendor/splitbrain/php-archive/src/ArchiveIOException.phpnu[PK!԰&DV "system/tgeoip/vendor/splitbrain/php-archive/src/ArchiveIllegalCompressionException.phpnu[PK!Jee<> "system/tgeoip/vendor/splitbrain/php-archive/src/FileInfo.phpnu[PK! 7[[7("system/tgeoip/vendor/splitbrain/php-archive/src/Tar.phpnu[PK!|NzzE"system/tgeoip/vendor/splitbrain/php-archive/src/FileInfoException.phpnu[PK!Ue#system/tgeoip/vendor/maxmind-db/reader/ext/tests/001-load.phptnu[PK!\h 3f#system/tgeoip/vendor/maxmind-db/reader/CHANGELOG.mdnu[PK!Ga''@r#system/tgeoip/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.phpnu[PK!ϞY#system/tgeoip/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.phpnu[PK!e$wREś#system/tgeoip/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Util.phpnu[PK!p'p""H'#system/tgeoip/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.phpnu[PK!Pܠ< < IA#system/tgeoip/vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Metadata.phpnu[PK!O-9#system/tgeoip/vendor/maxmind/web-service-common/README.mdnu[PK!yrr=g#system/tgeoip/vendor/maxmind/web-service-common/composer.jsonnu[PK!wW<F#system/tgeoip/vendor/maxmind/web-service-common/CHANGELOG.mdnu[PK!S^]{#system/tgeoip/vendor/maxmind/web-service-common/src/Exception/PermissionRequiredException.phpnu[PK!*BY#system/tgeoip/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.phpnu[PK!EU#system/tgeoip/vendor/maxmind/web-service-common/src/Exception/WebServiceException.phpnu[PK! Y #system/tgeoip/vendor/maxmind/web-service-common/src/Exception/InvalidRequestException.phpnu[PK!þ ''W(#system/tgeoip/vendor/maxmind/web-service-common/src/Exception/InvalidInputException.phpnu[PK!8s\#system/tgeoip/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.phpnu[PK!cjj\#system/tgeoip/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.phpnu[PK!cRRO#system/tgeoip/vendor/maxmind/web-service-common/src/Exception/HttpException.phpnu[PK!Y(-V#system/tgeoip/vendor/maxmind/web-service-common/src/WebService/Http/RequestFactory.phpnu[PK!IVO#system/tgeoip/vendor/maxmind/web-service-common/src/WebService/Http/Request.phpnu[PK!~ S#system/tgeoip/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.phpnu[PK!ᬇ5::IL#system/tgeoip/vendor/maxmind/web-service-common/src/WebService/Client.phpnu[PK!C!6$system/tgeoip/vendor/autoload.phpnu[PK!L/7$system/tgeoip/vendor/composer/autoload_psr4.phpnu[PK!Ti$II1$:$system/tgeoip/vendor/composer/autoload_static.phpnu[PK!b3@$system/tgeoip/vendor/composer/autoload_classmap.phpnu[PK!z44-A$system/tgeoip/vendor/composer/ClassLoader.phpnu[PK!Agի1v$system/tgeoip/vendor/composer/ca-bundle/README.mdnu[PK!C;5}$system/tgeoip/vendor/composer/ca-bundle/composer.jsonnu[PK!ps558q$system/tgeoip/vendor/composer/ca-bundle/src/CaBundle.phpnu[PK!]61E E 6$system/tgeoip/vendor/composer/ca-bundle/res/cacert.pemnu[PK!"",(system/tgeoip/vendor/composer/installed.jsonnu[PK!`/(system/tgeoip/vendor/composer/autoload_real.phpnu[PK!t!ו5(system/tgeoip/vendor/composer/autoload_namespaces.phpnu[PK!S@!! (system/tgeoip/script.install.phpnu[PK!ı'5(system/tgeoip/tgeoip.xmlnu[PK!PF11m(system/tgeoip/helper/tgeoip.phpnu[PK!@@#+)system/tgeoip/helper/fakebcmath.phpnu[PK!9#TTh=)system/fields/fields.xmlnu[PK!2*Ʀ#A)system/fields/services/provider.phpnu[PK!pֈo8o8&F)system/fields/src/Extension/Fields.phpnu[PK!A%)system/redirect/services/provider.phpnu[PK!//)system/redirect/redirect.xmlnu[PK!%|$$*9)system/redirect/src/Extension/Redirect.phpnu[PK!.!)system/redirect/form/excludes.xmlnu[PK!TT@b)system/helixultimate/language/en-GB.plg_system_helixultimate.ininu[PK!-ڜܠ( *system/helixultimate/params/megamenu.xmlnu[PK!,*system/helixultimate/params/blog-options.xmlnu[PK!-8*system/helixultimate/overrides/plg_content_vote/vote.phpnu[PK!-:*system/helixultimate/overrides/plg_content_vote/rating.phpnu[PK!a*>g*system/helixultimate/overrides/com_tags/tags/default_items.phpnu[PK!R5!82*system/helixultimate/overrides/com_tags/tags/default.phpnu[PK!m& & 48*system/helixultimate/overrides/com_tags/tag/list.phpnu[PK!k=7B*system/helixultimate/overrides/com_tags/tag/default_items.phpnu[PK!׃D D 7PT*system/helixultimate/overrides/com_tags/tag/default.phpnu[PK!}:_*system/helixultimate/overrides/com_tags/tag/list_items.phpnu[PK!>3=u*system/helixultimate/overrides/mod_menu/default_component.phpnu[PK!q36|*system/helixultimate/overrides/mod_menu/default.phpnu[PK!@/ۀ$$;l*system/helixultimate/overrides/mod_menu/default_heading.phpnu[PK!w=*system/helixultimate/overrides/mod_menu/default_separator.phpnu[PK!sa7]*system/helixultimate/overrides/mod_menu/default_url.phpnu[PK!ʒuܑ**system/helixultimate/overrides/modules.phpnu[PK!F5*system/helixultimate/overrides/mod_search/default.phpnu[PK! {w<*system/helixultimate/overrides/com_finder/search/default.phpnu[PK!3='ffD*system/helixultimate/overrides/com_finder/search/default_results.phpnu[PK!M0``A*system/helixultimate/overrides/com_finder/search/default_form.phpnu[PK!VVCY*system/helixultimate/overrides/com_finder/search/default_result.phpnu[PK!@~ <"*system/helixultimate/overrides/layouts/joomla/modal/main.phpnu[PK!ZJ J @!*system/helixultimate/overrides/layouts/joomla/system/message.phpnu[PK!B+system/helixultimate/overrides/layouts/joomla/links/groupsopen.phpnu[PK!XT&&Fi+system/helixultimate/overrides/layouts/joomla/links/groupseparator.phpnu[PK!NqH{A +system/helixultimate/overrides/layouts/joomla/links/groupopen.phpnu[PK!CC< +system/helixultimate/overrides/layouts/joomla/links/groupsclose.phpnu[PK!o/pB +system/helixultimate/overrides/layouts/joomla/links/groupclose.phpnu[PK!Z<.+system/helixultimate/overrides/layouts/joomla/links/link.phpnu[PK! ]GA+system/helixultimate/overrides/layouts/joomla/pagination/list.phpnu[PK!u u B+system/helixultimate/overrides/layouts/joomla/pagination/links.phpnu[PK!Ի A!+system/helixultimate/overrides/layouts/joomla/pagination/link.phpnu[PK!ݰCA0-+system/helixultimate/overrides/layouts/joomla/edit/item_title.phpnu[PK!ɽ! ! K/+system/helixultimate/overrides/layouts/joomla/edit/frontediting_modules.phpnu[PK!FIe?5;+system/helixultimate/overrides/layouts/joomla/edit/fieldset.phpnu[PK!xEQ@+system/helixultimate/overrides/layouts/joomla/edit/publishingdata.phpnu[PK!IN">zD+system/helixultimate/overrides/layouts/joomla/edit/details.phpnu[PK!"BL+system/helixultimate/overrides/layouts/joomla/edit/title_alias.phpnu[PK!+JCN+system/helixultimate/overrides/layouts/joomla/edit/associations.phpnu[PK!f=`S+system/helixultimate/overrides/layouts/joomla/edit/global.phpnu[PK!O1__=Y+system/helixultimate/overrides/layouts/joomla/edit/params.phpnu[PK!;;?Xh+system/helixultimate/overrides/layouts/joomla/edit/metadata.phpnu[PK!QjwkkAm+system/helixultimate/overrides/layouts/joomla/quickicons/icon.phpnu[PK!ruooBr+system/helixultimate/overrides/layouts/joomla/tinymce/textarea.phpnu[PK!F aaFx+system/helixultimate/overrides/layouts/joomla/tinymce/togglebutton.phpnu[PK!ymmH}+system/helixultimate/overrides/layouts/joomla/tinymce/buttons/button.phpnu[PK!)>{+system/helixultimate/overrides/layouts/joomla/toolbar/help.phpnu[PK!ljGee?+system/helixultimate/overrides/layouts/joomla/toolbar/apply.phpnu[PK!`<<I+system/helixultimate/overrides/layouts/joomla/toolbar/group/groupopen.phpnu[PK!',dH@+system/helixultimate/overrides/layouts/joomla/toolbar/group/groupmid.phpnu[PK!_J΋+system/helixultimate/overrides/layouts/joomla/toolbar/group/groupclose.phpnu[PK! D"{LL?X+system/helixultimate/overrides/layouts/joomla/toolbar/popup.phpnu[PK!!&G+system/helixultimate/overrides/layouts/joomla/toolbar/containeropen.phpnu[PK!vZ''>1+system/helixultimate/overrides/layouts/joomla/toolbar/base.phpnu[PK!))CƔ+system/helixultimate/overrides/layouts/joomla/toolbar/iconclass.phpnu[PK!yi@b+system/helixultimate/overrides/layouts/joomla/toolbar/slider.phpnu[PK!qggBR+system/helixultimate/overrides/layouts/joomla/toolbar/standard.phpnu[PK!?++system/helixultimate/overrides/layouts/joomla/toolbar/batch.phpnu[PK!CH+system/helixultimate/overrides/layouts/joomla/toolbar/containerclose.phpnu[PK!"A)+system/helixultimate/overrides/layouts/joomla/toolbar/confirm.phpnu[PK!?+system/helixultimate/overrides/layouts/joomla/toolbar/modal.phpnu[PK!߬%%>+system/helixultimate/overrides/layouts/joomla/toolbar/link.phpnu[PK!_``B+system/helixultimate/overrides/layouts/joomla/toolbar/versions.phpnu[PK!1C+system/helixultimate/overrides/layouts/joomla/toolbar/separator.phpnu[PK!)?]+system/helixultimate/overrides/layouts/joomla/toolbar/title.phpnu[PK! $E+system/helixultimate/overrides/layouts/joomla/content/intro_image.phpnu[PK!CfuuW+system/helixultimate/overrides/layouts/joomla/content/blog_style_default_item_title.phpnu[PK!n˓(B+system/helixultimate/overrides/layouts/joomla/content/language.phpnu[PK! HTY+system/helixultimate/overrides/layouts/joomla/content/info_block/parent_category.phpnu[PK!0M+system/helixultimate/overrides/layouts/joomla/content/info_block/category.phpnu[PK!F -ooP+system/helixultimate/overrides/layouts/joomla/content/info_block/modify_date.phpnu[PK!tEI+system/helixultimate/overrides/layouts/joomla/content/info_block/hits.phpnu[PK!8133Q+system/helixultimate/overrides/layouts/joomla/content/info_block/associations.phpnu[PK! .#44P+system/helixultimate/overrides/layouts/joomla/content/info_block/create_date.phpnu[PK!q+DDQh+system/helixultimate/overrides/layouts/joomla/content/info_block/publish_date.phpnu[PK!b99K-+system/helixultimate/overrides/layouts/joomla/content/info_block/author.phpnu[PK!FB,system/helixultimate/overrides/layouts/joomla/content/readmore.phpnu[PK!b9I/ ,system/helixultimate/overrides/layouts/joomla/content/options_default.phpnu[PK!j5ZAAJS,system/helixultimate/overrides/layouts/joomla/content/category_default.phpnu[PK!oD,system/helixultimate/overrides/layouts/joomla/content/full_image.phpnu[PK!B>|0,system/helixultimate/overrides/layouts/joomla/content/tags.phpnu[PK!6KL5,system/helixultimate/overrides/layouts/joomla/content/categories_default.phpnu[PK!KK@Q;,system/helixultimate/overrides/layouts/joomla/content/rating.phpnu[PK!7F @,system/helixultimate/overrides/layouts/joomla/content/text_filters.phpnu[PK!/CFE,system/helixultimate/overrides/layouts/joomla/content/icons/create.phpnu[PK!J : : C,system/helixultimate/overrides/layouts/joomla/form/field/hidden.phpnu[PK!LGٸBQ,system/helixultimate/overrides/layouts/joomla/form/field/media.phpnu[PK!Ÿ @,system/helixultimate/overrides/layouts/joomla/form/field/tel.phpnu[PK!  E -system/helixultimate/overrides/layouts/joomla/form/field/textarea.phpnu[PK!ya @5-system/helixultimate/overrides/layouts/joomla/form/field/url.phpnu[PK!},)K!-system/helixultimate/overrides/layouts/joomla/form/field/color/advanced.phpnu[PK!PhzC C I:3-system/helixultimate/overrides/layouts/joomla/form/field/color/simple.phpnu[PK!$``G@-system/helixultimate/overrides/layouts/joomla/form/field/radiobasic.phpnu[PK!VcAP-system/helixultimate/overrides/layouts/joomla/form/field/text.phpnu[PK!G+c-system/helixultimate/overrides/layouts/joomla/form/field/checkboxes.phpnu[PK!g, Cr-system/helixultimate/overrides/layouts/joomla/form/field/number.phpnu[PK!Ćc c E-system/helixultimate/overrides/layouts/joomla/form/field/password.phpnu[PK!;B-system/helixultimate/overrides/layouts/joomla/form/field/radio.phpnu[PK!ے B -system/helixultimate/overrides/layouts/joomla/form/field/range.phpnu[PK!8E-system/helixultimate/overrides/layouts/joomla/form/field/calendar.phpnu[PK!Ѽ[ [ B-system/helixultimate/overrides/layouts/joomla/form/field/email.phpnu[PK!x* Ho-system/helixultimate/overrides/layouts/joomla/form/field/moduleorder.phpnu[PK!Fc\ Kn-system/helixultimate/overrides/layouts/joomla/form/field/contenthistory.phpnu[PK!I B-system/helixultimate/overrides/layouts/joomla/form/field/meter.phpnu[PK!C8  A-system/helixultimate/overrides/layouts/joomla/form/field/file.phpnu[PK!-At-system/helixultimate/overrides/layouts/joomla/form/field/user.phpnu[PK!AB.system/helixultimate/overrides/layouts/joomla/form/renderlabel.phpnu[PK!NAB.system/helixultimate/overrides/layouts/joomla/form/renderfield.phpnu[PK!t5.system/helixultimate/overrides/layouts/comingsoon.phpnu[PK!^v--N>.system/helixultimate/overrides/layouts/libraries/html/bootstrap/modal/main.phpnu[PK!SZZGN.system/helixultimate/overrides/layouts/libraries/cms/html/bootstrap.phpnu[PK!A7S.system/helixultimate/overrides/layouts/libraries/cms/html/bootstrap/starttabset.phpnu[PK!;ӸTZ.system/helixultimate/overrides/layouts/libraries/cms/html/bootstrap/addtabscript.phpnu[PK!#RFQ.system/helixultimate/overrides/layouts/libraries/cms/html/bootstrap/endtabset.phpnu[PK! Nm.system/helixultimate/overrides/layouts/libraries/cms/html/bootstrap/endtab.phpnu[PK!BicQN.system/helixultimate/overrides/layouts/libraries/cms/html/bootstrap/addtab.phpnu[PK!z--;.system/helixultimate/overrides/layouts/chromes/sp_xhtml.phpnu[PK!۝m..J.system/helixultimate/overrides/layouts/plugins/user/profile/fields/dob.phpnu[PK!La  WĽ.system/helixultimate/overrides/layouts/plugins/editors/tinymce/field/tinymcebuilder.phpnu[PK!5t8SSbV.system/helixultimate/overrides/layouts/plugins/editors/tinymce/field/tinymcebuilder/setoptions.phpnu[PK!bJN;.system/helixultimate/overrides/layouts/com_contact/joomla/form/renderfield.phpnu[PK!H(e,,8.system/helixultimate/overrides/mod_languages/default.phpnu[PK!Yh-e.system/helixultimate/overrides/pagination.phpnu[PK!Yf:JwwBg.system/helixultimate/overrides/com_search/search/default_error.phpnu[PK!,_jj<P.system/helixultimate/overrides/com_search/search/default.phpnu[PK!10oEED&/system/helixultimate/overrides/com_search/search/default_results.phpnu[PK!T3 A/system/helixultimate/overrides/com_search/search/default_form.phpnu[PK!9l A/system/helixultimate/overrides/com_users/registration/default.phpnu[PK!s2B? /system/helixultimate/overrides/com_users/registration/complete.phpnu[PK!~g   C"/system/helixultimate/overrides/com_users/profile/default_custom.phpnu[PK!i\|9-/system/helixultimate/overrides/com_users/profile/edit.phpnu[PK! õ<cF/system/helixultimate/overrides/com_users/profile/default.phpnu[PK!((A]I/system/helixultimate/overrides/com_users/profile/default_core.phpnu[PK!*]CP/system/helixultimate/overrides/com_users/profile/default_params.phpnu[PK!BAA^^@)W/system/helixultimate/overrides/com_users/login/default_login.phpnu[PK!V:h/system/helixultimate/overrides/com_users/login/default.phpnu[PK!EM M A}k/system/helixultimate/overrides/com_users/login/default_logout.phpnu[PK!Xb:;u/system/helixultimate/overrides/com_users/reset/default.phpnu[PK!6:}/system/helixultimate/overrides/com_users/reset/confirm.phpnu[PK!;; /system/helixultimate/overrides/com_users/reset/complete.phpnu[PK!";{/system/helixultimate/overrides/com_users/remind/default.phpnu[PK!bCj:/system/helixultimate/overrides/mod_breadcrumbs/default.phpnu[PK!\6ihh>/system/helixultimate/overrides/mod_articles_latest/default.phpnu[PK!Z/ :/system/helixultimate/overrides/com_media/media/default.phpnu[PK!7  @/system/helixultimate/overrides/com_media/media/default_texts.phpnu[PK!w)uu40/system/helixultimate/overrides/mod_login/default.phpnu[PK!c  D /system/helixultimate/overrides/com_content/featured/default_item.phpnu[PK!h~ ?/system/helixultimate/overrides/com_content/featured/default.phpnu[PK!.O l66E/system/helixultimate/overrides/com_content/featured/default_links.phpnu[PK!vp^R&R&>}/system/helixultimate/overrides/com_content/article/default.phpnu[PK!NR# # D=0system/helixultimate/overrides/com_content/article/default_links.phpnu[PK!)1**G$0system/helixultimate/overrides/com_content/categories/default_items.phpnu[PK!6Au-0system/helixultimate/overrides/com_content/categories/default.phpnu[PK!}v.""D10system/helixultimate/overrides/com_content/archive/default_items.phpnu[PK!ӳx>T0system/helixultimate/overrides/com_content/archive/default.phpnu[PK!GGBF]0system/helixultimate/overrides/com_content/category/blog_links.phpnu[PK!ϩ%%<_0system/helixultimate/overrides/com_content/category/blog.phpnu[PK!ʐAw0system/helixultimate/overrides/com_content/category/blog_item.phpnu[PK!_pww?0system/helixultimate/overrides/com_content/category/default.phpnu[PK!2mG6G6Hx0system/helixultimate/overrides/com_content/category/default_articles.phpnu[PK!LH70system/helixultimate/overrides/com_content/category/default_children.phpnu[PK!- E0system/helixultimate/overrides/com_content/category/blog_children.phpnu[PK!2|#|#80system/helixultimate/overrides/com_content/form/edit.phpnu[PK!3ښG1system/helixultimate/overrides/com_contact/categories/default_items.phpnu[PK!*D!  A 1system/helixultimate/overrides/com_contact/categories/default.phpnu[PK!\F41system/helixultimate/overrides/com_contact/contact/default_address.phpnu[PK!I@@>T&1system/helixultimate/overrides/com_contact/contact/default.phpnu[PK!+0+Gf1system/helixultimate/overrides/com_contact/contact/default_articles.phpnu[PK!# yC/j1system/helixultimate/overrides/com_contact/contact/default_form.phpnu[PK!UDWq1system/helixultimate/overrides/com_contact/contact/default_links.phpnu[PK!nᔺ  "u1system/helixultimate/bootstrap.phpnu[PK!"Z\2pp"w1system/helixultimate/composer.jsonnu[PK!`*x1system/helixultimate/core/classes/menu.phpnu[PK!-v%BB+}1system/helixultimate/core/helixultimate.phpnu[PK!Oy'J1system/helixultimate/core/lib/fonts.phpnu[PK!99'1system/helixultimate/core/lib/icons.phpnu[PK!e##11system/helixultimate/core/lib/helixmenuhelper.phpnu[PK!{VW1'1system/helixultimate/fields/helixexportimport.phpnu[PK!%S.L1system/helixultimate/fields/helixdimension.phpnu[PK!c -q1system/helixultimate/fields/helixswitcher.phpnu[PK!aa0}1system/helixultimate/fields/helixmenubuilder.phpnu[PK!U# # ,2system/helixultimate/fields/helixgallery.phpnu[PK! ,82system/helixultimate/fields/helixpresets.phpnu[PK!J6kl *&+2system/helixultimate/fields/heliximage.phpnu[PK!+52system/helixultimate/fields/helixbutton.phpnu[PK!VV-<:2system/helixultimate/fields/helixmegamenu.phpnu[PK!` 11)T2system/helixultimate/fields/helixfont.phpnu[PK!D,62system/helixultimate/fields/helixdetails.phpnu[PK!MM+2system/helixultimate/fields/helixlayout.phpnu[PK!X*42system/helixultimate/fields/helixmedia.phpnu[PK!SIy.2system/helixultimate/fields/helixpositions.phpnu[PK!I2  ,P2system/helixultimate/fields/helixheaders.phpnu[PK!T՛,2system/helixultimate/fields/helixdevices.phpnu[PK!>)2system/helixultimate/fields/helixicon.phpnu[PK!d^12system/helixultimate/assets/css/system-j3.min.cssnu[PK!4RR12system/helixultimate/assets/css/system-j4.min.cssnu[PK!\V 1@2system/helixultimate/assets/css/frontend-edit.cssnu[PK! )72system/helixultimate/assets/css/admin/devices-field.cssnu[PK!ѯ12system/helixultimate/assets/css/admin/details.cssnu[PK!÷ִ..8K2system/helixultimate/assets/css/admin/menu.generator.cssnu[PK!%ۉll8g3system/helixultimate/assets/css/admin/helix-ultimate.cssnu[PK!b/;4system/helixultimate/assets/css/admin/modal.cssnu[PK!-x14system/helixultimate/assets/css/admin/toaster.cssnu[PK!z""0"4system/helixultimate/assets/css/admin/helper.cssnu[PK!z/m  654system/helixultimate/assets/css/admin/blog-options.cssnu[PK!p~00294system/helixultimate/assets/css/admin/megamenu.cssnu[PK!d6j4system/helixultimate/assets/css/admin/menu-builder.cssnu[PK!HL}L}7z4system/helixultimate/assets/css/admin/jquery-ui.min.cssnu[PK!iM A%%+g4system/helixultimate/assets/css/choices.cssnu[PK!<__1p5system/helixultimate/assets/css/bootstrap.min.cssnu[PK!9ct::3~7system/helixultimate/assets/css/frontend-editor.cssnu[PK!)]V(V(+7system/helixultimate/assets/css/icomoon.cssnu[PK!p/7system/helixultimate/assets/js/bootstrap.min.jsnu[PK!.8system/helixultimate/assets/js/admin/fields.jsnu[PK!書38system/helixultimate/assets/js/admin/menubuilder.jsnu[PK!=#I58system/helixultimate/assets/js/admin/jquery-ui.min.jsnu[PK!(^/%<system/helixultimate/assets/js/admin/webfont.jsnu[PK!i#77-C<system/helixultimate/assets/js/admin/modal.jsnu[PK!Yrr4<system/helixultimate/assets/js/admin/treeSortable.jsnu[PK!IV.u u /=system/helixultimate/assets/js/admin/toaster.jsnu[PK!Br-'=system/helixultimate/assets/js/admin/utils.jsnu[PK!F7+7+.t0=system/helixultimate/assets/js/admin/layout.jsnu[PK!:770 \=system/helixultimate/assets/js/admin/megamenu.jsnu[PK!TVKK6L=system/helixultimate/assets/js/admin/helix-ultimate.jsnu[PK!d~NN-E=system/helixultimate/assets/js/admin/media.jsnu[PK!`QQ6=system/helixultimate/assets/js/admin/menu.generator.jsnu[PK!f />system/helixultimate/assets/js/admin/presets.jsnu[PK!45&!>system/helixultimate/assets/js/admin/devices-field.jsnu[PK!z_L4$>system/helixultimate/assets/js/admin/blog-options.jsnu[PK!)r**/9>system/helixultimate/assets/js/admin/details.jsnu[PK!{0v;>system/helixultimate/assets/images/select-bg.svgnu[PK!d^:=>system/helixultimate/assets/images/helix-ultimate-logo.svgnu[PK!" .GS>system/helixultimate/assets/images/favicon.iconu[PK!.N /[>system/helixultimate/assets/images/icon-res.svgnu[PK!PU  >f>system/helixultimate/assets/images/helix-ultimate-logo-alt.svgnu[PK!1(ۣ 2'l>system/helixultimate/assets/images/icons/basic.svgnu[PK!52,w>system/helixultimate/assets/images/icons/close.svgnu[PK!y 4Lz>system/helixultimate/assets/images/icons/advance.svgnu[PK!11Q7>system/helixultimate/assets/images/icons/typography.svgnu[PK!v``1>system/helixultimate/assets/images/icons/blog.svgnu[PK!s)@@1>system/helixultimate/assets/images/icons/menu.svgnu[PK!h/4X>system/helixultimate/assets/images/icons/presets.svgnu[PK!Ņ1`>system/helixultimate/assets/images/icons/bars.svgnu[PK!1>system/helixultimate/assets/images/icons/save.svgnu[PK!y;!>system/helixultimate/assets/images/icons/device-desktop.svgnu[PK! UX<>system/helixultimate/assets/images/icons/image-thumbnail.svgnu[PK!y :#>system/helixultimate/assets/images/icons/licenseupdate.svgnu[PK!Q3>system/helixultimate/assets/images/icons/layout.svgnu[PK!4Ncc8>system/helixultimate/assets/images/icons/image-large.svgnu[PK!#bb:^>system/helixultimate/assets/images/icons/device-mobile.svgnu[PK!+;8*>system/helixultimate/assets/images/icons/custom_code.svgnu[PK! EE:>system/helixultimate/assets/images/icons/device-tablet.svgnu[PK!y 5?>system/helixultimate/assets/images/icons/advanced.svgnu[PK!\9?system/helixultimate/assets/images/icons/image-medium.svgnu[PK!x8%?system/helixultimate/assets/images/icons/image-small.svgnu[PK!KZ4 ?system/helixultimate/assets/images/select-bg-rtl.svgnu[PK!}= ?system/helixultimate/assets/images/mega-menu-color-select.jpgnu[PK!(Ii>>>?system/helixultimate/layouts/cpanel/control-board/settings.phpnu[PK!ӝCD?system/helixultimate/layouts/cpanel/control-board/fieldset/icon.phpnu[PK!DT?system/helixultimate/layouts/cpanel/control-board/fieldset/field.phpnu[PK!tm||D+?system/helixultimate/layouts/cpanel/control-board/fieldset/panel.phpnu[PK!n /E3?system/helixultimate/layouts/cpanel/control-board/fieldset/groups.phpnu[PK!WE9?system/helixultimate/layouts/cpanel/control-board/fieldset/fields.phpnu[PK!&##5C?system/helixultimate/layouts/cpanel/editor/topbar.phpnu[PK!TԎ7+g?system/helixultimate/layouts/cpanel/editor/controls.phpnu[PK!H<**0 k?system/helixultimate/layouts/backend/section.phpnu[PK!/?system/helixultimate/layouts/backend/column.phpnu[PK! (՛?system/helixultimate/layouts/display.phpnu[PK!177.3?system/helixultimate/layouts/frontend/rows.phpnu[PK!~   1Ȧ?system/helixultimate/layouts/frontend/modules.phpnu[PK!6&njj2/?system/helixultimate/layouts/frontend/generate.phpnu[PK!t'U7?system/helixultimate/layouts/frontend/conponentarea.phpnu[PK!C/?system/helixultimate/layouts/frontend/headerlist/style-1/header.phpnu[PK!/.4B?system/helixultimate/layouts/frontend/headerlist/style-1/thumb.jpgnu[PK!{C?system/helixultimate/layouts/frontend/headerlist/style-2/header.phpnu[PK!7B?system/helixultimate/layouts/frontend/headerlist/style-2/thumb.jpgnu[PK!/Vh((/M?system/helixultimate/layouts/preview/iframe.phpnu[PK!pp1?system/helixultimate/layouts/form/field/media.phpnu[PK!SZZB?system/helixultimate/html/layouts/libraries/cms/html/bootstrap.phpnu[PK!D__6 T@system/helixultimate/html/layouts/form/field/media.phpnu[PK!b229q@system/helixultimate/html/layouts/form/field/media_j3.phpnu[PK!ݲ7Q7Q&m@system/helixultimate/helixultimate.phpnu[PK!q5r,@system/helixultimate/layout/fields/media.phpnu[PK![9-@system/helixultimate/layout/fields/select.phpnu[PK!}+@system/helixultimate/layout/fields/text.phpnu[PK!3i=~ 08@system/helixultimate/layout/fields/alignment.phpnu[PK!,,.@system/helixultimate/layout/fields/color.phpnu[PK!;ڱ +Asystem/helixultimate/layout/fields/unit.phpnu[PK!N+/Asystem/helixultimate/layout/fields/menutype.phpnu[PK!3썔))/t#Asystem/helixultimate/layout/fields/checkbox.phpnu[PK!:/OO4*Asystem/helixultimate/layout/fields/menuHierarchy.phpnu[PK! L0=Asystem/helixultimate/layout/megaMenu/sidebar.phpnu[PK!'@̿0,FAsystem/helixultimate/layout/megaMenu/modules.phpnu[PK!>>znn.KAsystem/helixultimate/layout/megaMenu/slots.phpnu[PK!LL-T`Asystem/helixultimate/layout/megaMenu/grid.phpnu[PK!S#44,gAsystem/helixultimate/layout/megaMenu/row.phpnu[PK!(32wAsystem/helixultimate/layout/megaMenu/container.phpnu[PK!3Asystem/helixultimate/layout/megaMenu/megaFields.phpnu[PK!ĨTrr-#Asystem/helixultimate/layout/megaMenu/cell.phpnu[PK! X/Asystem/helixultimate/layout/megaMenu/column.phpnu[PK!Ad)cAsystem/helixultimate/layout/generated.phpnu[PK!MMT001ЬAsystem/helixultimate/layout/settings/settings.phpnu[PK!]/Asystem/helixultimate/layout/settings/fields.phpnu[PK!O::8 Asystem/helixultimate/vendor/tedivm/jshrink/composer.jsonnu[PK!L:I:ICAsystem/helixultimate/vendor/tedivm/jshrink/src/JShrink/Minifier.phpnu[PK!P(Z-Bsystem/helixultimate/vendor/autoload.phpnu[PK!\9]/Bsystem/helixultimate/vendor/scssphp/scssphp/composer.jsonnu[PK!%C558>Bsystem/helixultimate/vendor/scssphp/scssphp/scss.inc.phpnu[PK!@:]ABsystem/helixultimate/vendor/scssphp/scssphp/src/Parser.phpnu[PK!kB8fDsystem/helixultimate/vendor/scssphp/scssphp/src/Node.phpnu[PK!<87S7S?Dsystem/helixultimate/vendor/scssphp/scssphp/src/Node/Number.phpnu[PK!@RssEWDsystem/helixultimate/vendor/scssphp/scssphp/src/CompilationResult.phpnu[PK!4looL{\Dsystem/helixultimate/vendor/scssphp/scssphp/src/Exception/RangeException.phpnu[PK!bӆQf^Dsystem/helixultimate/vendor/scssphp/scssphp/src/Exception/SassScriptException.phpnu[PK!8IIKzbDsystem/helixultimate/vendor/scssphp/scssphp/src/Exception/SassException.phpnu[PK!M>cDsystem/helixultimate/vendor/scssphp/scssphp/src/Exception/ServerException.phpnu[PK!j||OeDsystem/helixultimate/vendor/scssphp/scssphp/src/Exception/CompilerException.phpnu[PK!8چMgDsystem/helixultimate/vendor/scssphp/scssphp/src/Exception/ParserException.phpnu[PK!~Cgg>alDsystem/helixultimate/vendor/scssphp/scssphp/src/Base/Range.phpnu[PK!0H?6pDsystem/helixultimate/vendor/scssphp/scssphp/src/OutputStyle.phpnu[PK!x[ [ C*qDsystem/helixultimate/vendor/scssphp/scssphp/src/Formatter/Debug.phpnu[PK!EQ#F{Dsystem/helixultimate/vendor/scssphp/scssphp/src/Formatter/Crunched.phpnu[PK!墕FDsystem/helixultimate/vendor/scssphp/scssphp/src/Formatter/Expanded.phpnu[PK!˝EDsystem/helixultimate/vendor/scssphp/scssphp/src/Formatter/Compact.phpnu[PK!WMDDsystem/helixultimate/vendor/scssphp/scssphp/src/Formatter/Nested.phpnu[PK!>ZLeeIDsystem/helixultimate/vendor/scssphp/scssphp/src/Formatter/OutputBlock.phpnu[PK!c,H^Dsystem/helixultimate/vendor/scssphp/scssphp/src/Formatter/Compressed.phpnu[PK!HDsystem/helixultimate/vendor/scssphp/scssphp/src/Compiler/Environment.phpnu[PK!..IDsystem/helixultimate/vendor/scssphp/scssphp/src/Compiler/CachedResult.phpnu[PK!XXD8Dsystem/helixultimate/vendor/scssphp/scssphp/src/Util.phpnu[PK!I" " BDsystem/helixultimate/vendor/scssphp/scssphp/src/ValueConverter.phpnu[PK!8?==;Dsystem/helixultimate/vendor/scssphp/scssphp/src/Version.phpnu[PK!]5 8@Dsystem/helixultimate/vendor/scssphp/scssphp/src/Type.phpnu[PK!K0"0"=/Dsystem/helixultimate/vendor/scssphp/scssphp/src/Formatter.phpnu[PK!R߅B9 Esystem/helixultimate/vendor/scssphp/scssphp/src/Cache.phpnu[PK!5MG(Esystem/helixultimate/vendor/scssphp/scssphp/src/Logger/StreamLogger.phpnu[PK!B|uuJa.Esystem/helixultimate/vendor/scssphp/scssphp/src/Logger/LoggerInterface.phpnu[PK!VmFP3Esystem/helixultimate/vendor/scssphp/scssphp/src/Logger/QuietLogger.phpnu[PK!D8|5Esystem/helixultimate/vendor/scssphp/scssphp/src/Warn.phpnu[PK!QY,44F=Esystem/helixultimate/vendor/scssphp/scssphp/src/Block/ContentBlock.phpnu[PK!͐!CU@Esystem/helixultimate/vendor/scssphp/scssphp/src/Block/EachBlock.phpnu[PK!%}ΠDBEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/WhileBlock.phpnu[PK!\n  DDEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/MediaBlock.phpnu[PK!k|@ZZBtGEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/ForBlock.phpnu[PK!Ǩ)zzG@JEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/CallableBlock.phpnu[PK!n&3H1MEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/DirectiveBlock.phpnu[PK!R{EOEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/ElseifBlock.phpnu[PK!~<%  MQEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/NestedPropertyBlock.phpnu[PK!ypĈCxTEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/ElseBlock.phpnu[PK!5xEsVEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/AtRootBlock.phpnu[PK!)  AXEsystem/helixultimate/vendor/scssphp/scssphp/src/Block/IfBlock.phpnu[PK!:-ww9i[Esystem/helixultimate/vendor/scssphp/scssphp/src/Block.phpnu[PK!`_<I_Esystem/helixultimate/vendor/scssphp/scssphp/src/Compiler.phpnu[PK!}@mm=#Jsystem/helixultimate/vendor/scssphp/scssphp/src/Util/Path.phpnu[PK!W2{:`)Jsystem/helixultimate/vendor/scssphp/scssphp/src/Colors.phpnu[PK!G!,"GMHJsystem/helixultimate/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.phpnu[PK!>S..P\YJsystem/helixultimate/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.phpnu[PK!e5] DJsystem/helixultimate/vendor/scssphp/scssphp/src/SourceMap/Base64.phpnu[PK!^h  6Jsystem/helixultimate/vendor/composer/autoload_psr4.phpnu[PK!$$8aJsystem/helixultimate/vendor/composer/autoload_static.phpnu[PK!}z:Jsystem/helixultimate/vendor/composer/autoload_classmap.phpnu[PK!畎K:::Jsystem/helixultimate/vendor/composer/InstalledVersions.phpnu[PK!5Ky>>4Ksystem/helixultimate/vendor/composer/ClassLoader.phpnu[PK!*28TKsystem/helixultimate/vendor/composer/installed.phpnu[PK!Mi3ZKsystem/helixultimate/vendor/composer/installed.jsonnu[PK!kqq6oKsystem/helixultimate/vendor/composer/autoload_real.phpnu[PK!D<sKsystem/helixultimate/vendor/composer/autoload_namespaces.phpnu[PK!Tt7 uKsystem/helixultimate/vendor/composer/platform_check.phpnu[PK!G=&yKsystem/helixultimate/helixultimate.xmlnu[PK!s aFaF-$Ksystem/helixultimate/src/Platform/Request.phpnu[PK!0'0'+Ksystem/helixultimate/src/Platform/Media.phpnu[PK!y.dCC,mKsystem/helixultimate/src/Platform/Helper.phpnu[PK!22Lsystem/helixultimate/src/Platform/HTMLOverride.phpnu[PK!Q*FLsystem/helixultimate/src/Platform/Blog.phpnu[PK!,?((.LcLsystem/helixultimate/src/Platform/Settings.phpnu[PK!PH H 3Lsystem/helixultimate/src/Platform/Classes/Image.phpnu[PK!GG>#Zsystem/shortcut/shortcut.xmlnu[PK!bч*(Zsystem/shortcut/src/Extension/Shortcut.phpnu[PK!4yjVV"=Zsystem/urltranslator/jbdrouter.phpnu[PK!C\;;&Zsystem/urltranslator/urltranslator.phpnu[PK!VZsystem/urltranslator/index.htmlnu[PK!?&Zsystem/urltranslator/urltranslator.xmlnu[PK!<(Zsystem/urltranslator/watermark/index.phpnu[PK!(Zsystem/urltranslator/watermark/.htaccessnu[PK!E%%#8Zsystem/skipto/services/provider.phpnu[PK!((Zsystem/skipto/skipto.xmlnu[PK! I9[[& Zsystem/skipto/src/Extension/Skipto.phpnu[PK!FF Zsystem/actionlogs/actionlogs.xmlnu[PK!ʢ'gZsystem/actionlogs/services/provider.phpnu[PK!@,,&Zsystem/actionlogs/forms/actionlogs.xmlnu[PK! {'CZsystem/actionlogs/forms/information.xmlnu[PK!8],z;z;.$Zsystem/actionlogs/src/Extension/ActionLogs.phpnu[PK!"@Q\*[system/cfuploadedfilescleaner/language/en-GB/en-GB.plg_system_cfuploadedfilescleaner.sys.ininu[PK!㻽H55Xw.[system/cfuploadedfilescleaner/language/en-GB/en-GB.plg_system_cfuploadedfilescleaner.ininu[PK!{Ngg840[system/cfuploadedfilescleaner/cfuploadedfilescleaner.phpnu[PK!R997G[system/cfuploadedfilescleaner/script.install.helper.phpnu[PK!8[system/cfuploadedfilescleaner/cfuploadedfilescleaner.xmlnu[PK!o0x[system/cfuploadedfilescleaner/script.install.phpnu[PK!k**$[system/jooa11y/services/provider.phpnu[PK!ըcN.[system/jooa11y/jooa11y.xmlnu[PK!/9 ))( [system/jooa11y/src/Extension/Jooa11y.phpnu[PK!p 9MM+T[system/schedulerunner/services/provider.phpnu[PK!hz  ([system/schedulerunner/schedulerunner.xmlnu[PK!jw#1"1"16_[system/schedulerunner/src/Extension/ScheduleRunner.phpnu[PK!={rr[system/foundry/foundry.xmlnu[PK!_, 3 3 [system/foundry/foundry.phpnu[PK!: % \system/webauthn/services/provider.phpnu[PK!E7 ]]S\system/webauthn/webauthn.xmlnu[PK!Պ{"\system/webauthn/forms/webauthn.xmlnu[PK!$++\system/webauthn/fido.jwtnu[PK!O e;system/webauthn/src/PluginTraits/AdditionalLoginButtons.phpnu[PK!rh h 9system/webauthn/src/PluginTraits/AjaxHandlerChallenge.phpnu[PK! ??5system/webauthn/src/PluginTraits/EventReturnAware.phpnu[PK!]ܨ1dsystem/webauthn/src/PluginTraits/UserDeletion.phpnu[PK!l>1>15R system/webauthn/src/PluginTraits/AjaxHandlerLogin.phpnu[PK!.h86Qsystem/webauthn/src/PluginTraits/AjaxHandlerCreate.phpnu[PK!bizz6dsystem/webauthn/src/PluginTraits/UserProfileFields.phpnu[PK!@1YY0ׁsystem/webauthn/src/PluginTraits/AjaxHandler.phpnu[PK!= 9system/webauthn/src/PluginTraits/AjaxHandlerSaveLabel.phpnu[PK!<:{6system/webauthn/src/PluginTraits/AjaxHandlerDelete.phpnu[PK!:ఈsystem/webauthn/src/PluginTraits/AjaxHandlerInitCreate.phpnu[PK!i*Csystem/webauthn/src/MetadataRepository.phpnu[PK!)vTT,Tˈsystem/webauthn/src/CredentialRepository.phpnu[PK!9 |ee* system/webauthn/src/Extension/Webauthn.phpnu[PK!6 +F;system/webauthn/src/Field/WebauthnField.phpnu[PK!o""AcFsystem/webauthn/src/Hotfix/FidoU2FAttestationStatementSupport.phpnu[PK!q++Disystem/webauthn/src/Hotfix/AndroidKeyAttestationStatementSupport.phpnu[PK!O.6H6H%system/webauthn/src/Hotfix/Server.phpnu[PK!MA•LL&މsystem/webauthn/src/Authentication.phpnu[PK!iq-nn+system/sef/sef.xmlnu[PK!U#l B0system/sef/services/provider.phpnu[PK!Ŵ  5system/sef/src/Extension/Sef.phpnu[PK!SS(Vsystem/guidedtours/services/provider.phpnu[PK!%nn"\system/guidedtours/guidedtours.xmlnu[PK!5̍WW0s`system/guidedtours/src/Extension/GuidedTours.phpnu[PK!WJJH*}system/convertforms/language/en-GB/en-GB.plg_system_convertforms.sys.ininu[PK!XgggD~system/convertforms/language/en-GB/en-GB.plg_system_convertforms.ininu[PK!#o,,-ǀsystem/convertforms/language/en-GB/index.htmlnu[PK!z11$Psystem/convertforms/convertforms.phpnu[PK!~2}9}9-system/convertforms/script.install.helper.phpnu[PK!JV$system/convertforms/convertforms.xmlnu[PK!M&system/convertforms/script.install.phpnu[PK!6(system/logrotation/services/provider.phpnu[PK!A32"system/logrotation/logrotation.xmlnu[PK!yׄ0'system/logrotation/src/Extension/LogRotation.phpnu[PK!8ľ# system/logout/services/provider.phpnu[PK!ĮTT"system/logout/logout.xmlnu[PK!1D D &%system/logout/src/Extension/Logout.phpnu[PK!bx*Q1sampledata/multilang/services/provider.phpnu[PK!լv"o7sampledata/multilang/multilang.xmlnu[PK! )YY4};sampledata/multilang/src/Extension/MultiLanguage.phpnu[PK!V˟%:sampledata/blog/services/provider.phpnu[PK!u.sampledata/blog/blog.xmlnu[PK!NQNQ&sampledata/blog/src/Extension/Blog.phpnu[PK!f.#Ceditors-xtd/pagebreak/pagebreak.xmlnu[PK!$==+Geditors-xtd/pagebreak/services/provider.phpnu[PK! !σ 1!Meditors-xtd/pagebreak/src/Extension/PageBreak.phpnu[PK!Ѹ!Yeditors-xtd/igallery/igallery.phpnu[PK!^GRss!J\editors-xtd/igallery/igallery.xmlnu[PK!kk`editors-xtd/article/article.xmlnu[PK!#ӗ33)ceditors-xtd/article/services/provider.phpnu[PK!8dƂ -Tieditors-xtd/article/src/Extension/Article.phpnu[PK![Wqq!3teditors-xtd/readmore/readmore.xmlnu[PK!xy77*weditors-xtd/readmore/services/provider.phpnu[PK!/}editors-xtd/readmore/src/Extension/ReadMore.phpnu[PK!U|qqeditors-xtd/fields/fields.xmlnu[PK!֠n..(veditors-xtd/fields/services/provider.phpnu[PK!\ +editors-xtd/fields/src/Extension/Fields.phpnu[PK!`<))'훍editors-xtd/image/services/provider.phpnu[PK!A__meditors-xtd/image/image.xmlnu[PK!)editors-xtd/image/src/Extension/Image.phpnu[PK!6//(*editors-xtd/module/services/provider.phpnu[PK!uAeeƍeditors-xtd/module/module.xmlnu[PK!2WF9 9 +cʍeditors-xtd/module/src/Extension/Module.phpnu[PK!$''&ԍeditors-xtd/menu/services/provider.phpnu[PK!eetڍeditors-xtd/menu/menu.xmlnu[PK!sm  '"ލeditors-xtd/menu/src/Extension/Menu.phpnu[PK!p33)editors-xtd/contact/services/provider.phpnu[PK!nZww$editors-xtd/contact/contact.xmlnu[PK!/ / -editors-xtd/contact/src/Extension/Contact.phpnu[PK!W)] 9veditors-xtd/easybloggoogleimport/easybloggoogleimport.phpnu[PK!Dǎ9editors-xtd/easybloggoogleimport/easybloggoogleimport.xmlnu[PK!m+* editors-xtd/easyblogpolls/easyblogpolls.xmlnu[PK!f&&+2editors-xtd/easyblogpolls/easyblogpolls.phpnu[PK!PR'editors-xtd/convertforms/language/en-GB/en-GB.plg_editors-xtd_convertforms.sys.ininu[PK!nN(editors-xtd/convertforms/language/en-GB/en-GB.plg_editors-xtd_convertforms.ininu[PK!#o,,2*editors-xtd/convertforms/language/en-GB/index.htmlnu[PK!@ŗ!+editors-xtd/convertforms/form.xmlnu[PK!_;++)o-editors-xtd/convertforms/convertforms.phpnu[PK!?^9923editors-xtd/convertforms/script.install.helper.phpnu[PK!<w  )meditors-xtd/convertforms/convertforms.xmlnu[PK!\Ƣ+Oqeditors-xtd/convertforms/script.install.phpnu[PK!C`**&twebservices/tags/services/provider.phpnu[PK!Gffzwebservices/tags/tags.xmlnu[PK!ua6WW'}webservices/tags/src/Extension/Tags.phpnu[PK!Ell`webservices/media/media.xmlnu[PK!j//'webservices/media/services/provider.phpnu[PK!嚫)webservices/media/src/Extension/Media.phpnu[PK!]O44( webservices/config/services/provider.phpnu[PK!R*rrwebservices/config/config.xmlnu[PK!p+Wwebservices/config/src/Extension/Config.phpnu[PK!x1 >>*=webservices/redirect/services/provider.phpnu[PK!ˍ~~!հwebservices/redirect/redirect.xmlnu[PK!Fs||/webservices/redirect/src/Extension/Redirect.phpnu[PK!s 99)webservices/banners/services/provider.phpnu[PK!TGxxwebservices/banners/banners.xmlnu[PK!}3 -Žwebservices/banners/src/Extension/Banners.phpnu[PK!VCC+̎webservices/templates/services/provider.phpnu[PK![wф#jҎwebservices/templates/templates.xmlnu[PK!PTT1A֎webservices/templates/src/Extension/Templates.phpnu[PK!/-99)ێwebservices/content/services/provider.phpnu[PK!ʚ*I I -webservices/content/src/Extension/Content.phpnu[PK!(xx.webservices/content/content.xmlnu[PK!j99)webservices/contact/services/provider.phpnu[PK!otsXxxwebservices/contact/contact.xmlnu[PK!}љ-Nwebservices/contact/src/Extension/Contact.phpnu[PK! CC+D webservices/newsfeeds/services/provider.phpnu[PK!F9̖AA1webservices/newsfeeds/src/Extension/Newsfeeds.phpnu[PK!#webservices/newsfeeds/newsfeeds.xmlnu[PK!1>>*[webservices/messages/services/provider.phpnu[PK!}4yy/ webservices/messages/src/Extension/Messages.phpnu[PK!ָ~~!%webservices/messages/messages.xmlnu[PK!@4Uxx)webservices/modules/modules.xmlnu[PK!\ 99)a-webservices/modules/services/provider.phpnu[PK!Y-2webservices/modules/src/Extension/Modules.phpnu[PK!~99):webservices/plugins/services/provider.phpnu[PK!@xxf@webservices/plugins/plugins.xmlnu[PK!m --Dwebservices/plugins/src/Extension/Plugins.phpnu[PK!=!#nJwebservices/installer/installer.xmlnu[PK!RCC+ENwebservices/installer/services/provider.phpnu[PK!v 1Swebservices/installer/src/Extension/Installer.phpnu[PK!$y//'6Ywebservices/menus/services/provider.phpnu[PK!Lҗll^webservices/menus/menus.xmlnu[PK! k\)sbwebservices/menus/src/Extension/Menus.phpnu[PK!!//'kwebservices/users/services/provider.phpnu[PK!Ƒll qwebservices/users/users.xmlnu[PK!0z)twebservices/users/src/Extension/Users.phpnu[PK!(99) }webservices/privacy/services/provider.phpnu[PK!n|xxwebservices/privacy/privacy.xmlnu[PK!-bwebservices/privacy/src/Extension/Privacy.phpnu[PK!snCC+>webservices/languages/services/provider.phpnu[PK!)U#ܓwebservices/languages/languages.xmlnu[PK!z [1webservices/languages/src/Extension/Languages.phpnu[PK!##&Ѫfilesystem/local/services/provider.phpnu[PK!7*(Jfilesystem/local/src/Extension/Local.phpnu[PK!^GsGs-Cfilesystem/local/src/Adapter/LocalAdapter.phpnu[PK!UGG2filesystem/local/local.xmlnu[PK!#x:fields/textarea/params/textarea.xmlnu[PK! "))%?fields/textarea/services/provider.phpnu[PK!r@/YYEfields/textarea/textarea.xmlnu[PK!oE!Mfields/textarea/tmpl/textarea.phpnu[PK!//*Ofields/textarea/src/Extension/Textarea.phpnu[PK!lRfields/text/params/text.xmlnu[PK!Vfields/text/text.xmlnu[PK!eh!q]fields/text/services/provider.phpnu[PK!obfields/text/tmpl/text.phpnu[PK!d6O"dfields/text/src/Extension/Text.phpnu[PK!Qg*gfields/radio/params/radio.xmlnu[PK! m"lfields/radio/services/provider.phpnu[PK! Wqfields/radio/radio.xmlnu[PK!@+"||Bxfields/radio/tmpl/radio.phpnu[PK!bC$ {fields/radio/src/Extension/Radio.phpnu[PK!pfields/media/params/media.xmlnu[PK!kYY҃fields/media/media.xmlnu[PK!"qfields/media/services/provider.phpnu[PK!fZK1ݏfields/media/tmpl/media.phpnu[PK!' $뒐fields/media/src/Extension/Media.phpnu[PK!-sfffields/color/color.xmlnu[PK!Yn"fields/color/services/provider.phpnu[PK!Aifields/color/tmpl/color.phpnu[PK!xII$말fields/color/src/Extension/Color.phpnu[PK!qkkfields/url/params/url.xmlnu[PK!av ϱfields/url/services/provider.phpnu[PK!Bь/fields/url/url.xmlnu[PK!\  )fields/url/tmpl/url.phpnu[PK!8qHH |fields/url/src/Extension/Url.phpnu[PK!ǐfields/list/params/list.xmlnu[PK!-/(̐fields/list/list.xmlnu[PK!u&&!4Ԑfields/list/services/provider.phpnu[PK!O7ِfields/list/tmpl/list.phpnu[PK!m?A(tܐfields/list/src/Extension/ListPlugin.phpnu[PK!rBV'fields/checkboxes/params/checkboxes.xmlnu[PK!Q33'fields/checkboxes/services/provider.phpnu[PK!_** qfields/checkboxes/checkboxes.xmlnu[PK!%fields/checkboxes/tmpl/checkboxes.phpnu[PK!NS.fields/checkboxes/src/Extension/Checkboxes.phpnu[PK!&~//2fields/sql/params/sql.xmlnu[PK!7fields/sql/sql.xmlnu[PK!d{X fields/sql/services/provider.phpnu[PK!'^^ fields/sql/tmpl/sql.phpnu[PK!  fields/sql/src/Extension/SQL.phpnu[PK!@KX"fields/editor/params/editor.xmlnu[PK!ԗs fields/editor/editor.xmlnu[PK!B#R)fields/editor/services/provider.phpnu[PK!m"4.fields/editor/tmpl/editor.phpnu[PK!tC&0fields/editor/src/Extension/Editor.phpnu[PK!H-%6fields/imagelist/params/imagelist.xmlnu[PK!6..&:fields/imagelist/services/provider.phpnu[PK!*@fields/imagelist/imagelist.xmlnu[PK!Q#Gfields/imagelist/tmpl/imagelist.phpnu[PK!tRR,Nfields/imagelist/src/Extension/Imagelist.phpnu[PK!UR'aaSfields/user/params/user.xmlnu[PK!Ez+authentication/cookie/services/provider.phpnu[PK!C6868.authentication/cookie/src/Extension/Cookie.phpnu[PK!MyQ ASauthentication/cookie/cookie.xmlnu[PK!G٬+Yauthentication/joomla/services/provider.phpnu[PK!Ľ _authentication/joomla/joomla.xmlnu[PK!%$.cauthentication/joomla/src/Extension/Joomla.phpnu[PK!j3Œ)\sauthentication/ldap/services/provider.phpnu[PK! SAyauthentication/ldap/ldap.xmlnu[PK!`j..8authentication/ldap/src/Factory/LdapFactoryInterface.phpnu[PK!r/)authentication/ldap/src/Factory/LdapFactory.phpnu[PK!P.544*.authentication/ldap/src/Extension/Ldap.phpnu[PK!֛&1ȓspsimpleportfolio/sppagebuilder/sppagebuilder.phpnu[PK!<,,-"Гspsimpleportfolio/sppagebuilder/thumbnail.jpgnu[PK!)BB1cspsimpleportfolio/sppagebuilder/sppagebuilder.xmlnu[PK!ıyGLL.api-authentication/token/services/provider.phpnu[PK!V;|110api-authentication/token/src/Extension/Token.phpnu[PK!\ssf”task/demotasks/demotasks.xmlnu[PK!3*%Ɣtask/demotasks/src/Extension/DemoTasks.phpnu[PK!BGMextension/jce/jce.phpnu[PK! -extension/jce/jce.xmlnu[PK!BwDD&extension/joomla/services/provider.phpnu[PK!Wffextension/joomla/joomla.xmlnu[PK!@&&)M extension/joomla/src/Extension/Joomla.phpnu[PK!PDl,10extension/namespacemap/services/provider.phpnu[PK!2hN'5extension/namespacemap/namespacemap.xmlnu[PK!vEA( 59extension/namespacemap/src/Extension/NamespaceMap.phpnu[PK!GffEextension/finder/finder.xmlnu[PK!l +?DD&WIextension/finder/services/provider.phpnu[PK!6ҡ)Nextension/finder/src/Extension/Finder.phpnu[PK!MOd d ]deasyblog/pagebreak/pagebreak.xmlnu[PK!^>->- oeasyblog/pagebreak/pagebreak.phpnu[PK!Veasyblog/pagebreak/index.htmlnu[PK!8l $ easyblog/autoarticle/autoarticle.xmlnu[PK!q9))9easyblog/autoarticle/elements/fields/modal/categories.phpnu[PK!5easyblog/autoarticle/elements/fields/modal/index.htmlnu[PK!1)V**$easyblog/autoarticle/autoarticle.phpnu[PK!VGݕeasyblog/autoarticle/index.htmlnu[PK!rn #ݕquickicon/eos/services/provider.phpnu[PK!quickicon/eos/eos.xmlnu[PK! ,U$$#quickicon/eos/src/Extension/Eos.phpnu[PK! 'B quickicon/privacycheck/privacycheck.xmlnu[PK!iFF,Kquickicon/privacycheck/services/provider.phpnu[PK!bRl005quickicon/privacycheck/src/Extension/PrivacyCheck.phpnu[PK!`%'quickicon/downloadkey/downloadkey.xmlnu[PK!@ZAA+,quickicon/downloadkey/services/provider.phpnu[PK!Z?32quickicon/downloadkey/src/Extension/Downloadkey.phpnu[PK!L3 ,#Dquickicon/joomlaupdate/services/provider.phpnu[PK!A'-Jquickicon/joomlaupdate/joomlaupdate.xmlnu[PK! E56Oquickicon/joomlaupdate/src/Extension/Joomlaupdate.phpnu[PK!+E$`quickicon/jce/jce.phpnu[PK!Gngquickicon/jce/jce.xmlnu[PK!a=-jquickicon/overridecheck/services/provider.phpnu[PK!il)qquickicon/overridecheck/overridecheck.xmlnu[PK!L.j7vquickicon/overridecheck/src/Extension/OverrideCheck.phpnu[PK!UU/:quickicon/phpversioncheck/services/provider.phpnu[PK! 8D-quickicon/phpversioncheck/phpversioncheck.xmlnu[PK!{``;琖quickicon/phpversioncheck/src/Extension/PhpVersionCheck.phpnu[PK!NHUU/quickicon/extensionupdate/services/provider.phpnu[PK!^-fquickicon/extensionupdate/extensionupdate.xmlnu[PK!E] ``;quickicon/extensionupdate/src/Extension/Extensionupdate.phpnu[PK!#ZXɖconvertformstools/calculations/language/ru-RU/ru-RU.plg_convertformstools_calculations.ininu[PK!b1ggZіconvertformstools/calculations/language/ca-ES/ca-ES.plg_convertformstools_calculations.ininu[PK!N>Zؖconvertformstools/calculations/language/bg-BG/bg-BG.plg_convertformstools_calculations.ininu[PK!KT}}Zconvertformstools/calculations/language/cs-CZ/cs-CZ.plg_convertformstools_calculations.ininu[PK!TpˑZconvertformstools/calculations/language/es-ES/es-ES.plg_convertformstools_calculations.ininu[PK!9^^Zconvertformstools/calculations/language/fi-FI/fi-FI.plg_convertformstools_calculations.ininu[PK!U4 >H菗convertformstools/pdf/language/ca-ES/ca-ES.plg_convertformstools_pdf.ininu[PK!3Hconvertformstools/pdf/language/pt-BR/pt-BR.plg_convertformstools_pdf.ininu[PK!x x HӠconvertformstools/pdf/language/bg-BG/bg-BG.plg_convertformstools_pdf.ininu[PK!PHìconvertformstools/pdf/language/cs-CZ/cs-CZ.plg_convertformstools_pdf.ininu[PK!'AHconvertformstools/pdf/language/es-ES/es-ES.plg_convertformstools_pdf.ininu[PK! Hconvertformstools/pdf/language/fi-FI/fi-FI.plg_convertformstools_pdf.ininu[PK!{{Lŗconvertformstools/pdf/language/en-GB/en-GB.plg_convertformstools_pdf.sys.ininu[PK!'SHǗconvertformstools/pdf/language/en-GB/en-GB.plg_convertformstools_pdf.ininu[PK!Y HЗconvertformstools/pdf/language/uk-UA/uk-UA.plg_convertformstools_pdf.ininu[PK!]ۤeeH ۗconvertformstools/pdf/language/fr-FR/fr-FR.plg_convertformstools_pdf.ininu[PK!#Hconvertformstools/pdf/language/de-DE/de-DE.plg_convertformstools_pdf.ininu[PK!PeHconvertformstools/pdf/language/it-IT/it-IT.plg_convertformstools_pdf.ininu[PK!a-$convertformstools/pdf/dompdf/autoload.inc.phpnu[PK!*pxmm2econvertformstools/pdf/dompdf/lib/fonts/ARIALbd.ufmnu[PK!wR;24ޙconvertformstools/pdf/dompdf/lib/fonts/ARIALbi.ttfnu[PK!|fڲ1qconvertformstools/pdf/dompdf/lib/fonts/ARIALi.ufmnu[PK!R×82{convertformstools/pdf/dompdf/lib/fonts/ARIALbi.ufmnu[PK!l{l{1Ǐconvertformstools/pdf/dompdf/lib/fonts/ARIALi.ttfnu[PK!:n8 8 0 convertformstools/pdf/dompdf/lib/fonts/ARIAL.ttfnu[PK!u0,convertformstools/pdf/dompdf/lib/fonts/ARIAL.ufmnu[PK!?J_m m 2Nһconvertformstools/pdf/dompdf/lib/fonts/ARIALbd.ttfnu[PK!"  H|@convertformstools/pdf/dompdf/lib/fonts/dompdf_font_family_cache.dist.phpnu[PK!KBconvertformstools/pdf/dompdf/lib/php-font-lib/.github/workflows/phpunit.ymlnu[PK!g7Fconvertformstools/pdf/dompdf/lib/php-font-lib/.htaccessnu[PK!Su]}Fconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Exception/FontNotFoundException.phpnu[PK!p{DGconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Header.phpnu[PK!vT*wCCIKconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/EncodingMap.phpnu[PK!-BNconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Font.phpnu[PK!t+>ZMVconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/TrueType/Header.phpnu[PK!zr5--KYconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/TrueType/File.phpnu[PK!KCZconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.phpnu[PK!rQconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/TrueType/Collection.phpnu[PK!_pN'N'Jconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/BinaryStream.phpnu[PK!FIhhIPconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/WOFF/Header.phpnu[PK!昑G1convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/WOFF/File.phpnu[PK! Vsconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.phpnu[PK!N] Hconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/EOT/Header.phpnu[PK!k8 8 FVconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/EOT/File.phpnu[PK!Z Rconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/DirectoryEntry.phpnu[PK!3Ikconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Table.phpnu[PK!Mconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/name.phpnu[PK! ;^HHM_ convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/head.phpnu[PK!*|8 8 M$convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/post.phpnu[PK!M&&Lconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/os2.phpnu[PK!5M{#convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/loca.phpnu[PK!^8>>M+convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/kern.phpnu[PK!$h M2convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/maxp.phpnu[PK!ȁM"8convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/hmtx.phpnu[PK!ԘٶM>convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/hhea.phpnu[PK!mw w MCconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/cmap.phpnu[PK!T aSdconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/nameRecord.phpnu[PK!3r,ffMiconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Table/Type/glyf.phpnu[PK!~Hzconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Autoloader.phpnu[PK!Z܁N~convertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/AdobeFontMetrics.phpnu[PK!@Koconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/OpenType/File.phpnu[PK!8Ztconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.phpnu[PK!"buuTconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Glyph/OutlineComposite.phpnu[PK!9Kconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Glyph/Outline.phpnu[PK!yF|Tconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Glyph/OutlineComponent.phpnu[PK!f QLconvertformstools/pdf/dompdf/lib/php-font-lib/src/FontLib/Glyph/OutlineSimple.phpnu[PK!AQ=convertformstools/pdf/dompdf/lib/php-svg-lib/src/autoload.phpnu[PK!7Econvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/DefaultStyle.phpnu[PK!ʘiGRGRE$convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Surface/CPdf.phpnu[PK!==--N;convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Surface/SurfacePDFLib.phpnu[PK!mrHY5Y5Leiconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Surface/SurfaceCpdf.phpnu[PK!~RRQ:convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Surface/SurfaceInterface.phpnu[PK!M(88F convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Gradient/Stop.phpnu[PK! a6Bconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Shape.phpnu[PK!W WWAFconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Rect.phpnu[PK!)bDAconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Line.phpnu[PK!g>  Kconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/LinearGradient.phpnu[PK!<::Aconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Stop.phpnu[PK!iECconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Polyline.phpnu[PK!*TBconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Group.phpnu[PK!zCconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Anchor.phpnu[PK!! C&convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/UseTag.phpnu[PK!KC-convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Circle.phpnu[PK!ˮ`DDKzconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/RadialGradient.phpnu[PK!0?ؔNNA9convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Path.phpnu[PK!9H>+convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/AbstractTag.phpnu[PK!x1 ttAS=convertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Text.phpnu[PK!=1cE8Dconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/StyleTag.phpnu[PK!3:EFconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/ClipPath.phpnu[PK!oDIconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Ellipse.phpnu[PK!=`BMconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Image.phpnu[PK!pDnTconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Tag/Polygon.phpnu[PK!>4>GG>Wconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Style.phpnu[PK!\S%%Ajconvertformstools/pdf/dompdf/lib/php-svg-lib/src/Svg/Document.phpnu[PK!k//>convertformstools/pdf/dompdf/lib/php-css-parser/src/Parser.phpnu[PK!FE66IQconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/CSSFunction.phpnu[PK!r  Aconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/URL.phpnu[PK!YP P J~convertformstools/pdf/dompdf/lib/php-css-parser/src/Value/CalcFunction.phpnu[PK!>emOHconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/CalcRuleValueList.phpnu[PK!s3Lconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/PrimitiveValue.phpnu[PK!ag ^ ^ Gconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/ValueList.phpnu[PK!Oܧ Gconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/CSSString.phpnu[PK!hrBconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/Size.phpnu[PK!p##KEconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/RuleValueList.phpnu[PK!FȽ!!Cconvertformstools/pdf/dompdf/lib/php-css-parser/src/Value/Value.phpnu[PK!ԙ  Fw3convertformstools/pdf/dompdf/lib/php-css-parser/src/Value/LineName.phpnu[PK!<C:convertformstools/pdf/dompdf/lib/php-css-parser/src/Value/Color.phpnu[PK!1nHRconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/KeyFrame.phpnu[PK!THZconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/Document.phpnu[PK!c=n==Gmconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/CSSList.phpnu[PK!eHettLconvertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/CSSBlockList.phpnu[PK!zzO}convertformstools/pdf/dompdf/lib/php-css-parser/src/CSSList/AtRuleBlockList.phpnu[PK!yW'Xvconvertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/UnexpectedTokenException.phpnu[PK!jyBffOconvertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/OutputException.phpnu[PK!44Kconvertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/ParserState.phpnu[PK!cܚ22Oconvertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/SourceException.phpnu[PK!qV]convertformstools/pdf/dompdf/lib/php-css-parser/src/Parsing/UnexpectedEOFException.phpnu[PK!,PRGconvertformstools/pdf/dompdf/lib/php-css-parser/src/OutputFormatter.phpnu[PK!@Iconvertformstools/pdf/dompdf/lib/php-css-parser/src/Settings.phpnu[PK!L((B`%convertformstools/pdf/dompdf/lib/php-css-parser/src/Renderable.phpnu[PK!TD&convertformstools/pdf/dompdf/lib/php-css-parser/src/OutputFormat.phpnu[PK!K''A Fconvertformstools/pdf/dompdf/lib/php-css-parser/src/Rule/Rule.phpnu[PK!**G*nconvertformstools/pdf/dompdf/lib/php-css-parser/src/RuleSet/RuleSet.phpnu[PK!|'ssPuconvertformstools/pdf/dompdf/lib/php-css-parser/src/RuleSet/DeclarationBlock.phpnu[PK![~I{ convertformstools/pdf/dompdf/lib/php-css-parser/src/RuleSet/AtRuleSet.phpnu[PK!QKGconvertformstools/pdf/dompdf/lib/php-css-parser/src/Comment/Comment.phpnu[PK!C!GKconvertformstools/pdf/dompdf/lib/php-css-parser/src/Comment/Commentable.phpnu[PK!0 Mconvertformstools/pdf/dompdf/lib/php-css-parser/src/Property/CSSNamespace.phpnu[PK!K$A H%convertformstools/pdf/dompdf/lib/php-css-parser/src/Property/Charset.phpnu[PK!) G/convertformstools/pdf/dompdf/lib/php-css-parser/src/Property/Import.phpnu[PK!Q9convertformstools/pdf/dompdf/lib/php-css-parser/src/Property/KeyframeSelector.phpnu[PK!\k k I$=convertformstools/pdf/dompdf/lib/php-css-parser/src/Property/Selector.phpnu[PK! EJ!!GKconvertformstools/pdf/dompdf/lib/php-css-parser/src/Property/AtRule.phpnu[PK!v__)Nconvertformstools/pdf/dompdf/lib/Cpdf.phpnu[PK!l-خconvertformstools/pdf/dompdf/lib/res/html.cssnu[PK!CEE5convertformstools/pdf/dompdf/lib/res/broken_image.svgnu[PK!Ɛjj5tconvertformstools/pdf/dompdf/lib/res/broken_image.pngnu[PK!0! ((,Cconvertformstools/pdf/dompdf/src/LineBox.phpnu[PK!P9nCnC0convertformstools/pdf/dompdf/src/FontMetrics.phpnu[PK!0W<u>convertformstools/pdf/dompdf/src/Frame/FrameTreeIterator.phpnu[PK!convertformstools/pdf/dompdf/src/FrameDecorator/ListBullet.phpnu[PK!PLL8sconvertformstools/pdf/dompdf/src/FrameDecorator/Text.phpnu[PK!$̋<'convertformstools/pdf/dompdf/src/FrameDecorator/TableRow.phpnu[PK!k#9convertformstools/pdf/dompdf/src/FrameDecorator/Block.phpnu[PK!aZ\ \ =yconvertformstools/pdf/dompdf/src/FrameDecorator/TableCell.phpnu[PK!Bdw 9Bconvertformstools/pdf/dompdf/src/FrameDecorator/Image.phpnu[PK!E@dd,Nconvertformstools/pdf/dompdf/src/Helpers.phpnu[PK!s<+convertformstools/pdf/dompdf/src/Dompdf.phpnu[PK!ζF> /convertformstools/pdf/dompdf/src/Positioner/NullPositioner.phpnu[PK!\]]B1convertformstools/pdf/dompdf/src/Positioner/AbstractPositioner.phpnu[PK! BTT5b6convertformstools/pdf/dompdf/src/Positioner/Fixed.phpnu[PK!]hQ6Econvertformstools/pdf/dompdf/src/Positioner/Inline.phpnu[PK!n9Q:Kconvertformstools/pdf/dompdf/src/Positioner/ListBullet.phpnu[PK!p8Qconvertformstools/pdf/dompdf/src/Positioner/TableRow.phpnu[PK!5Uconvertformstools/pdf/dompdf/src/Positioner/Block.phpnu[PK!qև8Yconvertformstools/pdf/dompdf/src/Positioner/Absolute.phpnu[PK!z9lconvertformstools/pdf/dompdf/src/Positioner/TableCell.phpnu[PK!omm,7oconvertformstools/pdf/dompdf/src/Cellmap.phpnu[PK!#t7)convertformstools/pdf/dompdf/src/JavascriptEmbedder.phpnu[PK!~))0aconvertformstools/pdf/dompdf/src/Image/Cache.phpnu[PK!l 3[ convertformstools/pdf/dompdf/src/Css/Stylesheet.phpnu[PK! ##.Qconvertformstools/pdf/dompdf/src/Css/Style.phpnu[PK!)ұdeEeE<Ҩconvertformstools/pdf/dompdf/src/Css/AttributeTranslator.phpnu[PK!p**.convertformstools/pdf/dompdf/src/Css/Color.phpnu[PK!L;convertformstools/pdf/dompdf/src/Renderer/TableRowGroup.phpnu[PK!A4convertformstools/pdf/dompdf/src/Renderer/Inline.phpnu[PK![3HH86convertformstools/pdf/dompdf/src/Renderer/ListBullet.phpnu[PK!T=>Rconvertformstools/pdf/dompdf/src/Renderer/AbstractRenderer.phpnu[PK! m2convertformstools/pdf/dompdf/src/Renderer/Text.phpnu[PK!b,%,%3convertformstools/pdf/dompdf/src/Renderer/Block.phpnu[PK!=++7convertformstools/pdf/dompdf/src/Renderer/TableCell.phpnu[PK!>a6 6 36)convertformstools/pdf/dompdf/src/Renderer/Image.phpnu[PK!i!{}{}*3convertformstools/pdf/dompdf/src/Frame.phpnu[PK!'t991convertformstools/pdf/dompdf/src/PhpEvaluator.phpnu[PK!{,XX.>convertformstools/pdf/dompdf/src/Exception.phpnu[PK! 11+convertformstools/pdf/dompdf/src/Canvas.phpnu[PK!F\2convertformstools/pdf/dompdf/src/CanvasFactory.phpnu[PK!B/yconvertformstools/pdf/dompdf/src/Autoloader.phpnu[PK!Z^L!!-\convertformstools/pdf/dompdf/src/Renderer.phpnu[PK! f f,?convertformstools/pdf/dompdf/src/Options.phpnu[PK!K}pp/~convertformstools/pdf/dompdf/src/Adapter/GD.phpnu[PK!=$Hg1convertformstools/pdf/dompdf/src/Adapter/CPDF.phpnu[PK!e.qq3rconvertformstools/pdf/dompdf/src/Adapter/PDFLib.phpnu[PK!0o&D0convertformstools/pdf/dompdf/src/FrameReflower/NullFrameReflower.phpnu[PK!:jd@4convertformstools/pdf/dompdf/src/FrameReflower/TableRowGroup.phpnu[PK!P\7<convertformstools/pdf/dompdf/src/FrameReflower/Page.phpnu[PK!€CC8Tconvertformstools/pdf/dompdf/src/FrameReflower/Table.phpnu[PK!ś|ee9convertformstools/pdf/dompdf/src/FrameReflower/Inline.phpnu[PK!8=Ȯconvertformstools/pdf/dompdf/src/FrameReflower/ListBullet.phpnu[PK!VxPP7ʳconvertformstools/pdf/dompdf/src/FrameReflower/Text.phpnu[PK!Jyy;convertformstools/pdf/dompdf/src/FrameReflower/TableRow.phpnu[PK!i>hpp8 convertformstools/pdf/dompdf/src/FrameReflower/Block.phpnu[PK!؊EE<convertformstools/pdf/dompdf/src/FrameReflower/TableCell.phpnu[PK!IXXHhconvertformstools/pdf/dompdf/src/FrameReflower/AbstractFrameReflower.phpnu[PK!68convertformstools/pdf/dompdf/src/FrameReflower/Image.phpnu[PK![,~~. convertformstools/pdf/fields/pdfsubmission.phpnu[PK!S99/(convertformstools/pdf/script.install.helper.phpnu[PK!RCc#c#ebconvertformstools/pdf/pdf.phpnu[PK!%(convertformstools/pdf/script.install.phpnu[PK!0B*<convertformstools/pdf/helper/pdfhelper.phpnu[PK!xkk3convertformstools/pdf/pdf.xmlnu[PK!,f**#convertformstools/pdf/form/form.xmlnu[PK!m-EE)hconvertformstools/pdf/form/submission.xmlnu[PK!OK__Tconvertformstools/gatracker/language/ru-RU/ru-RU.plg_convertformstools_gatracker.ininu[PK!Tconvertformstools/gatracker/language/ca-ES/ca-ES.plg_convertformstools_gatracker.ininu[PK!C-''Tconvertformstools/gatracker/language/bg-BG/bg-BG.plg_convertformstools_gatracker.ininu[PK!|_  T.convertformstools/gatracker/language/cs-CZ/cs-CZ.plg_convertformstools_gatracker.ininu[PK! ffTconvertformstools/gatracker/language/es-ES/es-ES.plg_convertformstools_gatracker.ininu[PK!?Bo=Tconvertformstools/gatracker/language/fi-FI/fi-FI.plg_convertformstools_gatracker.ininu[PK!qTconvertformstools/gatracker/language/en-GB/en-GB.plg_convertformstools_gatracker.ininu[PK!IsXfconvertformstools/gatracker/language/en-GB/en-GB.plg_convertformstools_gatracker.sys.ininu[PK!Tconvertformstools/gatracker/language/sv-SE/sv-SE.plg_convertformstools_gatracker.ininu[PK!Q.55Tconvertformstools/gatracker/language/uk-UA/uk-UA.plg_convertformstools_gatracker.ininu[PK!uVp,,Tconvertformstools/gatracker/language/fr-FR/fr-FR.plg_convertformstools_gatracker.ininu[PK!"$77T]convertformstools/gatracker/language/de-DE/de-DE.plg_convertformstools_gatracker.ininu[PK!,??Tconvertformstools/gatracker/language/it-IT/it-IT.plg_convertformstools_gatracker.ininu[PK!ohr995convertformstools/gatracker/script.install.helper.phpnu[PK!`>X)/convertformstools/gatracker/gatracker.xmlnu[PK!K8)4convertformstools/gatracker/gatracker.phpnu[PK!z(X.KCconvertformstools/gatracker/script.install.phpnu[PK!)Fconvertformstools/gatracker/form/form.xmlnu[PK!Q  bHconvertformstools/conditionallogic/language/ru-RU/ru-RU.plg_convertformstools_conditionallogic.ininu[PK!?ʈb(\convertformstools/conditionallogic/language/ca-ES/ca-ES.plg_convertformstools_conditionallogic.ininu[PK!59_bzlconvertformstools/conditionallogic/language/cs-CZ/cs-CZ.plg_convertformstools_conditionallogic.ininu[PK!b|convertformstools/conditionallogic/language/fi-FI/fi-FI.plg_convertformstools_conditionallogic.ininu[PK! 1f!convertformstools/conditionallogic/language/en-GB/en-GB.plg_convertformstools_conditionallogic.sys.ininu[PK!m hhbconvertformstools/conditionallogic/language/en-GB/en-GB.plg_convertformstools_conditionallogic.ininu[PK!I^\\b~convertformstools/conditionallogic/language/uk-UA/uk-UA.plg_convertformstools_conditionallogic.ininu[PK!)blconvertformstools/conditionallogic/language/fr-FR/fr-FR.plg_convertformstools_conditionallogic.ininu[PK!>>bconvertformstools/conditionallogic/language/de-DE/de-DE.plg_convertformstools_conditionallogic.ininu[PK![D22bconvertformstools/conditionallogic/language/it-IT/it-IT.plg_convertformstools_conditionallogic.ininu[PK!Z7Jconvertformstools/conditionallogic/conditionallogic.phpnu[PK!bppE`convertformstools/conditionallogic/fields/conditionallogicbuilder.phpnu[PK!&j~99<Econvertformstools/conditionallogic/script.install.helper.phpnu[PK!tC7=Sconvertformstools/conditionallogic/conditionallogic.xmlnu[PK!_"N5Wconvertformstools/conditionallogic/script.install.phpnu[PK! yNN0Zconvertformstools/conditionallogic/form/form.xmlnu[PK!Ձ66(^content/emailcloak/services/provider.phpnu[PK!y36!.dcontent/emailcloak/emailcloak.xmlnu[PK!I$N$N/icontent/emailcloak/src/Extension/EmailCloak.phpnu[PK!oGJ content/vote/vote.xmlnu[PK!QUQ""content/vote/services/provider.phpnu[PK!06OOcontent/vote/tmpl/vote.phpnu[PK!f +content/vote/tmpl/rating.phpnu[PK!4ZZ#]content/vote/src/Extension/Vote.phpnu[PK!!@\ \  content/pagebreak/pagebreak.xmlnu[PK!I@77'content/pagebreak/services/provider.phpnu[PK!c{%Ccontent/pagebreak/tmpl/navigation.phpnu[PK!ㆬQcontent/pagebreak/tmpl/toc.phpnu[PK!we0e0-<content/pagebreak/src/Extension/PageBreak.phpnu[PK!xw3content/igallery/igallery.phpnu[PK!8WQQ+Jcontent/igallery/igallery.xmlnu[PK!·GG'Mcontent/sppagebuilder/sppagebuilder.phpnu[PK!V$$#gmcontent/sppagebuilder/thumbnail.jpgnu[PK!MH++'ɑcontent/sppagebuilder/sppagebuilder.xmlnu[PK!ҁvrr!Kcontent/pingomatic/pingomatic.phpnu[PK!͢a!@content/pingomatic/pingomatic.xmlnu[PK!#o,,k content/pingomatic/index.htmlnu[PK!kd content/fields/fields.xmlnu[PK!$content/fields/services/provider.phpnu[PK!RȪ'content/fields/src/Extension/Fields.phpnu[PK!4,*content/pagenavigation/services/provider.phpnu[PK!*T)*0content/pagenavigation/pagenavigation.xmlnu[PK!d_))'P8content/pagenavigation/tmpl/default.phpnu[PK!!&&7>content/pagenavigation/src/Extension/PageNavigation.phpnu[PK!F3'fcontent/jce/jce.phpnu[PK!DKrhcontent/jce/jce.xmlnu[PK!Hx/!!$:lcontent/joomla/services/provider.phpnu[PK!{'^rcontent/joomla/joomla.xmlnu[PK!pJJ'ycontent/joomla/src/Extension/Joomla.phpnu[PK!^gZcontent/finder/finder.xmlnu[PK!U̪(($7content/finder/services/provider.phpnu[PK!/{'''content/finder/src/Extension/Finder.phpnu[PK!<<(1content/loadmodule/services/provider.phpnu[PK!p99!content/loadmodule/loadmodule.xmlnu[PK!F!!/Ocontent/loadmodule/src/Extension/LoadModule.phpnu[PK!m/Y%X content/contact/services/provider.phpnu[PK!(9Lcontent/contact/contact.xmlnu[PK!%})icontent/contact/src/Extension/Contact.phpnu[PK!`JJ,,content/confirmconsent/services/provider.phpnu[PK!u99 9 )2content/confirmconsent/confirmconsent.xmlnu[PK!'L 7<content/confirmconsent/src/Extension/ConfirmConsent.phpnu[PK!s))))4AFcontent/confirmconsent/src/Field/ConsentBoxField.phpnu[PK!:fB B 3ocaptcha/recaptcha_invisible/recaptcha_invisible.xmlnu[PK!yYT1s{captcha/recaptcha_invisible/services/provider.phpnu[PK! ˲oo@wcaptcha/recaptcha_invisible/src/Extension/InvisibleReCaptcha.phpnu[PK!S&editors/jce/layouts/editor/textarea.phpnu[PK!i'6editors/tinymce/tinymce.xmlnu[PK!t0%editors/tinymce/services/provider.phpnu[PK!wV!V!$"editors/tinymce/forms/setoptions.xmlnu[PK!_;OMM7Ceditors/tinymce/src/PluginTraits/ActiveSiteTemplate.phpnu[PK!g4E2lIeditors/tinymce/src/PluginTraits/GlobalFilters.phpnu[PK!5y y 3eeditors/tinymce/src/PluginTraits/ToolbarPresets.phpnu[PK! 1Z1Z1reditors/tinymce/src/PluginTraits/DisplayTrait.phpnu[PK!p /!editors/tinymce/src/PluginTraits/XTDButtons.phpnu[PK!~|1leditors/tinymce/src/PluginTraits/KnownButtons.phpnu[PK!Mq7 1\editors/tinymce/src/PluginTraits/ResolveFiles.phpnu[PK!P )editors/tinymce/src/Extension/TinyMCE.phpnu[PK!'  -editors/tinymce/src/Field/UploaddirsField.phpnu[PK!1& editors/tinymce/src/Field/TinymcebuilderField.phpnu[PK!v v 0Meditors/tinymce/src/Field/TemplateslistField.phpnu[PK!o77(#+editors/codemirror/services/provider.phpnu[PK!uWW80editors/codemirror/layouts/editors/codemirror/styles.phpnu[PK!z 9q8editors/codemirror/layouts/editors/codemirror/element.phpnu[PK! P%P%!Deditors/codemirror/codemirror.xmlnu[PK!J Wjeditors/codemirror/fonts.jsonnu[PK!zj3u)u)/yweditors/codemirror/src/Extension/Codemirror.phpnu[PK!CC+Meditors/codemirror/src/Field/FontsField.phpnu[PK!7"editors/none/services/provider.phpnu[PK!HtNnJJ#Veditors/none/src/Extension/None.phpnu[PK!wFFeditors/none/none.xmlnu[PK!?yy~installer/override/override.xmlnu[PK!c;(Finstaller/override/services/provider.phpnu[PK!behaviour/versionable/services/provider.phpnu[PK!ѐ%Dbehaviour/versionable/versionable.xmlnu[PK!7}aEE3Hbehaviour/versionable/src/Extension/Versionable.phpnu[PK!J''LmZconvertforms/convertkit/language/ru-RU/ru-RU.plg_convertforms_convertkit.ininu[PK!convertforms/zoho/zoho.xmlnu[PK!BVFAconvertforms/hubspot/language/ru-RU/ru-RU.plg_convertforms_hubspot.ininu[PK!o]]FDconvertforms/hubspot/language/ca-ES/ca-ES.plg_convertforms_hubspot.ininu[PK! FGconvertforms/hubspot/language/bg-BG/bg-BG.plg_convertforms_hubspot.ininu[PK!:VPJJFJconvertforms/hubspot/language/cs-CZ/cs-CZ.plg_convertforms_hubspot.ininu[PK! nzzFxMconvertforms/hubspot/language/es-ES/es-ES.plg_convertforms_hubspot.ininu[PK!5A99FhPconvertforms/hubspot/language/fi-FI/fi-FI.plg_convertforms_hubspot.ininu[PK!c;;FSconvertforms/hubspot/language/en-GB/en-GB.plg_convertforms_hubspot.ininu[PK!ssJUconvertforms/hubspot/language/en-GB/en-GB.plg_convertforms_hubspot.sys.ininu[PK!IFWconvertforms/hubspot/language/uk-UA/uk-UA.plg_convertforms_hubspot.ininu[PK!euFZconvertforms/hubspot/language/fr-FR/fr-FR.plg_convertforms_hubspot.ininu[PK!(TTF]convertforms/hubspot/language/de-DE/de-DE.plg_convertforms_hubspot.ininu[PK!4fQQF`convertforms/hubspot/language/it-IT/it-IT.plg_convertforms_hubspot.ininu[PK!6dcconvertforms/hubspot/form.xmlnu[PK!`L~9~9.econvertforms/hubspot/script.install.helper.phpnu[PK!0$$ nconvertforms/hubspot/hubspot.xmlnu[PK!vdZ'convertforms/hubspot/script.install.phpnu[PK!:  convertforms/hubspot/hubspot.phpnu[PK!.ĕM M D5convertforms/aweber/language/ru-RU/ru-RU.plg_convertforms_aweber.ininu[PK!dDconvertforms/aweber/language/ca-ES/ca-ES.plg_convertforms_aweber.ininu[PK! 2Dconvertforms/aweber/language/bg-BG/bg-BG.plg_convertforms_aweber.ininu[PK!NvTTDKconvertforms/aweber/language/cs-CZ/cs-CZ.plg_convertforms_aweber.ininu[PK!oyDconvertforms/aweber/language/es-ES/es-ES.plg_convertforms_aweber.ininu[PK!7DzDconvertforms/aweber/language/fi-FI/fi-FI.plg_convertforms_aweber.ininu[PK!4...Dconvertforms/aweber/language/en-GB/en-GB.plg_convertforms_aweber.ininu[PK!fuooHDconvertforms/aweber/language/en-GB/en-GB.plg_convertforms_aweber.sys.ininu[PK!\vD488D+convertforms/aweber/language/sv-SE/sv-SE.plg_convertforms_aweber.ininu[PK!!&> > Dconvertforms/aweber/language/uk-UA/uk-UA.plg_convertforms_aweber.ininu[PK!֤Dconvertforms/aweber/language/fr-FR/fr-FR.plg_convertforms_aweber.ininu[PK! dDconvertforms/aweber/language/de-DE/de-DE.plg_convertforms_aweber.ininu[PK!O~~Dconvertforms/aweber/language/it-IT/it-IT.plg_convertforms_aweber.ininu[PK!,UCCconvertforms/aweber/aweber.xmlnu[PK!4*] convertforms/aweber/wrapper/exceptions.phpnu[PK!+\\,yconvertforms/aweber/wrapper/aweber_entry.phpnu[PK!b_""-18convertforms/aweber/wrapper/oauth_adapter.phpnu[PK!U8ؔ""*:convertforms/aweber/wrapper/aweber_api.phpnu[PK!KK1]convertforms/aweber/wrapper/oauth_application.phpnu[PK!/!ll/convertforms/aweber/wrapper/aweber_response.phpnu[PK!etU-Nconvertforms/aweber/wrapper/curl_response.phpnu[PK!Z +convertforms/aweber/wrapper/curl_object.phpnu[PK!7convertforms/aweber/wrapper/aweber_entry_data_array.phpnu[PK!ۡ=='Lconvertforms/aweber/wrapper/wrapper.phpnu[PK!"}g1convertforms/aweber/wrapper/aweber_collection.phpnu[PK!onH~ ~  convertforms/aweber/aweber.phpnu[PK!]7,convertforms/aweber/form.xmlnu[PK!T}9}9-convertforms/aweber/script.install.helper.phpnu[PK!n&~Oconvertforms/aweber/script.install.phpnu[PK!=hPRconvertforms/elasticemail/language/ru-RU/ru-RU.plg_convertforms_elasticemail.ininu[PK!PZconvertforms/elasticemail/language/ca-ES/ca-ES.plg_convertforms_elasticemail.ininu[PK!˷KTTPaconvertforms/elasticemail/language/bg-BG/bg-BG.plg_convertforms_elasticemail.ininu[PK!Phconvertforms/elasticemail/language/cs-CZ/cs-CZ.plg_convertforms_elasticemail.ininu[PK!NPoconvertforms/elasticemail/language/es-ES/es-ES.plg_convertforms_elasticemail.ininu[PK!&ssP7uconvertforms/elasticemail/language/fi-FI/fi-FI.plg_convertforms_elasticemail.ininu[PK!egSSP*{convertforms/elasticemail/language/en-GB/en-GB.plg_convertforms_elasticemail.ininu[PK!bʇTconvertforms/elasticemail/language/en-GB/en-GB.plg_convertforms_elasticemail.sys.ininu[PK!onjddPconvertforms/elasticemail/language/uk-UA/uk-UA.plg_convertforms_elasticemail.ininu[PK!Pconvertforms/elasticemail/language/fr-FR/fr-FR.plg_convertforms_elasticemail.ininu[PK!00_PBconvertforms/elasticemail/language/de-DE/de-DE.plg_convertforms_elasticemail.ininu[PK!Pconvertforms/elasticemail/language/it-IT/it-IT.plg_convertforms_elasticemail.ininu[PK!cb "convertforms/elasticemail/form.xmlnu[PK!x993 convertforms/elasticemail/script.install.helper.phpnu[PK!?*convertforms/elasticemail/elasticemail.phpnu[PK!,convertforms/elasticemail/script.install.phpnu[PK!n88*Oconvertforms/elasticemail/elasticemail.xmlnu[PK!G!ddDconvertforms/drip/language/en-GB/en-GB.plg_convertforms_drip.sys.ininu[PK!C@convertforms/drip/language/en-GB/en-GB.plg_convertforms_drip.ininu[PK!לconvertforms/drip/form.xmlnu[PK!W{9{9+convertforms/drip/script.install.helper.phpnu[PK!:__4convertforms/drip/drip.phpnu[PK!![}9convertforms/drip/drip.xmlnu[PK!/$<convertforms/drip/script.install.phpnu[PK!y9=T?convertforms/activecampaign/language/ru-RU/ru-RU.plg_convertforms_activecampaign.ininu[PK!??T\Gconvertforms/activecampaign/language/ca-ES/ca-ES.plg_convertforms_activecampaign.ininu[PK!HHTMconvertforms/activecampaign/language/bg-BG/bg-BG.plg_convertforms_activecampaign.ininu[PK!l;;TSconvertforms/activecampaign/language/cs-CZ/cs-CZ.plg_convertforms_activecampaign.ininu[PK!YeeTYconvertforms/activecampaign/language/es-ES/es-ES.plg_convertforms_activecampaign.ininu[PK!Ty..T_convertforms/activecampaign/language/fi-FI/fi-FI.plg_convertforms_activecampaign.ininu[PK!{TEeconvertforms/activecampaign/language/en-GB/en-GB.plg_convertforms_activecampaign.ininu[PK!FǰXjconvertforms/activecampaign/language/en-GB/en-GB.plg_convertforms_activecampaign.sys.ininu[PK!qχ %%Tlconvertforms/activecampaign/language/sv-SE/sv-SE.plg_convertforms_activecampaign.ininu[PK!k[>>Trconvertforms/activecampaign/language/nl-NL/nl-NL.plg_convertforms_activecampaign.ininu[PK! TLxconvertforms/activecampaign/language/uk-UA/uk-UA.plg_convertforms_activecampaign.ininu[PK!?0rTconvertforms/activecampaign/language/fr-FR/fr-FR.plg_convertforms_activecampaign.ininu[PK!JL3XXTconvertforms/activecampaign/language/de-DE/de-DE.plg_convertforms_activecampaign.ininu[PK!E++Tconvertforms/activecampaign/language/it-IT/it-IT.plg_convertforms_activecampaign.ininu[PK!e+CC.convertforms/activecampaign/activecampaign.xmlnu[PK!(vv$Dconvertforms/activecampaign/form.xmlnu[PK!ɯq995convertforms/activecampaign/script.install.helper.phpnu[PK!Q5.convertforms/activecampaign/script.install.phpnu[PK!'1.7convertforms/activecampaign/activecampaign.phpnu[PK!(L6convertforms/salesforce/language/ru-RU/ru-RU.plg_convertforms_salesforce.ininu[PK!:33Lconvertforms/salesforce/language/ca-ES/ca-ES.plg_convertforms_salesforce.ininu[PK!gDLconvertforms/salesforce/language/bg-BG/bg-BG.plg_convertforms_salesforce.ininu[PK!धLconvertforms/salesforce/language/cs-CZ/cs-CZ.plg_convertforms_salesforce.ininu[PK!YKKLXconvertforms/salesforce/language/es-ES/es-ES.plg_convertforms_salesforce.ininu[PK!#0;  Lconvertforms/salesforce/language/fi-FI/fi-FI.plg_convertforms_salesforce.ininu[PK!91Lconvertforms/salesforce/language/en-GB/en-GB.plg_convertforms_salesforce.ininu[PK!LvvP>convertforms/salesforce/language/en-GB/en-GB.plg_convertforms_salesforce.sys.ininu[PK!aDGL4convertforms/salesforce/language/uk-UA/uk-UA.plg_convertforms_salesforce.ininu[PK!@>>Lconvertforms/salesforce/language/fr-FR/fr-FR.plg_convertforms_salesforce.ininu[PK!-22Lpconvertforms/salesforce/language/de-DE/de-DE.plg_convertforms_salesforce.ininu[PK!HڿsHHLconvertforms/salesforce/language/it-IT/it-IT.plg_convertforms_salesforce.ininu[PK!8   convertforms/salesforce/form.xmlnu[PK!833&J convertforms/salesforce/salesforce.xmlnu[PK!r;991convertforms/salesforce/script.install.helper.phpnu[PK!];ڸ*Jconvertforms/salesforce/script.install.phpnu[PK!&Mconvertforms/salesforce/salesforce.phpnu[PK!Y.)88V5Qconvertforms/campaignmonitor/language/ru-RU/ru-RU.plg_convertforms_campaignmonitor.ininu[PK!uLLVUconvertforms/campaignmonitor/language/ca-ES/ca-ES.plg_convertforms_campaignmonitor.ininu[PK!$VYconvertforms/campaignmonitor/language/bg-BG/bg-BG.plg_convertforms_campaignmonitor.ininu[PK! $99V]convertforms/campaignmonitor/language/cs-CZ/cs-CZ.plg_convertforms_campaignmonitor.ininu[PK![ZaaVaconvertforms/campaignmonitor/language/es-ES/es-ES.plg_convertforms_campaignmonitor.ininu[PK!qP  Veconvertforms/campaignmonitor/language/fi-FI/fi-FI.plg_convertforms_campaignmonitor.ininu[PK!Ȓ1v$$VFiconvertforms/campaignmonitor/language/en-GB/en-GB.plg_convertforms_campaignmonitor.ininu[PK!ՐZlconvertforms/campaignmonitor/language/en-GB/en-GB.plg_convertforms_campaignmonitor.sys.ininu[PK!AVoconvertforms/campaignmonitor/language/uk-UA/uk-UA.plg_convertforms_campaignmonitor.ininu[PK!vDs˦Vsconvertforms/campaignmonitor/language/fr-FR/fr-FR.plg_convertforms_campaignmonitor.ininu[PK!МGGVwconvertforms/campaignmonitor/language/de-DE/de-DE.plg_convertforms_campaignmonitor.ininu[PK!$??V{convertforms/campaignmonitor/language/it-IT/it-IT.plg_convertforms_campaignmonitor.ininu[PK!\@xx0Lconvertforms/campaignmonitor/campaignmonitor.phpnu[PK!I=#FF0$convertforms/campaignmonitor/campaignmonitor.xmlnu[PK! b%ʆconvertforms/campaignmonitor/form.xmlnu[PK!]Kg996convertforms/campaignmonitor/script.install.helper.phpnu[PK!HQ/convertforms/campaignmonitor/script.install.phpnu[PK!oPPHLconvertforms/icontact/language/ru-RU/ru-RU.plg_convertforms_icontact.ininu[PK!Q#[nHconvertforms/icontact/language/ca-ES/ca-ES.plg_convertforms_icontact.ininu[PK!𤹙11HRconvertforms/icontact/language/bg-BG/bg-BG.plg_convertforms_icontact.ininu[PK!eHconvertforms/icontact/language/cs-CZ/cs-CZ.plg_convertforms_icontact.ininu[PK!6;Hconvertforms/icontact/language/es-ES/es-ES.plg_convertforms_icontact.ininu[PK!13HZconvertforms/icontact/language/fi-FI/fi-FI.plg_convertforms_icontact.ininu[PK!|[hhHfconvertforms/icontact/language/en-GB/en-GB.plg_convertforms_icontact.ininu[PK!UN4wwLFconvertforms/icontact/language/en-GB/en-GB.plg_convertforms_icontact.sys.ininu[PK!yNNH9convertforms/icontact/language/uk-UA/uk-UA.plg_convertforms_icontact.ininu[PK!G0Hconvertforms/icontact/language/fr-FR/fr-FR.plg_convertforms_icontact.ininu[PK!<Hxconvertforms/icontact/language/de-DE/de-DE.plg_convertforms_icontact.ininu[PK!h Hconvertforms/icontact/language/it-IT/it-IT.plg_convertforms_icontact.ininu[PK!2convertforms/icontact/form.xmlnu[PK!4@99/ convertforms/icontact/script.install.helper.phpnu[PK!s!(("Fconvertforms/icontact/icontact.xmlnu[PK!9X6 6 "Jconvertforms/icontact/icontact.phpnu[PK!+(Sconvertforms/icontact/script.install.phpnu[PK!JVconvertforms/mailchimp/language/ru-RU/ru-RU.plg_convertforms_mailchimp.ininu[PK!^nJ\convertforms/mailchimp/language/ca-ES/ca-ES.plg_convertforms_mailchimp.ininu[PK!m[J`convertforms/mailchimp/language/bg-BG/bg-BG.plg_convertforms_mailchimp.ininu[PK!6 lJeconvertforms/mailchimp/language/cs-CZ/cs-CZ.plg_convertforms_mailchimp.ininu[PK!2J9jconvertforms/mailchimp/language/es-ES/es-ES.plg_convertforms_mailchimp.ininu[PK!<^Jnconvertforms/mailchimp/language/fi-FI/fi-FI.plg_convertforms_mailchimp.ininu[PK!PjJ$sconvertforms/mailchimp/language/en-GB/en-GB.plg_convertforms_mailchimp.ininu[PK!NpNowconvertforms/mailchimp/language/en-GB/en-GB.plg_convertforms_mailchimp.sys.ininu[PK!kJpyconvertforms/mailchimp/language/uk-UA/uk-UA.plg_convertforms_mailchimp.ininu[PK!EEJ~convertforms/mailchimp/language/fr-FR/fr-FR.plg_convertforms_mailchimp.ininu[PK!Jcconvertforms/mailchimp/language/de-DE/de-DE.plg_convertforms_mailchimp.ininu[PK!Jconvertforms/mailchimp/language/it-IT/it-IT.plg_convertforms_mailchimp.ininu[PK!5Nconvertforms/mailchimp/form.xmlnu[PK!ܺr990?convertforms/mailchimp/script.install.helper.phpnu[PK!^d$convertforms/mailchimp/mailchimp.phpnu[PK! [k>)convertforms/mailchimp/script.install.phpnu[PK!}//$convertforms/mailchimp/mailchimp.xmlnu[PK!̜Fconvertforms/zohocrm/language/ru-RU/ru-RU.plg_convertforms_zohocrm.ininu[PK!Fconvertforms/zohocrm/language/ca-ES/ca-ES.plg_convertforms_zohocrm.ininu[PK!6Fconvertforms/zohocrm/language/bg-BG/bg-BG.plg_convertforms_zohocrm.ininu[PK!A||Fconvertforms/zohocrm/language/cs-CZ/cs-CZ.plg_convertforms_zohocrm.ininu[PK!Fconvertforms/zohocrm/language/es-ES/es-ES.plg_convertforms_zohocrm.ininu[PK! [CbEEFVconvertforms/zohocrm/language/fi-FI/fi-FI.plg_convertforms_zohocrm.ininu[PK!*A66Fconvertforms/zohocrm/language/en-GB/en-GB.plg_convertforms_zohocrm.ininu[PK!YҀ\\J convertforms/zohocrm/language/en-GB/en-GB.plg_convertforms_zohocrm.sys.ininu[PK!BV(Fconvertforms/zohocrm/language/uk-UA/uk-UA.plg_convertforms_zohocrm.ininu[PK!C,QFconvertforms/zohocrm/language/fr-FR/fr-FR.plg_convertforms_zohocrm.ininu[PK!MB}F"convertforms/zohocrm/language/de-DE/de-DE.plg_convertforms_zohocrm.ininu[PK!ץFd&convertforms/zohocrm/language/it-IT/it-IT.plg_convertforms_zohocrm.ininu[PK!>S S -convertforms/zohocrm/form.xmlnu[PK!X~9~9.-7convertforms/zohocrm/script.install.helper.phpnu[PK!5&&  qconvertforms/zohocrm/zohocrm.xmlnu[PK!yU'tconvertforms/zohocrm/script.install.phpnu[PK!&NAZ wconvertforms/zohocrm/zohocrm.phpnu[PK![4E``N}convertforms/getresponse/language/ru-RU/ru-RU.plg_convertforms_getresponse.ininu[PK!Ԕ77Nconvertforms/getresponse/language/ca-ES/ca-ES.plg_convertforms_getresponse.ininu[PK!e<<NPconvertforms/getresponse/language/bg-BG/bg-BG.plg_convertforms_getresponse.ininu[PK!YUN convertforms/getresponse/language/cs-CZ/cs-CZ.plg_convertforms_getresponse.ininu[PK!R=BBNconvertforms/getresponse/language/es-ES/es-ES.plg_convertforms_getresponse.ininu[PK!p$:NKconvertforms/getresponse/language/fi-FI/fi-FI.plg_convertforms_getresponse.ininu[PK!|.Nכconvertforms/getresponse/language/en-GB/en-GB.plg_convertforms_getresponse.ininu[PK!)RCconvertforms/getresponse/language/en-GB/en-GB.plg_convertforms_getresponse.sys.ininu[PK!@ NRconvertforms/getresponse/language/nl-NL/nl-NL.plg_convertforms_getresponse.ininu[PK!LUI((Nߦconvertforms/getresponse/language/uk-UA/uk-UA.plg_convertforms_getresponse.ininu[PK!Rda=Nconvertforms/getresponse/language/fr-FR/fr-FR.plg_convertforms_getresponse.ininu[PK!6IINconvertforms/getresponse/language/de-DE/de-DE.plg_convertforms_getresponse.ininu[PK!#ȴNNKconvertforms/getresponse/language/it-IT/it-IT.plg_convertforms_getresponse.ininu[PK!Cww!ںconvertforms/getresponse/form.xmlnu[PK!6$ڂ992convertforms/getresponse/script.install.helper.phpnu[PK!YSb(convertforms/getresponse/getresponse.phpnu[PK!g V77(convertforms/getresponse/getresponse.xmlnu[PK!+\convertforms/getresponse/script.install.phpnu[PK!SENconvertforms/errorlogger/language/ru-RU/ru-RU.plg_convertforms_errorlogger.ininu[PK!@ߧNconvertforms/errorlogger/language/ca-ES/ca-ES.plg_convertforms_errorlogger.ininu[PK!@k5N convertforms/errorlogger/language/bg-BG/bg-BG.plg_convertforms_errorlogger.ininu[PK!{N convertforms/errorlogger/language/cs-CZ/cs-CZ.plg_convertforms_errorlogger.ininu[PK!0ɦN convertforms/errorlogger/language/es-ES/es-ES.plg_convertforms_errorlogger.ininu[PK!͜N4convertforms/errorlogger/language/fi-FI/fi-FI.plg_convertforms_errorlogger.ininu[PK!xdNcconvertforms/errorlogger/language/en-GB/en-GB.plg_convertforms_errorlogger.ininu[PK!xdRuconvertforms/errorlogger/language/en-GB/en-GB.plg_convertforms_errorlogger.sys.ininu[PK!KNconvertforms/errorlogger/language/nl-NL/nl-NL.plg_convertforms_errorlogger.ininu[PK!_VNconvertforms/errorlogger/language/uk-UA/uk-UA.plg_convertforms_errorlogger.ininu[PK!dNKconvertforms/errorlogger/language/fr-FR/fr-FR.plg_convertforms_errorlogger.ininu[PK!:|Nconvertforms/errorlogger/language/de-DE/de-DE.plg_convertforms_errorlogger.ininu[PK!@dNconvertforms/errorlogger/language/it-IT/it-IT.plg_convertforms_errorlogger.ininu[PK!jV992!convertforms/errorlogger/script.install.helper.phpnu[PK!A?9 9 ([convertforms/errorlogger/errorlogger.phpnu[PK!+@econvertforms/errorlogger/script.install.phpnu[PK!w(phconvertforms/errorlogger/errorlogger.xmlnu[PK!GffLkconvertforms/acymailing/language/ru-RU/ru-RU.plg_convertforms_acymailing.ininu[PK!aRLqconvertforms/acymailing/language/ca-ES/ca-ES.plg_convertforms_acymailing.ininu[PK!+?uLvconvertforms/acymailing/language/bg-BG/bg-BG.plg_convertforms_acymailing.ininu[PK! KLT{convertforms/acymailing/language/cs-CZ/cs-CZ.plg_convertforms_acymailing.ininu[PK!)DLconvertforms/acymailing/language/es-ES/es-ES.plg_convertforms_acymailing.ininu[PK! 5;Lconvertforms/acymailing/language/fi-FI/fi-FI.plg_convertforms_acymailing.ininu[PK!kHppL.convertforms/acymailing/language/en-GB/en-GB.plg_convertforms_acymailing.ininu[PK!pqPconvertforms/acymailing/language/en-GB/en-GB.plg_convertforms_acymailing.sys.ininu[PK!$Lconvertforms/acymailing/language/sv-SE/sv-SE.plg_convertforms_acymailing.ininu[PK!H_00LLconvertforms/acymailing/language/uk-UA/uk-UA.plg_convertforms_acymailing.ininu[PK!:ݥLconvertforms/acymailing/language/fr-FR/fr-FR.plg_convertforms_acymailing.ininu[PK!&,Lconvertforms/acymailing/language/de-DE/de-DE.plg_convertforms_acymailing.ininu[PK!D6L convertforms/acymailing/language/it-IT/it-IT.plg_convertforms_acymailing.ininu[PK!  Iconvertforms/acymailing/form.xmlnu[PK! 991Zconvertforms/acymailing/script.install.helper.phpnu[PK!&<convertforms/acymailing/acymailing.phpnu[PK!T6#*convertforms/acymailing/script.install.phpnu[PK!T4(kk"convertforms/acymailing/helper.phpnu[PK!#fWWW&xconvertforms/acymailing/acymailing.xmlnu[PK!?4TTD%convertforms/emails/language/ru-RU/ru-RU.plg_convertforms_emails.ininu[PK!'ԏDconvertforms/emails/language/ca-ES/ca-ES.plg_convertforms_emails.ininu[PK!}kkD convertforms/emails/language/pt-BR/pt-BR.plg_convertforms_emails.ininu[PK!\AADconvertforms/emails/language/bg-BG/bg-BG.plg_convertforms_emails.ininu[PK!IffDconvertforms/emails/language/cs-CZ/cs-CZ.plg_convertforms_emails.ininu[PK!,rrD^convertforms/emails/language/es-ES/es-ES.plg_convertforms_emails.ininu[PK!+mIIDDconvertforms/emails/language/fi-FI/fi-FI.plg_convertforms_emails.ininu[PK!<G%%D!convertforms/emails/language/en-GB/en-GB.plg_convertforms_emails.ininu[PK!u7iiH$convertforms/emails/language/en-GB/en-GB.plg_convertforms_emails.sys.ininu[PK!` 44D{&convertforms/emails/language/nl-NL/nl-NL.plg_convertforms_emails.ininu[PK!D#*convertforms/emails/language/uk-UA/uk-UA.plg_convertforms_emails.ininu[PK!Z4@@DE/convertforms/emails/language/fr-FR/fr-FR.plg_convertforms_emails.ininu[PK!UUD2convertforms/emails/language/de-DE/de-DE.plg_convertforms_emails.ininu[PK!z[JJD6convertforms/emails/language/it-IT/it-IT.plg_convertforms_emails.ininu[PK!9}9}9-:convertforms/emails/script.install.helper.phpnu[PK!   Ztconvertforms/emails/emails.xmlnu[PK!Wd&wconvertforms/emails/script.install.phpnu[PK!a]o!o!zconvertforms/emails/emails.phpnu[PK!tww#convertforms/emails/form/fields.xmlnu[PK! R4UU!fconvertforms/emails/form/form.xmlnu[PK!P:**- convertforms/emails/form/fields/cfsubform.phpnu[PK!FLconvertforms/sendinblue/language/ru-RU/ru-RU.plg_convertforms_sendinblue.ininu[PK!wVLconvertforms/sendinblue/language/ca-ES/ca-ES.plg_convertforms_sendinblue.ininu[PK!lrLӶconvertforms/sendinblue/language/bg-BG/bg-BG.plg_convertforms_sendinblue.ininu[PK!睝Lconvertforms/sendinblue/language/cs-CZ/cs-CZ.plg_convertforms_sendinblue.ininu[PK!ɱLconvertforms/sendinblue/language/es-ES/es-ES.plg_convertforms_sendinblue.ininu[PK!(iiLconvertforms/sendinblue/language/fi-FI/fi-FI.plg_convertforms_sendinblue.ininu[PK!cl0Pconvertforms/sendinblue/language/en-GB/en-GB.plg_convertforms_sendinblue.sys.ininu[PK!oLconvertforms/sendinblue/language/en-GB/en-GB.plg_convertforms_sendinblue.ininu[PK!Lo>Lconvertforms/sendinblue/language/uk-UA/uk-UA.plg_convertforms_sendinblue.ininu[PK!PYL-convertforms/sendinblue/language/fr-FR/fr-FR.plg_convertforms_sendinblue.ininu[PK!͖L\convertforms/sendinblue/language/de-DE/de-DE.plg_convertforms_sendinblue.ininu[PK!P5}}Lkconvertforms/sendinblue/language/it-IT/it-IT.plg_convertforms_sendinblue.ininu[PK!sRR dconvertforms/sendinblue/form.xmlnu[PK!!#991convertforms/sendinblue/script.install.helper.phpnu[PK!{*!convertforms/sendinblue/script.install.phpnu[PK!^00&%convertforms/sendinblue/sendinblue.xmlnu[PK! &(convertforms/sendinblue/sendinblue.phpnu[PK! %.privacy/content/services/provider.phpnu[PK!)4privacy/content/src/Extension/Content.phpnu[PK!2"n``#=privacy/content/content.xmlnu[PK!!NN@privacy/user/user.xmlnu[PK!ޒu$"aDprivacy/user/services/provider.phpnu[PK!֔)UJprivacy/user/src/Extension/UserPlugin.phpnu[PK!I1b%`fprivacy/message/services/provider.phpnu[PK!{ ``Zlprivacy/message/message.xmlnu[PK!q')pprivacy/message/src/Extension/Message.phpnu[PK!@Cc%Exprivacy/contact/services/provider.phpnu[PK!L```?~privacy/contact/contact.xmlnu[PK!Sݒ  )privacy/contact/src/Extension/Contact.phpnu[PK!*3rr!Sprivacy/actionlogs/actionlogs.xmlnu[PK!H(privacy/actionlogs/services/provider.phpnu[PK!U  /"privacy/actionlogs/src/Extension/Actionlogs.phpnu[PK!,p&privacy/consents/services/provider.phpnu[PK!;ffprivacy/consents/consents.xmlnu[PK!1+Qprivacy/consents/src/Extension/Consents.phpnu[PK!iMM&:search/sppagebuilder/sppagebuilder.phpnu[PK!oHYY&search/sppagebuilder/sppagebuilder.xmlnu[PK!i-:#nnsearch/easyblog/easyblog.xmlnu[PK!ja&&Fsearch/easyblog/easyblog.phpnu[PK!Vsearch/easyblog/index.htmlnu[PK!V66)|media-action/resize/services/provider.phpnu[PK!ݦ media-action/resize/resize.xmlnu[PK!,Q!!,media-action/resize/src/Extension/Resize.phpnu[PK!HAA#|media-action/resize/form/resize.xmlnu[PK!X66) media-action/rotate/services/provider.phpnu[PK!\0Amedia-action/rotate/rotate.xmlnu[PK!a`BB,|media-action/rotate/src/Extension/Rotate.phpnu[PK!4XX#media-action/rotate/form/rotate.xmlnu[PK!H*media-action/crop/crop.xmlnu[PK!6,,'media-action/crop/services/provider.phpnu[PK!}(#media-action/crop/src/Extension/Crop.phpnu[PK!{ { (media-action/crop/form/crop.xmlnu[PKww82