Your IP : 216.73.217.68


Current Path : /home/w/u/e/wuectly/www/03cbe/
Upload File :
Current File : /home/w/u/e/wuectly/www/03cbe/helpers.zip

PKAt!]��M�TT	route.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_content
 *
 * @copyright   (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Content Component Route Helper.
 *
 * @since  1.5
 */
abstract class ContentHelperRoute
{
	/**
	 * Get the article route.
	 *
	 * @param   integer  $id        The route of the content item.
	 * @param   integer  $catid     The category ID.
	 * @param   integer  $language  The language code.
	 * @param   string   $layout    The layout value.
	 *
	 * @return  string  The article route.
	 *
	 * @since   1.5
	 */
	public static function getArticleRoute($id, $catid = 0, $language = 0, $layout = null)
	{
		// Create the link
		$link = 'index.php?option=com_content&view=article&id=' . $id;

		if ((int) $catid > 1)
		{
			$link .= '&catid=' . $catid;
		}

		if ($language && $language !== '*' && JLanguageMultilang::isEnabled())
		{
			$link .= '&lang=' . $language;
		}

		if ($layout)
		{
			$link .= '&layout=' . $layout;
		}

		return $link;
	}

	/**
	 * Get the category route.
	 *
	 * @param   integer  $catid     The category ID.
	 * @param   integer  $language  The language code.
	 * @param   string   $layout    The layout value.
	 *
	 * @return  string  The article route.
	 *
	 * @since   1.5
	 */
	public static function getCategoryRoute($catid, $language = 0, $layout = null)
	{
		if ($catid instanceof JCategoryNode)
		{
			$id = $catid->id;
		}
		else
		{
			$id = (int) $catid;
		}

		if ($id < 1)
		{
			return '';
		}

		$link = 'index.php?option=com_content&view=category&id=' . $id;

		if ($language && $language !== '*' && JLanguageMultilang::isEnabled())
		{
			$link .= '&lang=' . $language;
		}

		if ($layout)
		{
			$link .= '&layout=' . $layout;
		}

		return $link;
	}

	/**
	 * Get the form route.
	 *
	 * @param   integer  $id  The form ID.
	 *
	 * @return  string  The article route.
	 *
	 * @since   1.5
	 */
	public static function getFormRoute($id)
	{
		return 'index.php?option=com_content&task=article.edit&a_id=' . (int) $id;
	}
}
PKBt!]�1Q���xmap.phpnu&1i�<?php
/**
 * @version     $Id$
 * @copyright   Copyright (C) 2007 - 2009 Joomla! Vargas. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 * @author      Guillermo Vargas (guille@vargas.co.cr)
 */


// No direct access
defined('_JEXEC') or die;

/**
 * Xmap component helper.
 *
 * @package     Xmap
 * @subpackage  com_xmap
 * @since       2.0
 */
class XmapHelper
{
    /**
     * Configure the Linkbar.
     *
     * @param    string  The name of the active view.
     */
    public static function addSubmenu($vName)
    {
        $version = new JVersion;

        if (version_compare($version->getShortVersion(), '3.0.0', '<')) {
            JSubMenuHelper::addEntry(
                JText::_('Xmap_Submenu_Sitemaps'),
                'index.php?option=com_xmap',
                $vName == 'sitemaps'
            );
            JSubMenuHelper::addEntry(
                JText::_('Xmap_Submenu_Extensions'),
                'index.php?option=com_plugins&view=plugins&filter_folder=xmap',
                $vName == 'extensions');
        } else {
            JHtmlSidebar::addEntry(
                JText::_('Xmap_Submenu_Sitemaps'),
                'index.php?option=com_xmap',
                $vName == 'sitemaps'
            );
            JHtmlSidebar::addEntry(
                JText::_('Xmap_Submenu_Extensions'),
                'index.php?option=com_plugins&view=plugins&filter_folder=xmap',
                $vName == 'extensions');
        }
    }
}
PKBt!]�#o,,
index.htmlnu&1i�<html><body bgcolor="#FFFFFF"></body></html>PK�t!]8�'��
mailto.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_mailto
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Mailto route helper class.
 *
 * @package     Joomla.Site
 * @subpackage  com_mailto
 * @since       1.6.1
 */
abstract class MailtoHelper
{
	/**
	 * Adds a URL to the mailto system and returns the hash
	 *
	 * @param   string  $url  Url
	 *
	 * @return  string  URL hash
	 */
	public static function addLink($url)
	{
		$hash = sha1($url);
		self::cleanHashes();

		$session      = JFactory::getSession();
		$mailto_links = $session->get('com_mailto.links', array());

		if (!isset($mailto_links[$hash]))
		{
			$mailto_links[$hash] = new stdClass;
		}

		$mailto_links[$hash]->link   = $url;
		$mailto_links[$hash]->expiry = time();
		$session->set('com_mailto.links', $mailto_links);

		return $hash;
	}

	/**
	 * Checks if a URL is a Flash file
	 *
	 * @param   string  $hash  File hash
	 *
	 * @return URL
	 */
	public static function validateHash($hash)
	{
		$retval  = false;
		$session = JFactory::getSession();

		self::cleanHashes();
		$mailto_links = $session->get('com_mailto.links', array());

		if (isset($mailto_links[$hash]))
		{
			$retval = $mailto_links[$hash]->link;
		}

		return $retval;
	}

	/**
	 * Cleans out old hashes
	 *
	 * @param   integer  $lifetime  How old are the hashes we want to remove
	 *
	 * @return  void
	 *
	 * @since 1.6.1
	 */
	public static function cleanHashes($lifetime = 1440)
	{
		// Flag for if we've cleaned on this cycle
		static $cleaned = false;

		if (!$cleaned)
		{
			$past         = time() - $lifetime;
			$session      = JFactory::getSession();
			$mailto_links = $session->get('com_mailto.links', array());

			foreach ($mailto_links as $index => $link)
			{
				if ($link->expiry < $past)
				{
					unset($mailto_links[$index]);
				}
			}

			$session->set('com_mailto.links', $mailto_links);
			$cleaned = true;
		}
	}
}
PK�z!]u#ų�M�M
fields.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_fields
 *
 * @copyright   (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
defined('_JEXEC') or die;

JLoader::register('JFolder', JPATH_LIBRARIES . '/joomla/filesystem/folder.php');

/**
 * FieldsHelper
 *
 * @since  3.7.0
 */
class FieldsHelper
{
	private static $fieldsCache = null;

	private static $fieldCache = null;

	/**
	 * Extracts the component and section from the context string which has to
	 * be in the format component.context.
	 *
	 * @param   string  $contextString  contextString
	 * @param   object  $item           optional item object
	 *
	 * @return  array|null
	 *
	 * @since   3.7.0
	 */
	public static function extract($contextString, $item = null)
	{
		$parts = explode('.', $contextString, 2);

		if (count($parts) < 2)
		{
			return null;
		}

		$component = $parts[0];
		$eName = str_replace('com_', '', $component);

		$path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php');

		if (file_exists($path))
		{
			$cName = ucfirst($eName) . 'Helper';

			JLoader::register($cName, $path);

			if (class_exists($cName) && is_callable(array($cName, 'validateSection')))
			{
				$section = call_user_func_array(array($cName, 'validateSection'), array($parts[1], $item));

				if ($section)
				{
					$parts[1] = $section;
				}
			}
		}

		return $parts;
	}

	/**
	 * Returns the fields for the given context.
	 * If the item is an object the returned fields do have an additional field
	 * "value" which represents the value for the given item. If the item has an
	 * assigned_cat_ids field, then additionally fields which belong to that
	 * category will be returned.
	 * Should the value being prepared to be shown in an HTML context then
	 * prepareValue must be set to true. No further escaping needs to be done.
	 * The values of the fields can be overridden by an associative array where the keys
	 * have to be a name and its corresponding value.
	 *
	 * @param   string    $context           The context of the content passed to the helper
	 * @param   stdClass  $item              item
	 * @param   int|bool  $prepareValue      (if int is display event): 1 - AfterTitle, 2 - BeforeDisplay, 3 - AfterDisplay, 0 - OFF
	 * @param   array     $valuesToOverride  The values to override
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public static function getFields($context, $item = null, $prepareValue = false, array $valuesToOverride = null)
	{
		if (self::$fieldsCache === null)
		{
			// Load the model			
			JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fields/models', 'FieldsModel');

			self::$fieldsCache = JModelLegacy::getInstance('Fields', 'FieldsModel', array(
				'ignore_request' => true)
			);

			self::$fieldsCache->setState('filter.state', 1);
			self::$fieldsCache->setState('list.limit', 0);
		}

		if (is_array($item))
		{
			$item = (object) $item;
		}

		if (JLanguageMultilang::isEnabled() && isset($item->language) && $item->language != '*')
		{
			self::$fieldsCache->setState('filter.language', array('*', $item->language));
		}

		self::$fieldsCache->setState('filter.context', $context);
		self::$fieldsCache->setState('filter.assigned_cat_ids', array());

		/*
		 * If item has assigned_cat_ids parameter display only fields which
		 * belong to the category
		 */
		if ($item && (isset($item->catid) || isset($item->fieldscatid)))
		{
			$assignedCatIds = isset($item->catid) ? $item->catid : $item->fieldscatid;

			if (!is_array($assignedCatIds))
			{
				$assignedCatIds = explode(',', $assignedCatIds);
			}

			// Fields without any category assigned should show as well
			$assignedCatIds[] = 0;

			self::$fieldsCache->setState('filter.assigned_cat_ids', $assignedCatIds);
		}

		$fields = self::$fieldsCache->getItems();

		if ($fields === false)
		{
			return array();
		}

		if ($item && isset($item->id))
		{
			if (self::$fieldCache === null)
			{
				self::$fieldCache = JModelLegacy::getInstance('Field', 'FieldsModel', array('ignore_request' => true));
			}

			$fieldIds = array_map(
				function ($f)
				{
					return $f->id;
				},
				$fields
			);

			$fieldValues = self::$fieldCache->getFieldValues($fieldIds, $item->id);

			$new = array();

			foreach ($fields as $key => $original)
			{
				/*
				 * Doing a clone, otherwise fields for different items will
				 * always reference to the same object
				 */
				$field = clone $original;

				if ($valuesToOverride && key_exists($field->name, $valuesToOverride))
				{
					$field->value = $valuesToOverride[$field->name];
				}
				elseif ($valuesToOverride && key_exists($field->id, $valuesToOverride))
				{
					$field->value = $valuesToOverride[$field->id];
				}
				elseif (key_exists($field->id, $fieldValues))
				{
					$field->value = $fieldValues[$field->id];
				}

				if (!isset($field->value) || $field->value === '')
				{
					$field->value = $field->default_value;
				}

				$field->rawvalue = $field->value;

				// If boolean prepare, if int, it is the event type: 1 - After Title, 2 - Before Display, 3 - After Display, 0 - Do not prepare
				if ($prepareValue && (is_bool($prepareValue) || $prepareValue === (int) $field->params->get('display', '2')))
				{
					JPluginHelper::importPlugin('fields');

					$dispatcher = JEventDispatcher::getInstance();

					// Event allow plugins to modify the output of the field before it is prepared
					$dispatcher->trigger('onCustomFieldsBeforePrepareField', array($context, $item, &$field));

					// Gathering the value for the field
					$value = $dispatcher->trigger('onCustomFieldsPrepareField', array($context, $item, &$field));

					if (is_array($value))
					{
						$value = implode(' ', $value);
					}

					// Event allow plugins to modify the output of the prepared field
					$dispatcher->trigger('onCustomFieldsAfterPrepareField', array($context, $item, $field, &$value));

					// Assign the value
					$field->value = $value;
				}

				$new[$key] = $field;
			}

			$fields = $new;
		}

		return $fields;
	}

	/**
	 * Renders the layout file and data on the context and does a fall back to
	 * Fields afterwards.
	 *
	 * @param   string  $context      The context of the content passed to the helper
	 * @param   string  $layoutFile   layoutFile
	 * @param   array   $displayData  displayData
	 *
	 * @return  NULL|string
	 *
	 * @since  3.7.0
	 */
	public static function render($context, $layoutFile, $displayData)
	{
		$value = '';

		/*
		 * Because the layout refreshes the paths before the render function is
		 * called, so there is no way to load the layout overrides in the order
		 * template -> context -> fields.
		 * If there is no override in the context then we need to call the
		 * layout from Fields.
		 */
		if ($parts = self::extract($context))
		{
			// Trying to render the layout on the component from the context
			$value = JLayoutHelper::render($layoutFile, $displayData, null, array('component' => $parts[0], 'client' => 0));
		}

		if ($value == '')
		{
			// Trying to render the layout on Fields itself
			$value = JLayoutHelper::render($layoutFile, $displayData, null, array('component' => 'com_fields','client' => 0));
		}

		return $value;
	}

	/**
	 * PrepareForm
	 *
	 * @param   string  $context  The context of the content passed to the helper
	 * @param   JForm   $form     form
	 * @param   object  $data     data.
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	public static function prepareForm($context, JForm $form, $data)
	{
		// Extracting the component and section
		$parts = self::extract($context);

		if (! $parts)
		{
			return true;
		}

		$context = $parts[0] . '.' . $parts[1];

		// When no fields available return here
		$fields = self::getFields($parts[0] . '.' . $parts[1], new JObject);

		if (! $fields)
		{
			return true;
		}

		$component = $parts[0];
		$section   = $parts[1];

		$assignedCatids = isset($data->catid) ? $data->catid : (isset($data->fieldscatid) ? $data->fieldscatid : $form->getValue('catid'));

		// Account for case that a submitted form has a multi-value category id field (e.g. a filtering form), just use the first category
		$assignedCatids = is_array($assignedCatids)
			? (int) reset($assignedCatids)
			: (int) $assignedCatids;

		if (!$assignedCatids && $formField = $form->getField('catid'))
		{
			$assignedCatids = $formField->getAttribute('default', null);

			// Choose the first category available
			$xml = new DOMDocument;
			$xml->loadHTML($formField->__get('input'));
			$options = $xml->getElementsByTagName('option');

			if (!$assignedCatids && $firstChoice = $options->item(0))
			{
				$assignedCatids = $firstChoice->getAttribute('value');
			}

			$data->fieldscatid = $assignedCatids;
		}

		/*
		 * If there is a catid field we need to reload the page when the catid
		 * is changed
		 */
		if ($form->getField('catid') && $parts[0] != 'com_fields')
		{
			/*
			 * Setting the onchange event to reload the page when the category
			 * has changed
			*/
			$form->setFieldAttribute('catid', 'onchange', 'categoryHasChanged(this);');

			// Preload spindle-wheel when we need to submit form due to category selector changed
			JFactory::getDocument()->addScriptDeclaration("
			function categoryHasChanged(element) {
				var cat = jQuery(element);
				if (cat.val() == '" . $assignedCatids . "')return;
				Joomla.loadingLayer('show');
				jQuery('input[name=task]').val('" . $section . ".reload');
				Joomla.submitform('" . $section . ".reload', element.form);
			}
			jQuery( document ).ready(function() {
				Joomla.loadingLayer('load');
				var formControl = '#" . $form->getFormControl() . "_catid';
				if (!jQuery(formControl).val() != '" . $assignedCatids . "'){jQuery(formControl).val('" . $assignedCatids . "');}
			});"
			);
		}

		// Getting the fields
		$fields = self::getFields($parts[0] . '.' . $parts[1], $data);

		if (!$fields)
		{
			return true;
		}

		$fieldTypes = self::getFieldTypes();

		// Creating the dom
		$xml = new DOMDocument('1.0', 'UTF-8');
		$fieldsNode = $xml->appendChild(new DOMElement('form'))->appendChild(new DOMElement('fields'));
		$fieldsNode->setAttribute('name', 'com_fields');

		// Organizing the fields according to their group
		$fieldsPerGroup = array(0 => array());

		foreach ($fields as $field)
		{
			if (!array_key_exists($field->type, $fieldTypes))
			{
				// Field type is not available
				continue;
			}

			if (!array_key_exists($field->group_id, $fieldsPerGroup))
			{
				$fieldsPerGroup[$field->group_id] = array();
			}

			if ($path = $fieldTypes[$field->type]['path'])
			{
				// Add the lookup path for the field
				JFormHelper::addFieldPath($path);
			}

			if ($path = $fieldTypes[$field->type]['rules'])
			{
				// Add the lookup path for the rule
				JFormHelper::addRulePath($path);
			}

			$fieldsPerGroup[$field->group_id][] = $field;
		}

		// On the front, sometimes the admin fields path is not included
		JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fields/tables');

		$model = JModelLegacy::getInstance('Groups', 'FieldsModel', array('ignore_request' => true));
		$model->setState('filter.context', $context);

		/**
		 * $model->getItems() would only return existing groups, but we also
		 * have the 'default' group with id 0 which is not in the database,
		 * so we create it virtually here.
		 */
		$defaultGroup = new \stdClass;
		$defaultGroup->id = 0;
		$defaultGroup->title = '';
		$defaultGroup->description = '';
		$iterateGroups = array_merge(array($defaultGroup), $model->getItems());

		// Looping through the groups
		foreach ($iterateGroups as $group)
		{
			if (empty($fieldsPerGroup[$group->id]))
			{
				continue;
			}

			// Defining the field set
			/** @var DOMElement $fieldset */
			$fieldset = $fieldsNode->appendChild(new DOMElement('fieldset'));
			$fieldset->setAttribute('name', 'fields-' . $group->id);
			$fieldset->setAttribute('addfieldpath', '/administrator/components/' . $component . '/models/fields');
			$fieldset->setAttribute('addrulepath', '/administrator/components/' . $component . '/models/rules');

			$label       = $group->title;
			$description = $group->description;

			if (!$label)
			{
				$key = strtoupper($component . '_FIELDS_' . $section . '_LABEL');

				if (!JFactory::getLanguage()->hasKey($key))
				{
					$key = 'JGLOBAL_FIELDS';
				}

				$label = $key;
			}

			if (!$description)
			{
				$key = strtoupper($component . '_FIELDS_' . $section . '_DESC');

				if (JFactory::getLanguage()->hasKey($key))
				{
					$description = $key;
				}
			}

			$fieldset->setAttribute('label', $label);
			$fieldset->setAttribute('description', strip_tags($description));

			// Looping through the fields for that context
			foreach ($fieldsPerGroup[$group->id] as $field)
			{
				try
				{
					JFactory::getApplication()->triggerEvent('onCustomFieldsPrepareDom', array($field, $fieldset, $form));

					/*
					 * If the field belongs to an assigned_cat_id but the assigned_cat_ids in the data
					 * is not known, set the required flag to false on any circumstance.
					 */
					if (!$assignedCatids && !empty($field->assigned_cat_ids) && $form->getField($field->name))
					{
						$form->setFieldAttribute($field->name, 'required', 'false');
					}
				}
				catch (Exception $e)
				{
					JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error');
				}
			}

			// When the field set is empty, then remove it
			if (!$fieldset->hasChildNodes())
			{
				$fieldsNode->removeChild($fieldset);
			}
		}

		// Loading the XML fields string into the form
		$form->load($xml->saveXML());

		$model = JModelLegacy::getInstance('Field', 'FieldsModel', array('ignore_request' => true));

		if ((!isset($data->id) || !$data->id) && JFactory::getApplication()->input->getCmd('controller') == 'config.display.modules'
			&& JFactory::getApplication()->isClient('site'))
		{
			// Modules on front end editing don't have data and an id set
			$data->id = JFactory::getApplication()->input->getInt('id');
		}

		// Looping through the fields again to set the value
		if (!isset($data->id) || !$data->id)
		{
			return true;
		}

		foreach ($fields as $field)
		{
			$value = $model->getFieldValue($field->id, $data->id);

			if ($value === null)
			{
				continue;
			}

			if (!is_array($value) && $value !== '')
			{
				// Function getField doesn't cache the fields, so we try to do it only when necessary
				$formField = $form->getField($field->name, 'com_fields');

				if ($formField && $formField->forceMultiple)
				{
					$value = (array) $value;
				}
			}

			// Setting the value on the field
			$form->setValue($field->name, 'com_fields', $value);
		}

		return true;
	}

	/**
	 * Return a boolean if the actual logged in user can edit the given field value.
	 *
	 * @param   stdClass  $field  The field
	 *
	 * @return  boolean
	 *
	 * @since   3.7.0
	 */
	public static function canEditFieldValue($field)
	{
		$parts = self::extract($field->context);

		return JFactory::getUser()->authorise('core.edit.value', $parts[0] . '.field.' . (int) $field->id);
	}

	/**
	 * Return a boolean based on field (and field group) display / show_on settings
	 *
	 * @param   stdClass  $field  The field
	 *
	 * @return  boolean
	 *
	 * @since   3.8.7
	 */
	public static function displayFieldOnForm($field)
	{
		$app = JFactory::getApplication();

		// Detect if the field should be shown at all
		if ($field->params->get('show_on') == 1 && $app->isClient('administrator'))
		{
			return false;
		}
		elseif ($field->params->get('show_on') == 2 && $app->isClient('site'))
		{
			return false;
		}

		if (!self::canEditFieldValue($field))
		{
			$fieldDisplayReadOnly = $field->params->get('display_readonly', '2');

			if ($fieldDisplayReadOnly == '2')
			{
				// Inherit from field group display read-only setting
				$groupModel = JModelLegacy::getInstance('Group', 'FieldsModel', array('ignore_request' => true));
				$groupDisplayReadOnly = $groupModel->getItem($field->group_id)->params->get('display_readonly', '1');
				$fieldDisplayReadOnly = $groupDisplayReadOnly;
			}

			if ($fieldDisplayReadOnly == '0')
			{
				// Do not display field on form when field is read-only
				return false;
			}
		}

		// Display field on form
		return true;
	}

	/**
	 * Gets assigned categories titles for a field
	 *
	 * @param   stdClass[]  $fieldId  The field ID
	 *
	 * @return  array  Array with the assigned categories
	 *
	 * @since   3.7.0
	 */
	public static function getAssignedCategoriesTitles($fieldId)
	{
		$fieldId = (int) $fieldId;

		if (!$fieldId)
		{
			return array();
		}

		$db    = JFactory::getDbo();
		$query = $db->getQuery(true);

		$query->select($db->quoteName('c.title'))
			->from($db->quoteName('#__fields_categories', 'a'))
			->join('INNER', $db->quoteName('#__categories', 'c') . ' ON a.category_id = c.id')
			->where('field_id = ' . $fieldId);

		$db->setQuery($query);

		return $db->loadColumn();
	}

	/**
	 * Gets the fields system plugin extension id.
	 *
	 * @return  integer  The fields system plugin extension id.
	 *
	 * @since   3.7.0
	 */
	public static function getFieldsPluginId()
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('extension_id'))
			->from($db->quoteName('#__extensions'))
			->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
			->where($db->quoteName('element') . ' = ' . $db->quote('fields'));
		$db->setQuery($query);

		try
		{
			$result = (int) $db->loadResult();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());
			$result = 0;
		}

		return $result;
	}

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $context  The context the fields are used for
	 * @param   string  $vName    The view currently active
	 *
	 * @return  void
	 *
	 * @since    3.7.0
	 */
	public static function addSubmenu($context, $vName)
	{
		$parts = self::extract($context);

		if (!$parts)
		{
			return;
		}

		$component = $parts[0];

		// Avoid nonsense situation.
		if ($component == 'com_fields')
		{
			return;
		}

		// Try to find the component helper.
		$eName = str_replace('com_', '', $component);
		$file  = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php');

		if (!file_exists($file))
		{
			return;
		}

		require_once $file;

		$cName = ucfirst($eName) . 'Helper';

		if (class_exists($cName) && is_callable(array($cName, 'addSubmenu')))
		{
			$lang = JFactory::getLanguage();
			$lang->load($component, JPATH_ADMINISTRATOR)
			|| $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component);

			$cName::addSubmenu('fields.' . $vName);
		}
	}

	/**
	 * Loads the fields plugins and returns an array of field types from the plugins.
	 *
	 * The returned array contains arrays with the following keys:
	 * - label: The label of the field
	 * - type:  The type of the field
	 * - path:  The path of the folder where the field can be found
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public static function getFieldTypes()
	{
		JPluginHelper::importPlugin('fields');
		$eventData = JEventDispatcher::getInstance()->trigger('onCustomFieldsGetTypes');

		$data = array();

		foreach ($eventData as $fields)
		{
			foreach ($fields as $fieldDescription)
			{
				if (!array_key_exists('path', $fieldDescription))
				{
					$fieldDescription['path'] = null;
				}

				if (!array_key_exists('rules', $fieldDescription))
				{
					$fieldDescription['rules'] = null;
				}

				$data[$fieldDescription['type']] = $fieldDescription;
			}
		}

		return $data;
	}

	/**
	 * Clears the internal cache for the custom fields.
	 *
	 * @return  void
	 *
	 * @since   3.8.0
	 */
	public static function clearFieldsCache()
	{
		self::$fieldCache  = null;
		self::$fieldsCache = null;
	}
}
PKT|!]ꠠ�
�
html/banner.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_banners
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Banner HTML class.
 *
 * @since  2.5
 */
abstract class JHtmlBanner
{
	/**
	 * Display a batch widget for the client selector.
	 *
	 * @return  string  The necessary HTML for the widget.
	 *
	 * @since   2.5
	 */
	public static function clients()
	{
		JHtml::_('bootstrap.tooltip');

		// Create the batch selector to change the client on a selection list.
		return implode(
			"\n",
			array(
				'<label id="batch-client-lbl" for="batch-client" class="hasTooltip" title="'
					. JHtml::_('tooltipText', 'COM_BANNERS_BATCH_CLIENT_LABEL', 'COM_BANNERS_BATCH_CLIENT_LABEL_DESC')
					. '">',
				JText::_('COM_BANNERS_BATCH_CLIENT_LABEL'),
				'</label>',
				'<select name="batch[client_id]" id="batch-client-id">',
				'<option value="">' . JText::_('COM_BANNERS_BATCH_CLIENT_NOCHANGE') . '</option>',
				'<option value="0">' . JText::_('COM_BANNERS_NO_CLIENT') . '</option>',
				JHtml::_('select.options', static::clientlist(), 'value', 'text'),
				'</select>'
			)
		);
	}

	/**
	 * Method to get the field options.
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   1.6
	 */
	public static function clientlist()
	{
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('id As value, name As text')
			->from('#__banner_clients AS a')
			->order('a.name');

		// Get the options.
		$db->setQuery($query);

		try
		{
			$options = $db->loadObjectList();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());
		}

		return $options;
	}

	/**
	 * Returns a pinned state on a grid
	 *
	 * @param   integer  $value     The state value.
	 * @param   integer  $i         The row index
	 * @param   boolean  $enabled   An optional setting for access control on the action.
	 * @param   string   $checkbox  An optional prefix for checkboxes.
	 *
	 * @return  string   The Html code
	 *
	 * @see     JHtmlJGrid::state
	 * @since   2.5.5
	 */
	public static function pinned($value, $i, $enabled = true, $checkbox = 'cb')
	{
		$states = array(
			1 => array(
				'sticky_unpublish',
				'COM_BANNERS_BANNERS_PINNED',
				'COM_BANNERS_BANNERS_HTML_PIN_BANNER',
				'COM_BANNERS_BANNERS_PINNED',
				true,
				'publish',
				'publish'
			),
			0 => array(
				'sticky_publish',
				'COM_BANNERS_BANNERS_UNPINNED',
				'COM_BANNERS_BANNERS_HTML_UNPIN_BANNER',
				'COM_BANNERS_BANNERS_UNPINNED',
				true,
				'unpublish',
				'unpublish'
			),
		);

		return JHtml::_('jgrid.state', $states, $value, $i, 'banners.', $enabled, true, $checkbox);
	}
}
PKT|!]m�~'``banners.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_banners
 *
 * @copyright   (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Banners component helper.
 *
 * @since  1.6
 */
class BannersHelper extends JHelperContent
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_BANNERS_SUBMENU_BANNERS'),
			'index.php?option=com_banners&view=banners',
			$vName == 'banners'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_BANNERS_SUBMENU_CATEGORIES'),
			'index.php?option=com_categories&extension=com_banners',
			$vName == 'categories'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_BANNERS_SUBMENU_CLIENTS'),
			'index.php?option=com_banners&view=clients',
			$vName == 'clients'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_BANNERS_SUBMENU_TRACKS'),
			'index.php?option=com_banners&view=tracks',
			$vName == 'tracks'
		);
	}

	/**
	 * Update / reset the banners
	 *
	 * @return  boolean
	 *
	 * @since   1.6
	 */
	public static function updateReset()
	{
		$db       = JFactory::getDbo();
		$nullDate = $db->getNullDate();
		$query    = $db->getQuery(true)
			->select('*')
			->from('#__banners')
			->where($db->quote(JFactory::getDate()) . ' >= ' . $db->quote('reset'))
			->where($db->quoteName('reset') . ' != ' . $db->quote($nullDate) . ' AND ' . $db->quoteName('reset') . '!= NULL')
			->where(
				'(' . $db->quoteName('checked_out') . ' = 0 OR ' . $db->quoteName('checked_out') . ' = '
				. (int) $db->quote(JFactory::getUser()->id) . ')'
			);
		$db->setQuery($query);

		try
		{
			$rows = $db->loadObjectList();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());

			return false;
		}

		JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR . '/tables');

		foreach ($rows as $row)
		{
			$purchaseType = $row->purchase_type;

			if ($purchaseType < 0 && $row->cid)
			{
				/** @var BannersTableClient $client */
				$client = JTable::getInstance('Client', 'BannersTable');
				$client->load($row->cid);
				$purchaseType = $client->purchase_type;
			}

			if ($purchaseType < 0)
			{
				$params = JComponentHelper::getParams('com_banners');
				$purchaseType = $params->get('purchase_type');
			}

			switch ($purchaseType)
			{
				case 1:
					$reset = $nullDate;
					break;
				case 2:
					$date = JFactory::getDate('+1 year ' . date('Y-m-d'));
					$reset = $db->quote($date->toSql());
					break;
				case 3:
					$date = JFactory::getDate('+1 month ' . date('Y-m-d'));
					$reset = $db->quote($date->toSql());
					break;
				case 4:
					$date = JFactory::getDate('+7 day ' . date('Y-m-d'));
					$reset = $db->quote($date->toSql());
					break;
				case 5:
					$date = JFactory::getDate('+1 day ' . date('Y-m-d'));
					$reset = $db->quote($date->toSql());
					break;
			}

			// Update the row ordering field.
			$query->clear()
				->update($db->quoteName('#__banners'))
				->set($db->quoteName('reset') . ' = ' . $db->quote($reset))
				->set($db->quoteName('impmade') . ' = ' . $db->quote(0))
				->set($db->quoteName('clicks') . ' = ' . $db->quote(0))
				->where($db->quoteName('id') . ' = ' . $db->quote($row->id));
			$db->setQuery($query);

			try
			{
				$db->execute();
			}
			catch (RuntimeException $e)
			{
				JError::raiseWarning(500, $db->getMessage());

				return false;
			}
		}

		return true;
	}

	/**
	 * Get client list in text/value format for a select field
	 *
	 * @return  array
	 */
	public static function getClientOptions()
	{
		$options = array();

		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('id AS value, name AS text')
			->from('#__banner_clients AS a')
			->where('a.state = 1')
			->order('a.name');

		// Get the options.
		$db->setQuery($query);

		try
		{
			$options = $db->loadObjectList();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());
		}

		array_unshift($options, JHtml::_('select.option', '0', JText::_('COM_BANNERS_NO_CLIENT')));

		return $options;
	}

	/**
	 * Adds Count Items for Category Manager.
	 *
	 * @param   stdClass[]  &$items  The category objects
	 *
	 * @return  stdClass[]
	 *
	 * @since   3.5
	 */
	public static function countItems(&$items)
	{
		$config = (object) array(
			'related_tbl'   => 'banners',
			'state_col'     => 'state',
			'group_col'     => 'catid',
			'relation_type' => 'category_or_group',
		);

		return parent::countRelations($items, $config);
	}
}
PKW|!]��c��html/finder.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('FinderHelperLanguage', JPATH_ADMINISTRATOR . '/components/com_finder/helpers/language.php');

use Joomla\Utilities\ArrayHelper;

/**
 * HTML behavior class for Finder.
 *
 * @since  2.5
 */
abstract class JHtmlFinder
{
	/**
	 * Creates a list of types to filter on.
	 *
	 * @return  array  An array containing the types that can be selected.
	 *
	 * @since   2.5
	 */
	public static function typeslist()
	{
		// Load the finder types.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('DISTINCT t.title AS text, t.id AS value')
			->from($db->quoteName('#__finder_types') . ' AS t')
			->join('LEFT', $db->quoteName('#__finder_links') . ' AS l ON l.type_id = t.id')
			->order('t.title ASC');
		$db->setQuery($query);

		try
		{
			$rows = $db->loadObjectList();
		}
		catch (RuntimeException $e)
		{
			return array();
		}

		// Compile the options.
		$options = array();

		$lang = JFactory::getLanguage();

		foreach ($rows as $row)
		{
			$key       = $lang->hasKey(FinderHelperLanguage::branchPlural($row->text)) ? FinderHelperLanguage::branchPlural($row->text) : $row->text;
			$options[] = JHtml::_('select.option', $row->value, JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_($key)));
		}

		return $options;
	}

	/**
	 * Creates a list of maps.
	 *
	 * @return  array  An array containing the maps that can be selected.
	 *
	 * @since   2.5
	 */
	public static function mapslist()
	{
		// Load the finder types.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('title', 'text'))
			->select($db->quoteName('id', 'value'))
			->from($db->quoteName('#__finder_taxonomy'))
			->where($db->quoteName('parent_id') . ' = 1');
		$db->setQuery($query);

		try
		{
			$branches = $db->loadObjectList();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $db->getMessage());
		}

		// Translate.
		$lang = JFactory::getLanguage();

		foreach ($branches as $branch)
		{
			$key = FinderHelperLanguage::branchPlural($branch->text);
			$branch->translatedText = $lang->hasKey($key) ? JText::_($key) : $branch->text;
		}

		// Order by title.
		$branches = ArrayHelper::sortObjects($branches, 'translatedText', 1, true, true);

		// Compile the options.
		$options = array();
		$options[] = JHtml::_('select.option', '', JText::_('COM_FINDER_MAPS_SELECT_BRANCH'));

		// Convert the values to options.
		foreach ($branches as $branch)
		{
			$options[] = JHtml::_('select.option', $branch->value, $branch->translatedText);
		}

		return $options;
	}

	/**
	 * Creates a list of published states.
	 *
	 * @return  array  An array containing the states that can be selected.
	 *
	 * @since   2.5
	 */
	public static function statelist()
	{
		return array(
			JHtml::_('select.option', '1', JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_('JPUBLISHED'))),
			JHtml::_('select.option', '0', JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_('JUNPUBLISHED')))
		);
	}
}
PKW|!]�l(��9�9indexer/indexer.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\String\StringHelper;

JLoader::register('FinderIndexerHelper', __DIR__ . '/helper.php');
JLoader::register('FinderIndexerParser', __DIR__ . '/parser.php');
JLoader::register('FinderIndexerStemmer', __DIR__ . '/stemmer.php');
JLoader::register('FinderIndexerTaxonomy', __DIR__ . '/taxonomy.php');
JLoader::register('FinderIndexerToken', __DIR__ . '/token.php');

jimport('joomla.filesystem.file');

/**
 * Main indexer class for the Finder indexer package.
 *
 * The indexer class provides the core functionality of the Finder
 * search engine. It is responsible for adding and updating the
 * content links table; extracting and scoring tokens; and maintaining
 * all referential information for the content.
 *
 * Note: All exceptions thrown from within this class should be caught
 * by the controller.
 *
 * @since  2.5
 */
abstract class FinderIndexer
{
	/**
	 * The title context identifier.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	const TITLE_CONTEXT = 1;

	/**
	 * The text context identifier.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	const TEXT_CONTEXT = 2;

	/**
	 * The meta context identifier.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	const META_CONTEXT = 3;

	/**
	 * The path context identifier.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	const PATH_CONTEXT = 4;

	/**
	 * The misc context identifier.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	const MISC_CONTEXT = 5;

	/**
	 * The indexer state object.
	 *
	 * @var    JObject
	 * @since  2.5
	 */
	public static $state;

	/**
	 * The indexer profiler object.
	 *
	 * @var    JProfiler
	 * @since  2.5
	 */
	public static $profiler;

	/**
	 * Database driver cache.
	 *
	 * @var    JDatabaseDriver
	 * @since  3.8.0
	 */
	protected $db;

	/**
	 * Reusable Query Template. To be used with clone.
	 *
	 * @var    JDatabaseQuery
	 * @since  3.8.0
	 */
	protected $addTokensToDbQueryTemplate;

	/**
	 * FinderIndexer constructor.
	 *
	 * @since  3.8.0
	 */
	public function __construct()
	{
		$this->db = JFactory::getDbo();

		$db = $this->db;

		/**
		 * Set up query template for addTokensToDb, we will be cloning this template when needed.
		 * This is about twice as fast as calling the clear function or setting up a new object.
		 */
		$this->addTokensToDbQueryTemplate = $db->getQuery(true)->insert($db->quoteName('#__finder_tokens'))
			->columns(
				array(
					$db->quoteName('term'),
					$db->quoteName('stem'),
					$db->quoteName('common'),
					$db->quoteName('phrase'),
					$db->quoteName('weight'),
					$db->quoteName('context'),
					$db->quoteName('language')
				)
			);
	}

	/**
	 * Returns a reference to the FinderIndexer object.
	 *
	 * @return  FinderIndexer instance based on the database driver
	 *
	 * @since   3.0
	 * @throws  RuntimeException if driver class for indexer not present.
	 */
	public static function getInstance()
	{
		// Setup the adapter for the indexer.
		$serverType = JFactory::getDbo()->getServerType();

		// For `mssql` server types, convert the type to `sqlsrv`
		if ($serverType === 'mssql')
		{
			$serverType = 'sqlsrv';
		}

		$path = __DIR__ . '/driver/' . $serverType . '.php';
		$class = 'FinderIndexerDriver' . ucfirst($serverType);

		// Check if a parser exists for the format.
		if (file_exists($path))
		{
			// Instantiate the parser.
			JLoader::register($class, $path);

			return new $class;
		}

		// Throw invalid format exception.
		throw new RuntimeException(JText::sprintf('COM_FINDER_INDEXER_INVALID_DRIVER', $serverType));
	}

	/**
	 * Method to get the indexer state.
	 *
	 * @return  object  The indexer state object.
	 *
	 * @since   2.5
	 */
	public static function getState()
	{
		// First, try to load from the internal state.
		if ((bool) static::$state)
		{
			return static::$state;
		}

		// If we couldn't load from the internal state, try the session.
		$session = JFactory::getSession();
		$data = $session->get('_finder.state', null);

		// If the state is empty, load the values for the first time.
		if (empty($data))
		{
			$data = new JObject;

			// Load the default configuration options.
			$data->options = JComponentHelper::getParams('com_finder');

			// Setup the weight lookup information.
			$data->weights = array(
				self::TITLE_CONTEXT => round($data->options->get('title_multiplier', 1.7), 2),
				self::TEXT_CONTEXT  => round($data->options->get('text_multiplier', 0.7), 2),
				self::META_CONTEXT  => round($data->options->get('meta_multiplier', 1.2), 2),
				self::PATH_CONTEXT  => round($data->options->get('path_multiplier', 2.0), 2),
				self::MISC_CONTEXT  => round($data->options->get('misc_multiplier', 0.3), 2)
			);

			// Set the current time as the start time.
			$data->startTime = JFactory::getDate()->toSql();

			// Set the remaining default values.
			$data->batchSize   = (int) $data->options->get('batch_size', 50);
			$data->batchOffset = 0;
			$data->totalItems  = 0;
			$data->pluginState = array();
		}

		// Setup the profiler if debugging is enabled.
		if (JFactory::getApplication()->get('debug'))
		{
			static::$profiler = JProfiler::getInstance('FinderIndexer');
		}

		// Setup the stemmer.
		if ($data->options->get('stem', 1) && $data->options->get('stemmer', 'porter_en'))
		{
			FinderIndexerHelper::$stemmer = FinderIndexerStemmer::getInstance($data->options->get('stemmer', 'porter_en'));
		}

		// Set the state.
		static::$state = $data;

		return static::$state;
	}

	/**
	 * Method to set the indexer state.
	 *
	 * @param   object  $data  A new indexer state object.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   2.5
	 */
	public static function setState($data)
	{
		// Check the state object.
		if (empty($data) || !$data instanceof JObject)
		{
			return false;
		}

		// Set the new internal state.
		static::$state = $data;

		// Set the new session state.
		JFactory::getSession()->set('_finder.state', $data);

		return true;
	}

	/**
	 * Method to reset the indexer state.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public static function resetState()
	{
		// Reset the internal state to null.
		self::$state = null;

		// Reset the session state to null.
		JFactory::getSession()->set('_finder.state', null);
	}

	/**
	 * Method to index a content item.
	 *
	 * @param   FinderIndexerResult  $item    The content item to index.
	 * @param   string               $format  The format of the content. [optional]
	 *
	 * @return  integer  The ID of the record in the links table.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	abstract public function index($item, $format = 'html');

	/**
	 * Method to remove a link from the index.
	 *
	 * @param   integer  $linkId  The id of the link.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public function remove($linkId)
	{
		$db    = $this->db;
		$query = $db->getQuery(true);

		// Update the link counts and remove the mapping records.
		for ($i = 0; $i <= 15; $i++)
		{
			// Update the link counts for the terms.
			$query->clear()
				->update($db->quoteName('#__finder_terms', 't'))
				->join('INNER', $db->quoteName('#__finder_links_terms' . dechex($i), 'm') .
					' ON ' . $db->quoteName('m.term_id') . ' = ' . $db->quoteName('t.term_id')
				)
				->set($db->quoteName('links') . ' = ' . $db->quoteName('links') . ' - 1')
				->where($db->quoteName('m.link_id') . ' = ' . (int) $linkId);
			$db->setQuery($query)->execute();

			// Remove all records from the mapping tables.
			$query->clear()
				->delete($db->quoteName('#__finder_links_terms' . dechex($i)))
				->where($db->quoteName('link_id') . ' = ' . (int) $linkId);
			$db->setQuery($query)->execute();
		}

		// Delete all orphaned terms.
		$query->clear()
			->delete($db->quoteName('#__finder_terms'))
			->where($db->quoteName('links') . ' <= 0');
		$db->setQuery($query)->execute();

		// Delete the link from the index.
		$query->clear()
			->delete($db->quoteName('#__finder_links'))
			->where($db->quoteName('link_id') . ' = ' . (int) $linkId);
		$db->setQuery($query)->execute();

		// Remove the taxonomy maps.
		FinderIndexerTaxonomy::removeMaps($linkId);

		// Remove the orphaned taxonomy nodes.
		FinderIndexerTaxonomy::removeOrphanNodes();

		return true;
	}

	/**
	 * Method to optimize the index. We use this method to remove unused terms
	 * and any other optimizations that might be necessary.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	abstract public function optimize();

	/**
	 * Method to get a content item's signature.
	 *
	 * @param   object  $item  The content item to index.
	 *
	 * @return  string  The content item's signature.
	 *
	 * @since   2.5
	 */
	protected static function getSignature($item)
	{
		// Get the indexer state.
		$state = static::getState();

		// Get the relevant configuration variables.
		$config = array(
			$state->weights,
			$state->options->get('stem', 1),
			$state->options->get('stemmer', 'porter_en')
		);

		return md5(serialize(array($item, $config)));
	}

	/**
	 * Method to parse input, tokenize it, and then add it to the database.
	 *
	 * @param   mixed    $input    String or resource to use as input. A resource input will automatically be chunked to conserve
	 *                             memory. Strings will be chunked if longer than 2K in size.
	 * @param   integer  $context  The context of the input. See context constants.
	 * @param   string   $lang     The language of the input.
	 * @param   string   $format   The format of the input.
	 *
	 * @return  integer  The number of tokens extracted from the input.
	 *
	 * @since   2.5
	 */
	protected function tokenizeToDb($input, $context, $lang, $format)
	{
		$count = 0;
		$buffer = null;

		if (empty($input))
		{
			return $count;
		}

		// If the input is a resource, batch the process out.
		if (is_resource($input))
		{
			// Batch the process out to avoid memory limits.
			while (!feof($input))
			{
				// Read into the buffer.
				$buffer .= fread($input, 2048);

				/*
				 * If we haven't reached the end of the file, seek to the last
				 * space character and drop whatever is after that to make sure
				 * we didn't truncate a term while reading the input.
				 */
				if (!feof($input))
				{
					// Find the last space character.
					$ls = strrpos($buffer, ' ');

					// Adjust string based on the last space character.
					if ($ls)
					{
						// Truncate the string to the last space character.
						$string = substr($buffer, 0, $ls);

						// Adjust the buffer based on the last space for the next iteration and trim.
						$buffer = StringHelper::trim(substr($buffer, $ls));
					}
					// No space character was found.
					else
					{
						$string = $buffer;
					}
				}
				// We've reached the end of the file, so parse whatever remains.
				else
				{
					$string = $buffer;
				}

				// Parse, tokenise and add tokens to the database.
				$count = $this->tokenizeToDbShort($string, $context, $lang, $format, $count);

				unset($string, $tokens);
			}

			return $count;
		}

		// Parse, tokenise and add tokens to the database.
		$count = $this->tokenizeToDbShort($input, $context, $lang, $format, $count);

		return $count;
	}

	/**
	 * Method to parse input, tokenise it, then add the tokens to the database.
	 *
	 * @param   string   $input    String to parse, tokenise and add to database.
	 * @param   integer  $context  The context of the input. See context constants.
	 * @param   string   $lang     The language of the input.
	 * @param   string   $format   The format of the input.
	 * @param   integer  $count    The number of tokens processed so far.
	 *
	 * @return  integer  Cumulative number of tokens extracted from the input so far.
	 *
	 * @since   3.7.0
	 */
	private function tokenizeToDbShort($input, $context, $lang, $format, $count)
	{
		// Parse the input.
		$input = FinderIndexerHelper::parse($input, $format);

		// Check the input.
		if (empty($input))
		{
			return $count;
		}

		// Tokenize the input.
		$tokens = FinderIndexerHelper::tokenize($input, $lang);

		// Add the tokens to the database.
		$count += $this->addTokensToDb($tokens, $context);

		// Check if we're approaching the memory limit of the token table.
		if ($count > static::$state->options->get('memory_table_limit', 30000))
		{
			$this->toggleTables(false);
		}

		return $count;
	}

	/**
	 * Method to add a set of tokens to the database.
	 *
	 * @param   mixed  $tokens   An array or single FinderIndexerToken object.
	 * @param   mixed  $context  The context of the tokens. See context constants. [optional]
	 *
	 * @return  integer  The number of tokens inserted into the database.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function addTokensToDb($tokens, $context = '')
	{
		// Get the database object.
		$db = $this->db;

		$query = clone $this->addTokensToDbQueryTemplate;

		// Check if a single FinderIndexerToken object was given and make it to be an array of FinderIndexerToken objects
		$tokens = is_array($tokens) ? $tokens : array($tokens);

		// Count the number of token values.
		$values = 0;

		// Break into chunks of no more than 1000 items
		$chunks = array_chunk($tokens, 128);

		foreach ($chunks as $tokens)
		{
			$query->clear('values');

			// Iterate through the tokens to create SQL value sets.
			foreach ($tokens as $token)
			{
				$query->values(
					$db->quote($token->term) . ', '
					. $db->quote($token->stem) . ', '
					. (int) $token->common . ', '
					. (int) $token->phrase . ', '
					. $db->escape((float) $token->weight) . ', '
					. (int) $context . ', '
					. $db->quote($token->language)
				);
				++$values;
			}

			$db->setQuery($query)->execute();

			// Check if we're approaching the memory limit of the token table.
			if ($values > static::$state->options->get('memory_table_limit', 10000))
			{
				$this->toggleTables(false);
			}
		}

		return $values;
	}

	/**
	 * Method to switch the token tables from Memory tables to Disk tables
	 * when they are close to running out of memory.
	 * Since this is not supported/implemented in all DB-drivers, the default is a stub method, which simply returns true.
	 *
	 * @param   boolean  $memory  Flag to control how they should be toggled.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function toggleTables($memory)
	{
		return true;
	}
}
PKW|!]C�y/'/'indexer/taxonomy.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Stemmer base class for the Finder indexer package.
 *
 * @since  2.5
 */
class FinderIndexerTaxonomy
{
	/**
	 * An internal cache of taxonomy branch data.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public static $branches = array();

	/**
	 * An internal cache of taxonomy node data.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public static $nodes = array();

	/**
	 * Method to add a branch to the taxonomy tree.
	 *
	 * @param   string   $title   The title of the branch.
	 * @param   integer  $state   The published state of the branch. [optional]
	 * @param   integer  $access  The access state of the branch. [optional]
	 *
	 * @return  integer  The id of the branch.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function addBranch($title, $state = 1, $access = 1)
	{
		// Check to see if the branch is in the cache.
		if (isset(static::$branches[$title]))
		{
			return static::$branches[$title]->id;
		}

		// Check to see if the branch is in the table.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('*')
			->from($db->quoteName('#__finder_taxonomy'))
			->where($db->quoteName('parent_id') . ' = 1')
			->where($db->quoteName('title') . ' = ' . $db->quote($title));
		$db->setQuery($query);

		// Get the result.
		$result = $db->loadObject();

		// Check if the database matches the input data.
		if ((bool) $result && $result->state == $state && $result->access == $access)
		{
			// The data matches, add the item to the cache.
			static::$branches[$title] = $result;

			return static::$branches[$title]->id;
		}

		/*
		 * The database did not match the input. This could be because the
		 * state has changed or because the branch does not exist. Let's figure
		 * out which case is true and deal with it.
		 */
		$branch = new JObject;

		if (empty($result))
		{
			// Prepare the branch object.
			$branch->parent_id = 1;
			$branch->title = $title;
			$branch->state = (int) $state;
			$branch->access = (int) $access;
		}
		else
		{
			// Prepare the branch object.
			$branch->id = (int) $result->id;
			$branch->parent_id = (int) $result->parent_id;
			$branch->title = $result->title;
			$branch->state = (int) $result->title;
			$branch->access = (int) $result->access;
			$branch->ordering = (int) $result->ordering;
		}

		// Store the branch.
		static::storeNode($branch);

		// Add the branch to the cache.
		static::$branches[$title] = $branch;

		return static::$branches[$title]->id;
	}

	/**
	 * Method to add a node to the taxonomy tree.
	 *
	 * @param   string   $branch  The title of the branch to store the node in.
	 * @param   string   $title   The title of the node.
	 * @param   integer  $state   The published state of the node. [optional]
	 * @param   integer  $access  The access state of the node. [optional]
	 *
	 * @return  integer  The id of the node.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function addNode($branch, $title, $state = 1, $access = 1)
	{
		// Check to see if the node is in the cache.
		if (isset(static::$nodes[$branch][$title]))
		{
			return static::$nodes[$branch][$title]->id;
		}

		// Get the branch id, insert it if it does not exist.
		$branchId = static::addBranch($branch);

		// Check to see if the node is in the table.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('*')
			->from($db->quoteName('#__finder_taxonomy'))
			->where($db->quoteName('parent_id') . ' = ' . $db->quote($branchId))
			->where($db->quoteName('title') . ' = ' . $db->quote($title));
		$db->setQuery($query);

		// Get the result.
		$result = $db->loadObject();

		// Check if the database matches the input data.
		if ((bool) $result && $result->state == $state && $result->access == $access)
		{
			// The data matches, add the item to the cache.
			static::$nodes[$branch][$title] = $result;

			return static::$nodes[$branch][$title]->id;
		}

		/*
		 * The database did not match the input. This could be because the
		 * state has changed or because the node does not exist. Let's figure
		 * out which case is true and deal with it.
		 */
		$node = new JObject;

		if (empty($result))
		{
			// Prepare the node object.
			$node->parent_id = (int) $branchId;
			$node->title = $title;
			$node->state = (int) $state;
			$node->access = (int) $access;
		}
		else
		{
			// Prepare the node object.
			$node->id = (int) $result->id;
			$node->parent_id = (int) $result->parent_id;
			$node->title = $result->title;
			$node->state = (int) $result->title;
			$node->access = (int) $result->access;
			$node->ordering = (int) $result->ordering;
		}

		// Store the node.
		static::storeNode($node);

		// Add the node to the cache.
		static::$nodes[$branch][$title] = $node;

		return static::$nodes[$branch][$title]->id;
	}

	/**
	 * Method to add a map entry between a link and a taxonomy node.
	 *
	 * @param   integer  $linkId  The link to map to.
	 * @param   integer  $nodeId  The node to map to.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function addMap($linkId, $nodeId)
	{
		// Insert the map.
		$db = JFactory::getDbo();

		$query = $db->getQuery(true)
			->select($db->quoteName('link_id'))
			->from($db->quoteName('#__finder_taxonomy_map'))
			->where($db->quoteName('link_id') . ' = ' . (int) $linkId)
			->where($db->quoteName('node_id') . ' = ' . (int) $nodeId);
		$db->setQuery($query);
		$db->execute();
		$id = (int) $db->loadResult();

		$map = new JObject;
		$map->link_id = (int) $linkId;
		$map->node_id = (int) $nodeId;

		if ($id)
		{
			$db->updateObject('#__finder_taxonomy_map', $map, array('link_id', 'node_id'));
		}
		else
		{
			$db->insertObject('#__finder_taxonomy_map', $map);
		}

		return true;
	}

	/**
	 * Method to get the title of all taxonomy branches.
	 *
	 * @return  array  An array of branch titles.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function getBranchTitles()
	{
		$db = JFactory::getDbo();

		// Set user variables
		$groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels());

		// Create a query to get the taxonomy branch titles.
		$query = $db->getQuery(true)
			->select($db->quoteName('title'))
			->from($db->quoteName('#__finder_taxonomy'))
			->where($db->quoteName('parent_id') . ' = 1')
			->where($db->quoteName('state') . ' = 1')
			->where($db->quoteName('access') . ' IN (' . $groups . ')');

		// Get the branch titles.
		$db->setQuery($query);

		return $db->loadColumn();
	}

	/**
	 * Method to find a taxonomy node in a branch.
	 *
	 * @param   string  $branch  The branch to search.
	 * @param   string  $title   The title of the node.
	 *
	 * @return  mixed  Integer id on success, null on no match.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function getNodeByTitle($branch, $title)
	{
		$db = JFactory::getDbo();

		// Set user variables
		$groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels());

		// Create a query to get the node.
		$query = $db->getQuery(true)
			->select('t1.*')
			->from($db->quoteName('#__finder_taxonomy') . ' AS t1')
			->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id')
			->where('t1.access IN (' . $groups . ')')
			->where('t1.state = 1')
			->where('t1.title LIKE ' . $db->quote($db->escape($title) . '%'))
			->where('t2.access IN (' . $groups . ')')
			->where('t2.state = 1')
			->where('t2.title = ' . $db->quote($branch));

		// Get the node.
		$db->setQuery($query, 0, 1);

		return $db->loadObject();
	}

	/**
	 * Method to remove map entries for a link.
	 *
	 * @param   integer  $linkId  The link to remove.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function removeMaps($linkId)
	{
		// Delete the maps.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->delete($db->quoteName('#__finder_taxonomy_map'))
			->where($db->quoteName('link_id') . ' = ' . (int) $linkId);
		$db->setQuery($query);
		$db->execute();

		return true;
	}

	/**
	 * Method to remove orphaned taxonomy nodes and branches.
	 *
	 * @return  integer  The number of deleted rows.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function removeOrphanNodes()
	{
		// Delete all orphaned nodes.
		$db = JFactory::getDbo();

		$query = $db->getQuery(true)
			->select($db->quoteName('t.id'))
			->from($db->quoteName('#__finder_taxonomy', 't'))
			->join('LEFT', $db->quoteName('#__finder_taxonomy_map', 'm') . ' ON ' . $db->quoteName('m.node_id') . '=' . $db->quoteName('t.id'))
			->where($db->quoteName('t.parent_id') . ' > 1 ')
			->where($db->quoteName('m.link_id') . ' IS NULL');

		$db->setQuery($query);
		
		$ids = $db->loadColumn();

		if (empty($ids))
		{
			return 0;
		}

		$query->clear()
			->delete($db->quoteName('#__finder_taxonomy'))
			->where($db->quoteName('id') . ' IN (' . implode(',', $ids) . ')');

		$db->setQuery($query);
		
		$db->execute();

		return $db->getAffectedRows();
	}

	/**
	 * Method to store a node to the database.  This method will accept either a branch or a node.
	 *
	 * @param   object  $item  The item to store.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected static function storeNode($item)
	{
		$db = JFactory::getDbo();

		// Check if we are updating or inserting the item.
		if (empty($item->id))
		{
			// Insert the item.
			$db->insertObject('#__finder_taxonomy', $item, 'id');
		}
		else
		{
			// Update the item.
			$db->updateObject('#__finder_taxonomy', $item, 'id');
		}

		return true;
	}
}
PKW|!]��ѳ����indexer/query.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;
use Joomla\String\StringHelper;
use Joomla\Utilities\ArrayHelper;

JLoader::register('FinderIndexerHelper', __DIR__ . '/helper.php');
JLoader::register('FinderIndexerTaxonomy', __DIR__ . '/taxonomy.php');
JLoader::register('FinderHelperRoute', JPATH_SITE . '/components/com_finder/helpers/route.php');
JLoader::register('FinderHelperLanguage', JPATH_ADMINISTRATOR . '/components/com_finder/helpers/language.php');

/**
 * Query class for the Finder indexer package.
 *
 * @since  2.5
 */
class FinderIndexerQuery
{
	/**
	 * Flag to show whether the query can return results.
	 *
	 * @var    boolean
	 * @since  2.5
	 */
	public $search;

	/**
	 * The query input string.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $input;

	/**
	 * The language of the query.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $language;

	/**
	 * The query string matching mode.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $mode;

	/**
	 * The included tokens.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public $included = array();

	/**
	 * The excluded tokens.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public $excluded = array();

	/**
	 * The tokens to ignore because no matches exist.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public $ignored = array();

	/**
	 * The operators used in the query input string.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public $operators = array();

	/**
	 * The terms to highlight as matches.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public $highlight = array();

	/**
	 * The number of matching terms for the query input.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	public $terms;

	/**
	 * The static filter id.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $filter;

	/**
	 * The taxonomy filters. This is a multi-dimensional array of taxonomy
	 * branches as the first level and then the taxonomy nodes as the values.
	 *
	 * For example:
	 * $filters = array(
	 *     'Type' = array(10, 32, 29, 11, ...);
	 *     'Label' = array(20, 314, 349, 91, 82, ...);
	 *        ...
	 * );
	 *
	 * @var    array
	 * @since  2.5
	 */
	public $filters = array();

	/**
	 * The start date filter.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $date1;

	/**
	 * The end date filter.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $date2;

	/**
	 * The start date filter modifier.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $when1;

	/**
	 * The end date filter modifier.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $when2;

	/**
	 * Method to instantiate the query object.
	 *
	 * @param   array  $options  An array of query options.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public function __construct($options)
	{
		// Get the input string.
		$this->input = isset($options['input']) ? $options['input'] : '';

		// Get the empty query setting.
		$this->empty = isset($options['empty']) ? (bool) $options['empty'] : false;

		// Get the input language.
		$this->language = !empty($options['language']) ? $options['language'] : FinderIndexerHelper::getDefaultLanguage();
		$this->language = FinderIndexerHelper::getPrimaryLanguage($this->language);

		// Get the matching mode.
		$this->mode = 'AND';

		// Initialize the temporary date storage.
		$this->dates = new Registry;

		// Populate the temporary date storage.
		if (!empty($options['date1']))
		{
			$this->dates->set('date1', $options['date1']);
		}

		if (!empty($options['date2']))
		{
			$this->dates->set('date2', $options['date2']);
		}

		if (!empty($options['when1']))
		{
			$this->dates->set('when1', $options['when1']);
		}

		if (!empty($options['when2']))
		{
			$this->dates->set('when2', $options['when2']);
		}

		// Process the static taxonomy filters.
		if (!empty($options['filter']))
		{
			$this->processStaticTaxonomy($options['filter']);
		}

		// Process the dynamic taxonomy filters.
		if (!empty($options['filters']))
		{
			$this->processDynamicTaxonomy($options['filters']);
		}

		// Get the date filters.
		$d1 = $this->dates->get('date1');
		$d2 = $this->dates->get('date2');
		$w1 = $this->dates->get('when1');
		$w2 = $this->dates->get('when2');

		// Process the date filters.
		if (!empty($d1) || !empty($d2))
		{
			$this->processDates($d1, $d2, $w1, $w2);
		}

		// Process the input string.
		$this->processString($this->input, $this->language, $this->mode);

		// Get the number of matching terms.
		foreach ($this->included as $token)
		{
			$this->terms += count($token->matches);
		}

		// Remove the temporary date storage.
		unset($this->dates);

		// Lastly, determine whether this query can return a result set.

		// Check if we have a query string.
		if (!empty($this->input))
		{
			$this->search = true;
		}
		// Check if we can search without a query string.
		elseif ($this->empty && (!empty($this->filter) || !empty($this->filters) || !empty($this->date1) || !empty($this->date2)))
		{
			$this->search = true;
		}
		// We do not have a valid search query.
		else
		{
			$this->search = false;
		}
	}

	/**
	 * Method to convert the query object into a URI string.
	 *
	 * @param   string  $base  The base URI. [optional]
	 *
	 * @return  string  The complete query URI.
	 *
	 * @since   2.5
	 */
	public function toUri($base = '')
	{
		// Set the base if not specified.
		if ($base === '')
		{
			$base = 'index.php?option=com_finder&view=search';
		}

		// Get the base URI.
		$uri = JUri::getInstance($base);

		// Add the static taxonomy filter if present.
		if ((bool) $this->filter)
		{
			$uri->setVar('f', $this->filter);
		}

		// Get the filters in the request.
		$t = JFactory::getApplication()->input->request->get('t', array(), 'array');

		// Add the dynamic taxonomy filters if present.
		if ((bool) $this->filters)
		{
			foreach ($this->filters as $nodes)
			{
				foreach ($nodes as $node)
				{
					if (!in_array($node, $t))
					{
						continue;
					}

					$uri->setVar('t[]', $node);
				}
			}
		}

		// Add the input string if present.
		if (!empty($this->input))
		{
			$uri->setVar('q', $this->input);
		}

		// Add the start date if present.
		if (!empty($this->date1))
		{
			$uri->setVar('d1', $this->date1);
		}

		// Add the end date if present.
		if (!empty($this->date2))
		{
			$uri->setVar('d2', $this->date2);
		}

		// Add the start date modifier if present.
		if (!empty($this->when1))
		{
			$uri->setVar('w1', $this->when1);
		}

		// Add the end date modifier if present.
		if (!empty($this->when2))
		{
			$uri->setVar('w2', $this->when2);
		}

		// Add a menu item id if one is not present.
		if (!$uri->getVar('Itemid'))
		{
			// Get the menu item id.
			$query = array(
				'view' => $uri->getVar('view'),
				'f'    => $uri->getVar('f'),
				'q'    => $uri->getVar('q'),
			);

			$item = FinderHelperRoute::getItemid($query);

			// Add the menu item id if present.
			if ($item !== null)
			{
				$uri->setVar('Itemid', $item);
			}
		}

		return $uri->toString(array('path', 'query'));
	}

	/**
	 * Method to get a list of excluded search term ids.
	 *
	 * @return  array  An array of excluded term ids.
	 *
	 * @since   2.5
	 */
	public function getExcludedTermIds()
	{
		$results = array();

		// Iterate through the excluded tokens and compile the matching terms.
		for ($i = 0, $c = count($this->excluded); $i < $c; $i++)
		{
			$results = array_merge($results, $this->excluded[$i]->matches);
		}

		// Sanitize the terms.
		$results = array_unique($results);

		return ArrayHelper::toInteger($results);
	}

	/**
	 * Method to get a list of included search term ids.
	 *
	 * @return  array  An array of included term ids.
	 *
	 * @since   2.5
	 */
	public function getIncludedTermIds()
	{
		$results = array();

		// Iterate through the included tokens and compile the matching terms.
		for ($i = 0, $c = count($this->included); $i < $c; $i++)
		{
			// Check if we have any terms.
			if (empty($this->included[$i]->matches))
			{
				continue;
			}

			// Get the term.
			$term = $this->included[$i]->term;

			// Prepare the container for the term if necessary.
			if (!array_key_exists($term, $results))
			{
				$results[$term] = array();
			}

			// Add the matches to the stack.
			$results[$term] = array_merge($results[$term], $this->included[$i]->matches);
		}

		// Sanitize the terms.
		foreach ($results as $key => $value)
		{
			$results[$key] = array_unique($results[$key]);
			$results[$key] = ArrayHelper::toInteger($results[$key]);
		}

		return $results;
	}

	/**
	 * Method to get a list of required search term ids.
	 *
	 * @return  array  An array of required term ids.
	 *
	 * @since   2.5
	 */
	public function getRequiredTermIds()
	{
		$results = array();

		// Iterate through the included tokens and compile the matching terms.
		for ($i = 0, $c = count($this->included); $i < $c; $i++)
		{
			// Check if the token is required.
			if ($this->included[$i]->required)
			{
				// Get the term.
				$term = $this->included[$i]->term;

				// Prepare the container for the term if necessary.
				if (!array_key_exists($term, $results))
				{
					$results[$term] = array();
				}

				// Add the matches to the stack.
				$results[$term] = array_merge($results[$term], $this->included[$i]->matches);
			}
		}

		// Sanitize the terms.
		foreach ($results as $key => $value)
		{
			$results[$key] = array_unique($results[$key]);
			$results[$key] = ArrayHelper::toInteger($results[$key]);
		}

		return $results;
	}

	/**
	 * Method to process the static taxonomy input. The static taxonomy input
	 * comes in the form of a pre-defined search filter that is assigned to the
	 * search form.
	 *
	 * @param   integer  $filterId  The id of static filter.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function processStaticTaxonomy($filterId)
	{
		// Get the database object.
		$db = JFactory::getDbo();

		// Initialize user variables
		$groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels());

		// Load the predefined filter.
		$query = $db->getQuery(true)
			->select('f.data, f.params')
			->from($db->quoteName('#__finder_filters') . ' AS f')
			->where('f.filter_id = ' . (int) $filterId);

		$db->setQuery($query);
		$return = $db->loadObject();

		// Check the returned filter.
		if (empty($return))
		{
			return false;
		}

		// Set the filter.
		$this->filter = (int) $filterId;

		// Get a parameter object for the filter date options.
		$registry = new Registry($return->params);
		$params = $registry;

		// Set the dates if not already set.
		$this->dates->def('d1', $params->get('d1'));
		$this->dates->def('d2', $params->get('d2'));
		$this->dates->def('w1', $params->get('w1'));
		$this->dates->def('w2', $params->get('w2'));

		// Remove duplicates and sanitize.
		$filters = explode(',', $return->data);
		$filters = array_unique($filters);
		$filters = ArrayHelper::toInteger($filters);

		// Remove any values of zero.
		if (in_array(0, $filters, true) !== false)
		{
			unset($filters[array_search(0, $filters, true)]);
		}

		// Check if we have any real input.
		if (empty($filters))
		{
			return true;
		}

		/*
		 * Create the query to get filters from the database. We do this for
		 * two reasons: one, it allows us to ensure that the filters being used
		 * are real; two, we need to sort the filters by taxonomy branch.
		 */
		$query->clear()
			->select('t1.id, t1.title, t2.title AS branch')
			->from($db->quoteName('#__finder_taxonomy') . ' AS t1')
			->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id')
			->where('t1.state = 1')
			->where('t1.access IN (' . $groups . ')')
			->where('t1.id IN (' . implode(',', $filters) . ')')
			->where('t2.state = 1')
			->where('t2.access IN (' . $groups . ')');

		// Load the filters.
		$db->setQuery($query);
		$results = $db->loadObjectList();

		// Sort the filter ids by branch.
		foreach ($results as $result)
		{
			$this->filters[$result->branch][$result->title] = (int) $result->id;
		}

		return true;
	}

	/**
	 * Method to process the dynamic taxonomy input. The dynamic taxonomy input
	 * comes in the form of select fields that the user chooses from. The
	 * dynamic taxonomy input is processed AFTER the static taxonomy input
	 * because the dynamic options can be used to further narrow a static
	 * taxonomy filter.
	 *
	 * @param   array  $filters  An array of taxonomy node ids.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function processDynamicTaxonomy($filters)
	{
		// Initialize user variables
		$groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels());

		// Remove duplicates and sanitize.
		$filters = array_unique($filters);
		$filters = ArrayHelper::toInteger($filters);

		// Remove any values of zero.
		if (in_array(0, $filters, true) !== false)
		{
			unset($filters[array_search(0, $filters, true)]);
		}

		// Check if we have any real input.
		if (empty($filters))
		{
			return true;
		}

		// Get the database object.
		$db = JFactory::getDbo();

		$query = $db->getQuery(true);

		/*
		 * Create the query to get filters from the database. We do this for
		 * two reasons: one, it allows us to ensure that the filters being used
		 * are real; two, we need to sort the filters by taxonomy branch.
		 */
		$query->select('t1.id, t1.title, t2.title AS branch')
			->from($db->quoteName('#__finder_taxonomy') . ' AS t1')
			->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id')
			->where('t1.state = 1')
			->where('t1.access IN (' . $groups . ')')
			->where('t1.id IN (' . implode(',', $filters) . ')')
			->where('t2.state = 1')
			->where('t2.access IN (' . $groups . ')');

		// Load the filters.
		$db->setQuery($query);
		$results = $db->loadObjectList();

		// Cleared filter branches.
		$cleared = array();

		/*
		 * Sort the filter ids by branch. Because these filters are designed to
		 * override and further narrow the items selected in the static filter,
		 * we will clear the values from the static filter on a branch by
		 * branch basis before adding the dynamic filters. So, if the static
		 * filter defines a type filter of "articles" and three "category"
		 * filters but the user only limits the category further, the category
		 * filters will be flushed but the type filters will not.
		 */
		foreach ($results as $result)
		{
			// Check if the branch has been cleared.
			if (!in_array($result->branch, $cleared, true))
			{
				// Clear the branch.
				$this->filters[$result->branch] = array();

				// Add the branch to the cleared list.
				$cleared[] = $result->branch;
			}

			// Add the filter to the list.
			$this->filters[$result->branch][$result->title] = (int) $result->id;
		}

		return true;
	}

	/**
	 * Method to process the query date filters to determine start and end
	 * date limitations.
	 *
	 * @param   string  $date1  The first date filter.
	 * @param   string  $date2  The second date filter.
	 * @param   string  $when1  The first date modifier.
	 * @param   string  $when2  The second date modifier.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 */
	protected function processDates($date1, $date2, $when1, $when2)
	{
		// Clean up the inputs.
		$date1 = trim(StringHelper::strtolower($date1));
		$date2 = trim(StringHelper::strtolower($date2));
		$when1 = trim(StringHelper::strtolower($when1));
		$when2 = trim(StringHelper::strtolower($when2));

		// Get the time offset.
		$offset = JFactory::getApplication()->get('offset');

		// Array of allowed when values.
		$whens = array('before', 'after', 'exact');

		// The value of 'today' is a special case that we need to handle.
		if ($date1 === StringHelper::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY')))
		{
			$date1 = JFactory::getDate('now', $offset)->format('%Y-%m-%d');
		}

		// Try to parse the date string.
		$date = JFactory::getDate($date1, $offset);

		// Check if the date was parsed successfully.
		if ($date->toUnix() !== null)
		{
			// Set the date filter.
			$this->date1 = $date->toSql();
			$this->when1 = in_array($when1, $whens, true) ? $when1 : 'before';
		}

		// The value of 'today' is a special case that we need to handle.
		if ($date2 === StringHelper::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY')))
		{
			$date2 = JFactory::getDate('now', $offset)->format('%Y-%m-%d');
		}

		// Try to parse the date string.
		$date = JFactory::getDate($date2, $offset);

		// Check if the date was parsed successfully.
		if ($date->toUnix() !== null)
		{
			// Set the date filter.
			$this->date2 = $date->toSql();
			$this->when2 = in_array($when2, $whens, true) ? $when2 : 'before';
		}

		return true;
	}

	/**
	 * Method to process the query input string and extract required, optional,
	 * and excluded tokens; taxonomy filters; and date filters.
	 *
	 * @param   string  $input  The query input string.
	 * @param   string  $lang   The query input language.
	 * @param   string  $mode   The query matching mode.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function processString($input, $lang, $mode)
	{
		// Clean up the input string.
		$input = html_entity_decode($input, ENT_QUOTES, 'UTF-8');
		$input = StringHelper::strtolower($input);
		$input = preg_replace('#\s+#mi', ' ', $input);
		$input = trim($input);
		$debug = JFactory::getConfig()->get('debug_lang');

		/*
		 * First, we need to handle string based modifiers. String based
		 * modifiers could potentially include things like "category:blah" or
		 * "before:2009-10-21" or "type:article", etc.
		 */
		$patterns = array(
			'before' => JText::_('COM_FINDER_FILTER_WHEN_BEFORE'),
			'after'  => JText::_('COM_FINDER_FILTER_WHEN_AFTER'),
		);

		// Add the taxonomy branch titles to the possible patterns.
		foreach (FinderIndexerTaxonomy::getBranchTitles() as $branch)
		{
			// Add the pattern.
			$patterns[$branch] = StringHelper::strtolower(JText::_(FinderHelperLanguage::branchSingular($branch)));
		}

		// Container for search terms and phrases.
		$terms   = array();
		$phrases = array();

		// Cleared filter branches.
		$cleared = array();

		/*
		 * Compile the suffix pattern. This is used to match the values of the
		 * filter input string. Single words can be input directly, multi-word
		 * values have to be wrapped in double quotes.
		 */
		$quotes = html_entity_decode('&#8216;&#8217;&#39;', ENT_QUOTES, 'UTF-8');
		$suffix = '(([\w\d' . $quotes . '-]+)|\"([\w\d\s' . $quotes . '-]+)\")';

		/*
		 * Iterate through the possible filter patterns and search for matches.
		 * We need to match the key, colon, and a value pattern for the match
		 * to be valid.
		 */
		foreach ($patterns as $modifier => $pattern)
		{
			$matches = array();

			if ($debug)
			{
				$pattern = substr($pattern, 2, -2);
			}

			// Check if the filter pattern is in the input string.
			if (preg_match('#' . $pattern . '\s*:\s*' . $suffix . '#mi', $input, $matches))
			{
				// Get the value given to the modifier.
				$value = isset($matches[3]) ? $matches[3] : $matches[1];

				// Now we have to handle the filter string.
				switch ($modifier)
				{
					// Handle a before and after date filters.
					case 'before':
					case 'after':
					{
						// Get the time offset.
						$offset = JFactory::getApplication()->get('offset');

						// Array of allowed when values.
						$whens = array('before', 'after', 'exact');

						// The value of 'today' is a special case that we need to handle.
						if ($value === StringHelper::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY')))
						{
							$value = JFactory::getDate('now', $offset)->format('%Y-%m-%d');
						}

						// Try to parse the date string.
						$date = JFactory::getDate($value, $offset);

						// Check if the date was parsed successfully.
						if ($date->toUnix() !== null)
						{
							// Set the date filter.
							$this->date1 = $date->toSql();
							$this->when1 = in_array($modifier, $whens, true) ? $modifier : 'before';
						}

						break;
					}

					// Handle a taxonomy branch filter.
					default:
					{
						// Try to find the node id.
						$return = FinderIndexerTaxonomy::getNodeByTitle($modifier, $value);

						// Check if the node id was found.
						if ($return)
						{
							// Check if the branch has been cleared.
							if (!in_array($modifier, $cleared, true))
							{
								// Clear the branch.
								$this->filters[$modifier] = array();

								// Add the branch to the cleared list.
								$cleared[] = $modifier;
							}

							// Add the filter to the list.
							$this->filters[$modifier][$return->title] = (int) $return->id;
						}

						break;
					}
				}

				// Clean up the input string again.
				$input = str_replace($matches[0], '', $input);
				$input = preg_replace('#\s+#mi', ' ', $input);
				$input = trim($input);
			}
		}

		/*
		 * Extract the tokens enclosed in double quotes so that we can handle
		 * them as phrases.
		 */
		if (StringHelper::strpos($input, '"') !== false)
		{
			$matches = array();

			// Extract the tokens enclosed in double quotes.
			if (preg_match_all('#\"([^"]+)\"#m', $input, $matches))
			{
				/*
				 * One or more phrases were found so we need to iterate through
				 * them, tokenize them as phrases, and remove them from the raw
				 * input string before we move on to the next processing step.
				 */
				foreach ($matches[1] as $key => $match)
				{
					// Find the complete phrase in the input string.
					$pos = StringHelper::strpos($input, $matches[0][$key]);
					$len = StringHelper::strlen($matches[0][$key]);

					// Add any terms that are before this phrase to the stack.
					if (trim(StringHelper::substr($input, 0, $pos)))
					{
						$terms = array_merge($terms, explode(' ', trim(StringHelper::substr($input, 0, $pos))));
					}

					// Strip out everything up to and including the phrase.
					$input = StringHelper::substr($input, $pos + $len);

					// Clean up the input string again.
					$input = preg_replace('#\s+#mi', ' ', $input);
					$input = trim($input);

					// Get the number of words in the phrase.
					$parts = explode(' ', $match);

					// Check if the phrase is longer than three words.
					if (count($parts) > 3)
					{
						/*
						 * If the phrase is longer than three words, we need to
						 * break it down into smaller chunks of phrases that
						 * are less than or equal to three words. We overlap
						 * the chunks so that we can ensure that a match is
						 * found for the complete phrase and not just portions
						 * of it.
						 */
						for ($i = 0, $c = count($parts); $i < $c; $i += 2)
						{
							// Set up the chunk.
							$chunk = array();

							// The chunk has to be assembled based on how many
							// pieces are available to use.
							switch ($c - $i)
							{
								/*
								 * If only one word is left, we can break from
								 * the switch and loop because the last word
								 * was already used at the end of the last
								 * chunk.
								 */
								case 1:
									break 2;

								// If there words are left, we use them both as
								// the last chunk of the phrase and we're done.
								case 2:
									$chunk[] = $parts[$i];
									$chunk[] = $parts[$i + 1];
									break;

								// If there are three or more words left, we
								// build a three word chunk and continue on.
								default:
									$chunk[] = $parts[$i];
									$chunk[] = $parts[$i + 1];
									$chunk[] = $parts[$i + 2];
									break;
							}

							// If the chunk is not empty, add it as a phrase.
							if (count($chunk))
							{
								$phrases[] = implode(' ', $chunk);
								$terms[]   = implode(' ', $chunk);
							}
						}
					}
					else
					{
						// The phrase is <= 3 words so we can use it as is.
						$phrases[] = $match;
						$terms[]   = $match;
					}
				}
			}
		}

		// Add the remaining terms if present.
		if ((bool) $input)
		{
			$terms = array_merge($terms, explode(' ', $input));
		}

		// An array of our boolean operators. $operator => $translation
		$operators = array(
			'AND' => StringHelper::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_AND')),
			'OR'  => StringHelper::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_OR')),
			'NOT' => StringHelper::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_NOT')),
		);

		// If language debugging is enabled you need to ignore the debug strings in matching.
		if (JDEBUG)
		{
			$debugStrings = array('**', '??');
			$operators    = str_replace($debugStrings, '', $operators);
		}

		/*
		 * Iterate through the terms and perform any sorting that needs to be
		 * done based on boolean search operators. Terms that are before an
		 * and/or/not modifier have to be handled in relation to their operator.
		 */
		for ($i = 0, $c = count($terms); $i < $c; $i++)
		{
			// Check if the term is followed by an operator that we understand.
			if (isset($terms[$i + 1]) && in_array($terms[$i + 1], $operators, true))
			{
				// Get the operator mode.
				$op = array_search($terms[$i + 1], $operators, true);

				// Handle the AND operator.
				if ($op === 'AND' && isset($terms[$i + 2]))
				{
					// Tokenize the current term.
					$token = FinderIndexerHelper::tokenize($terms[$i], $lang, true);

					// Todo: The previous function call may return an array, which seems not to be handled by the next one, which expects an object
					$token = $this->getTokenData($token);

					// Set the required flag.
					$token->required = true;

					// Add the current token to the stack.
					$this->included[] = $token;
					$this->highlight  = array_merge($this->highlight, array_keys($token->matches));

					// Skip the next token (the mode operator).
					$this->operators[] = $terms[$i + 1];

					// Tokenize the term after the next term (current plus two).
					$other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true);
					$other = $this->getTokenData($other);

					// Set the required flag.
					$other->required = true;

					// Add the token after the next token to the stack.
					$this->included[] = $other;
					$this->highlight  = array_merge($this->highlight, array_keys($other->matches));

					// Remove the processed phrases if possible.
					if (($pk = array_search($terms[$i], $phrases, true)) !== false)
					{
						unset($phrases[$pk]);
					}

					if (($pk = array_search($terms[$i + 2], $phrases, true)) !== false)
					{
						unset($phrases[$pk]);
					}

					// Remove the processed terms.
					unset($terms[$i], $terms[$i + 1], $terms[$i + 2]);

					// Adjust the loop.
					$i += 2;
					continue;
				}
				// Handle the OR operator.
				elseif ($op === 'OR' && isset($terms[$i + 2]))
				{
					// Tokenize the current term.
					$token = FinderIndexerHelper::tokenize($terms[$i], $lang, true);
					$token = $this->getTokenData($token);

					// Set the required flag.
					$token->required = false;

					// Add the current token to the stack.
					if ((bool) $token->matches)
					{
						$this->included[] = $token;
						$this->highlight  = array_merge($this->highlight, array_keys($token->matches));
					}
					else
					{
						$this->ignored[] = $token;
					}

					// Skip the next token (the mode operator).
					$this->operators[] = $terms[$i + 1];

					// Tokenize the term after the next term (current plus two).
					$other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true);
					$other = $this->getTokenData($other);

					// Set the required flag.
					$other->required = false;

					// Add the token after the next token to the stack.
					if ((bool) $other->matches)
					{
						$this->included[] = $other;
						$this->highlight  = array_merge($this->highlight, array_keys($other->matches));
					}
					else
					{
						$this->ignored[] = $other;
					}

					// Remove the processed phrases if possible.
					if (($pk = array_search($terms[$i], $phrases, true)) !== false)
					{
						unset($phrases[$pk]);
					}

					if (($pk = array_search($terms[$i + 2], $phrases, true)) !== false)
					{
						unset($phrases[$pk]);
					}

					// Remove the processed terms.
					unset($terms[$i], $terms[$i + 1], $terms[$i + 2]);

					// Adjust the loop.
					$i += 2;
					continue;
				}
			}
			// Handle an orphaned OR operator.
			elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators, true) === 'OR')
			{
				// Skip the next token (the mode operator).
				$this->operators[] = $terms[$i];

				// Tokenize the next term (current plus one).
				$other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true);
				$other = $this->getTokenData($other);

				// Set the required flag.
				$other->required = false;

				// Add the token after the next token to the stack.
				if ((bool) $other->matches)
				{
					$this->included[] = $other;
					$this->highlight  = array_merge($this->highlight, array_keys($other->matches));
				}
				else
				{
					$this->ignored[] = $other;
				}

				// Remove the processed phrase if possible.
				if (($pk = array_search($terms[$i + 1], $phrases, true)) !== false)
				{
					unset($phrases[$pk]);
				}

				// Remove the processed terms.
				unset($terms[$i], $terms[$i + 1]);

				// Adjust the loop.
				$i++;
				continue;
			}
			// Handle the NOT operator.
			elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators, true) === 'NOT')
			{
				// Skip the next token (the mode operator).
				$this->operators[] = $terms[$i];

				// Tokenize the next term (current plus one).
				$other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true);
				$other = $this->getTokenData($other);

				// Set the required flag.
				$other->required = false;

				// Add the next token to the stack.
				if ((bool) $other->matches)
				{
					$this->excluded[] = $other;
				}
				else
				{
					$this->ignored[] = $other;
				}

				// Remove the processed phrase if possible.
				if (($pk = array_search($terms[$i + 1], $phrases, true)) !== false)
				{
					unset($phrases[$pk]);
				}

				// Remove the processed terms.
				unset($terms[$i], $terms[$i + 1]);

				// Adjust the loop.
				$i++;
				continue;
			}
		}

		/*
		 * Iterate through any search phrases and tokenize them. We handle
		 * phrases as autonomous units and do not break them down into two and
		 * three word combinations.
		 */
		for ($i = 0, $c = count($phrases); $i < $c; $i++)
		{
			// Tokenize the phrase.
			$token = FinderIndexerHelper::tokenize($phrases[$i], $lang, true);
			$token = $this->getTokenData($token);

			// Set the required flag.
			$token->required = true;

			// Add the current token to the stack.
			$this->included[] = $token;
			$this->highlight  = array_merge($this->highlight, array_keys($token->matches));

			// Remove the processed term if possible.
			if (($pk = array_search($phrases[$i], $terms, true)) !== false)
			{
				unset($terms[$pk]);
			}

			// Remove the processed phrase.
			unset($phrases[$i]);
		}

		/*
		 * Handle any remaining tokens using the standard processing mechanism.
		 */
		if ((bool) $terms)
		{
			// Tokenize the terms.
			$terms  = implode(' ', $terms);
			$tokens = FinderIndexerHelper::tokenize($terms, $lang, false);

			// Make sure we are working with an array.
			$tokens = is_array($tokens) ? $tokens : array($tokens);

			// Get the token data and required state for all the tokens.
			foreach ($tokens as $token)
			{
				// Get the token data.
				$token = $this->getTokenData($token);

				// Set the required flag for the token.
				$token->required = $mode === 'AND' ? (!$token->phrase) : false;

				// Add the token to the appropriate stack.
				if ($token->required || (bool) $token->matches)
				{
					$this->included[] = $token;
					$this->highlight  = array_merge($this->highlight, array_keys($token->matches));
				}
				else
				{
					$this->ignored[] = $token;
				}
			}
		}

		return true;
	}

	/**
	 * Method to get the base and similar term ids and, if necessary, suggested
	 * term data from the database. The terms ids are identified based on a
	 * 'like' match in MySQL and/or a common stem. If no term ids could be
	 * found, then we know that we will not be able to return any results for
	 * that term and we should try to find a similar term to use that we can
	 * match so that we can suggest the alternative search query to the user.
	 *
	 * @param   FinderIndexerToken  $token  A FinderIndexerToken object.
	 *
	 * @return  FinderIndexerToken  A FinderIndexerToken object.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function getTokenData($token)
	{
		// Get the database object.
		$db = JFactory::getDbo();

		// Create a database query to build match the token.
		$query = $db->getQuery(true)
			->select('t.term, t.term_id')
			->from('#__finder_terms AS t');

		/*
		 * If the token is a phrase, the lookup process is fairly simple. If
		 * the token is a word, it is a little more complicated. We have to
		 * create two queries to lookup the term and the stem respectively,
		 * then union the result sets together. This is MUCH faster than using
		 * an or condition in the database query.
		 */
		if ($token->phrase)
		{
			// Add the phrase to the query.
			$query->where('t.term = ' . $db->quote($token->term))
				->where('t.phrase = 1');
		}
		else
		{
			// Add the term to the query.
			$query->where('t.term = ' . $db->quote($token->term))
				->where('t.phrase = 0');

			// Clone the query, replace the WHERE clause.
			$sub = clone $query;
			$sub->clear('where');
			$sub->where('t.stem = ' . $db->quote($token->stem));
			$sub->where('t.phrase = 0');

			// Union the two queries.
			$query->union($sub);
		}

		// Get the terms.
		$db->setQuery($query);
		$matches = $db->loadObjectList();

		// Check the matching terms.
		if ((bool) $matches)
		{
			// Add the matches to the token.
			for ($i = 0, $c = count($matches); $i < $c; $i++)
			{
				$token->matches[$matches[$i]->term] = (int) $matches[$i]->term_id;
			}
		}

		// If no matches were found, try to find a similar but better token.
		if (empty($token->matches))
		{
			// Create a database query to get the similar terms.
			// TODO: PostgreSQL doesn't support SOUNDEX out of the box
			$query->clear()
				->select('DISTINCT t.term_id AS id, t.term AS term')
				->from('#__finder_terms AS t')
				// ->where('t.soundex = ' . soundex($db->quote($token->term)))
				->where('t.soundex = SOUNDEX(' . $db->quote($token->term) . ')')
				->where('t.phrase = ' . (int) $token->phrase);

			// Get the terms.
			$db->setQuery($query);
			$results = $db->loadObjectList();

			// Check if any similar terms were found.
			if (empty($results))
			{
				return $token;
			}

			// Stack for sorting the similar terms.
			$suggestions = array();

			// Get the levnshtein distance for all suggested terms.
			foreach ($results as $sk => $st)
			{
				// Get the levenshtein distance between terms.
				$distance = levenshtein($st->term, $token->term);

				// Make sure the levenshtein distance isn't over 50.
				if ($distance < 50)
				{
					$suggestions[$sk] = $distance;
				}
			}

			// Sort the suggestions.
			asort($suggestions, SORT_NUMERIC);

			// Get the closest match.
			$keys = array_keys($suggestions);
			$key  = $keys[0];

			// Add the suggested term.
			$token->suggestion = $results[$key]->term;
		}

		return $token;
	}
}
PKW|!]���~LLindexer/driver/mysql.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

jimport('joomla.filesystem.file');

/**
 * Indexer class supporting MySQL(i) for the Finder indexer package.
 *
 * The indexer class provides the core functionality of the Finder
 * search engine. It is responsible for adding and updating the
 * content links table; extracting and scoring tokens; and maintaining
 * all referential information for the content.
 *
 * Note: All exceptions thrown from within this class should be caught
 * by the controller.
 *
 * @since  3.0
 */
class FinderIndexerDriverMysql extends FinderIndexer
{
	/**
	 * Method to index a content item.
	 *
	 * @param   FinderIndexerResult  $item    The content item to index.
	 * @param   string               $format  The format of the content. [optional]
	 *
	 * @return  integer  The ID of the record in the links table.
	 *
	 * @since   3.0
	 * @throws  Exception on database error.
	 */
	public function index($item, $format = 'html')
	{
		// Mark beforeIndexing in the profiler.
		static::$profiler ? static::$profiler->mark('beforeIndexing') : null;
		$db = $this->db;
		$nd = $db->getNullDate();

		// Check if the item is in the database.
		$query = $db->getQuery(true)
			->select($db->quoteName('link_id') . ', ' . $db->quoteName('md5sum'))
			->from($db->quoteName('#__finder_links'))
			->where($db->quoteName('url') . ' = ' . $db->quote($item->url));

		// Load the item  from the database.
		$db->setQuery($query);
		$link = $db->loadObject();

		// Get the indexer state.
		$state = static::getState();

		// Get the signatures of the item.
		$curSig = static::getSignature($item);
		$oldSig = isset($link->md5sum) ? $link->md5sum : null;

		// Get the other item information.
		$linkId = empty($link->link_id) ? null : $link->link_id;
		$isNew = empty($link->link_id) ? true : false;

		// Check the signatures. If they match, the item is up to date.
		if (!$isNew && $curSig == $oldSig)
		{
			return $linkId;
		}

		/*
		 * If the link already exists, flush all the term maps for the item.
		 * Maps are stored in 16 tables so we need to iterate through and flush
		 * each table one at a time.
		 */
		if (!$isNew)
		{
			for ($i = 0; $i <= 15; $i++)
			{
				// Flush the maps for the link.
				$query->clear()
					->delete($db->quoteName('#__finder_links_terms' . dechex($i)))
					->where($db->quoteName('link_id') . ' = ' . (int) $linkId);
				$db->setQuery($query);
				$db->execute();
			}

			// Remove the taxonomy maps.
			FinderIndexerTaxonomy::removeMaps($linkId);
		}

		// Mark afterUnmapping in the profiler.
		static::$profiler ? static::$profiler->mark('afterUnmapping') : null;

		// Perform cleanup on the item data.
		$item->publish_start_date = (int) $item->publish_start_date != 0 ? $item->publish_start_date : $nd;
		$item->publish_end_date = (int) $item->publish_end_date != 0 ? $item->publish_end_date : $nd;
		$item->start_date = (int) $item->start_date != 0 ? $item->start_date : $nd;
		$item->end_date = (int) $item->end_date != 0 ? $item->end_date : $nd;

		// Prepare the item description.
		$item->description = FinderIndexerHelper::parse($item->summary);

		/*
		 * Now, we need to enter the item into the links table. If the item
		 * already exists in the database, we need to use an UPDATE query.
		 * Otherwise, we need to use an INSERT to get the link id back.
		 */

		if ($isNew)
		{
			$columnsArray = array(
				$db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'),
				$db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'),
				$db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'),
				$db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'),
				$db->quoteName('sale_price')
			);

			// Insert the link.
			$query->clear()
				->insert($db->quoteName('#__finder_links'))
				->columns($columnsArray)
				->values(
					$db->quote($item->url) . ', '
					. $db->quote($item->route) . ', '
					. $db->quote($item->title) . ', '
					. $db->quote($item->description) . ', '
					. $query->currentTimestamp() . ', '
					. '1, '
					. (int) $item->state . ', '
					. (int) $item->access . ', '
					. $db->quote($item->language) . ', '
					. (int) $item->type_id . ', '
					. $db->quote(serialize($item)) . ', '
					. $db->quote($item->publish_start_date) . ', '
					. $db->quote($item->publish_end_date) . ', '
					. $db->quote($item->start_date) . ', '
					. $db->quote($item->end_date) . ', '
					. (double) ($item->list_price ?: 0) . ', '
					. (double) ($item->sale_price ?: 0)
				);
			$db->setQuery($query);
			$db->execute();

			// Get the link id.
			$linkId = (int) $db->insertid();
		}
		else
		{
			// Update the link.
			$query->clear()
				->update($db->quoteName('#__finder_links'))
				->set($db->quoteName('route') . ' = ' . $db->quote($item->route))
				->set($db->quoteName('title') . ' = ' . $db->quote($item->title))
				->set($db->quoteName('description') . ' = ' . $db->quote($item->description))
				->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp())
				->set($db->quoteName('state') . ' = ' . (int) $item->state)
				->set($db->quoteName('access') . ' = ' . (int) $item->access)
				->set($db->quoteName('language') . ' = ' . $db->quote($item->language))
				->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id)
				->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item)))
				->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date))
				->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date))
				->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date))
				->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date))
				->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ?: 0))
				->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ?: 0))
				->where('link_id = ' . (int) $linkId);
			$db->setQuery($query);
			$db->execute();
		}

		// Set up the variables we will need during processing.
		$count = 0;

		// Mark afterLinking in the profiler.
		static::$profiler ? static::$profiler->mark('afterLinking') : null;

		// Truncate the tokens tables.
		$db->truncateTable('#__finder_tokens');

		// Truncate the tokens aggregate table.
		$db->truncateTable('#__finder_tokens_aggregate');

		/*
		 * Process the item's content. The items can customize their
		 * processing instructions to define extra properties to process
		 * or rearrange how properties are weighted.
		 */
		foreach ($item->getInstructions() as $group => $properties)
		{
			// Iterate through the properties of the group.
			foreach ($properties as $property)
			{
				// Check if the property exists in the item.
				if (empty($item->$property))
				{
					continue;
				}

				// Tokenize the property.
				if (is_array($item->$property))
				{
					// Tokenize an array of content and add it to the database.
					foreach ($item->$property as $ip)
					{
						/*
						 * If the group is path, we need to a few extra processing
						 * steps to strip the extension and convert slashes and dashes
						 * to spaces.
						 */
						if ($group === static::PATH_CONTEXT)
						{
							$ip = JFile::stripExt($ip);
							$ip = str_replace(array('/', '-'), ' ', $ip);
						}

						// Tokenize a string of content and add it to the database.
						$count += $this->tokenizeToDb($ip, $group, $item->language, $format);

						// Check if we're approaching the memory limit of the token table.
						if ($count > static::$state->options->get('memory_table_limit', 30000))
						{
							$this->toggleTables(false);
						}
					}
				}
				else
				{
					/*
					 * If the group is path, we need to a few extra processing
					 * steps to strip the extension and convert slashes and dashes
					 * to spaces.
					 */
					if ($group === static::PATH_CONTEXT)
					{
						$item->$property = JFile::stripExt($item->$property);
						$item->$property = str_replace('/', ' ', $item->$property);
						$item->$property = str_replace('-', ' ', $item->$property);
					}

					// Tokenize a string of content and add it to the database.
					$count += $this->tokenizeToDb($item->$property, $group, $item->language, $format);

					// Check if we're approaching the memory limit of the token table.
					if ($count > static::$state->options->get('memory_table_limit', 30000))
					{
						$this->toggleTables(false);
					}
				}
			}
		}

		/*
		 * Process the item's taxonomy. The items can customize their
		 * taxonomy mappings to define extra properties to map.
		 */
		foreach ($item->getTaxonomy() as $branch => $nodes)
		{
			// Iterate through the nodes and map them to the branch.
			foreach ($nodes as $node)
			{
				// Add the node to the tree.
				$nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access);

				// Add the link => node map.
				FinderIndexerTaxonomy::addMap($linkId, $nodeId);
			}
		}

		// Mark afterProcessing in the profiler.
		static::$profiler ? static::$profiler->mark('afterProcessing') : null;

		/*
		 * At this point, all of the item's content has been parsed, tokenized
		 * and inserted into the #__finder_tokens table. Now, we need to
		 * aggregate all the data into that table into a more usable form. The
		 * aggregated data will be inserted into #__finder_tokens_aggregate
		 * table.
		 */
		$query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') .
			' (' . $db->quoteName('term_id') .
			', ' . $db->quoteName('map_suffix') .
				', ' . $db->quoteName('term') .
			', ' . $db->quoteName('stem') .
			', ' . $db->quoteName('common') .
			', ' . $db->quoteName('phrase') .
			', ' . $db->quoteName('term_weight') .
			', ' . $db->quoteName('context') .
			', ' . $db->quoteName('context_weight') .
			', ' . $db->quoteName('total_weight') .
				', ' . $db->quoteName('language') . ')' .
			' SELECT' .
			' COALESCE(t.term_id, 0), \'\', t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' .
			' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, 0, t1.language' .
			' FROM (' .
			'   SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
			'   FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' .
			'   WHERE t1.context = %d' .
			' ) AS t1' .
			' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' .
			' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' .
			' WHERE t2.context = %d' .
			' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
			' ORDER BY t1.term DESC';

		// Iterate through the contexts and aggregate the tokens per context.
		foreach ($state->weights as $context => $multiplier)
		{
			// Run the query to aggregate the tokens for this context..
			$db->setQuery(sprintf($query, $multiplier, $context, $context));
			$db->execute();
		}

		// Mark afterAggregating in the profiler.
		static::$profiler ? static::$profiler->mark('afterAggregating') : null;

		/*
		 * When we pulled down all of the aggregate data, we did a LEFT JOIN
		 * over the terms table to try to find all the term ids that
		 * already exist for our tokens. If any of the rows in the aggregate
		 * table have a term of 0, then no term record exists for that
		 * term so we need to add it to the terms table.
		 */
		$db->setQuery(
			'INSERT IGNORE INTO ' . $db->quoteName('#__finder_terms') .
			' (' . $db->quoteName('term') .
			', ' . $db->quoteName('stem') .
			', ' . $db->quoteName('common') .
			', ' . $db->quoteName('phrase') .
			', ' . $db->quoteName('weight') .
			', ' . $db->quoteName('soundex') .
			', ' . $db->quoteName('language') . ')' .
			' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' .
			' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' .
			' WHERE ta.term_id = 0' .
			' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language'
		);
		$db->execute();

		/*
		 * Now, we just inserted a bunch of new records into the terms table
		 * so we need to go back and update the aggregate table with all the
		 * new term ids.
		 */
		$query = $db->getQuery(true)
			->update($db->quoteName('#__finder_tokens_aggregate') . ' AS ta')
			->join('INNER', $db->quoteName('#__finder_terms') . ' AS t ON t.term = ta.term')
			->set('ta.term_id = t.term_id')
			->where('ta.term_id = 0');
		$db->setQuery($query);
		$db->execute();

		// Mark afterTerms in the profiler.
		static::$profiler ? static::$profiler->mark('afterTerms') : null;

		/*
		 * After we've made sure that all of the terms are in the terms table
		 * and the aggregate table has the correct term ids, we need to update
		 * the links counter for each term by one.
		 */
		$query->clear()
			->update($db->quoteName('#__finder_terms') . ' AS t')
			->join('INNER', $db->quoteName('#__finder_tokens_aggregate') . ' AS ta ON ta.term_id = t.term_id')
			->set('t.' . $db->quoteName('links') . ' = t.links + 1');
		$db->setQuery($query);
		$db->execute();

		// Mark afterTerms in the profiler.
		static::$profiler ? static::$profiler->mark('afterTerms') : null;

		/*
		 * Before we can insert all of the mapping rows, we have to figure out
		 * which mapping table the rows need to be inserted into. The mapping
		 * table for each term is based on the first character of the md5 of
		 * the first character of the term. In php, it would be expressed as
		 * substr(md5(substr($token, 0, 1)), 0, 1)
		 */
		$query->clear()
			->update($db->quoteName('#__finder_tokens_aggregate'))
			->set($db->quoteName('map_suffix') . ' = SUBSTR(MD5(SUBSTR(' . $db->quoteName('term') . ', 1, 1)), 1, 1)');
		$db->setQuery($query);
		$db->execute();

		/*
		 * At this point, the aggregate table contains a record for each
		 * term in each context. So, we're going to pull down all of that
		 * data while grouping the records by term and add all of the
		 * sub-totals together to arrive at the final total for each token for
		 * this link. Then, we insert all of that data into the appropriate
		 * mapping table.
		 */
		for ($i = 0; $i <= 15; $i++)
		{
			// Get the mapping table suffix.
			$suffix = dechex($i);

			/*
			 * We have to run this query 16 times, one for each link => term
			 * mapping table.
			 */
			$db->setQuery(
				'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) .
				' (' . $db->quoteName('link_id') .
				', ' . $db->quoteName('term_id') .
				', ' . $db->quoteName('weight') . ')' .
				' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' .
				' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' .
				' FROM ' . $db->quoteName('#__finder_tokens_aggregate') .
				' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) .
				' GROUP BY ' . $db->quoteName('term') . ', ' . $db->quoteName('term_id') .
				' ORDER BY ' . $db->quoteName('term') . ' DESC'
			);
			$db->execute();
		}

		// Mark afterMapping in the profiler.
		static::$profiler ? static::$profiler->mark('afterMapping') : null;

		// Update the signature.
		$object = serialize($item);
		$query->clear()
			->update($db->quoteName('#__finder_links'))
			->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig))
			->set($db->quoteName('object') . ' = ' . $db->quote($object))
			->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId));
		$db->setQuery($query);
		$db->execute();

		// Mark afterSigning in the profiler.
		static::$profiler ? static::$profiler->mark('afterSigning') : null;

		// Truncate the tokens tables.
		$db->truncateTable('#__finder_tokens');

		// Truncate the tokens aggregate table.
		$db->truncateTable('#__finder_tokens_aggregate');

		// Toggle the token tables back to memory tables.
		$this->toggleTables(true);

		// Mark afterTruncating in the profiler.
		static::$profiler ? static::$profiler->mark('afterTruncating') : null;

		return $linkId;
	}

	/**
	 * Method to optimize the index. We use this method to remove unused terms
	 * and any other optimizations that might be necessary.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.0
	 * @throws  Exception on database error.
	 */
	public function optimize()
	{
		// Get the database object.
		$db = $this->db;
		$query = $db->getQuery(true);

		// Delete all orphaned terms.
		$query->delete($db->quoteName('#__finder_terms'))
			->where($db->quoteName('links') . ' <= 0');
		$db->setQuery($query);
		$db->execute();

		// Optimize the links table.
		$db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links'));
		$db->execute();

		for ($i = 0; $i <= 15; $i++)
		{
			// Optimize the terms mapping table.
			$db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links_terms' . dechex($i)));
			$db->execute();
		}

		// Optimize the filters table.
		$db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_filters'));
		$db->execute();

		// Optimize the terms common table.
		$db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_terms_common'));
		$db->execute();

		// Optimize the types table.
		$db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_types'));
		$db->execute();

		// Remove the orphaned taxonomy nodes.
		FinderIndexerTaxonomy::removeOrphanNodes();

		// Optimize the taxonomy mapping table.
		$db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_taxonomy_map'));
		$db->execute();

		// Optimize the taxonomy table.
		$db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_taxonomy'));
		$db->execute();

		return true;
	}


	/**
	 * Method to switch the token tables from Memory tables to MyISAM tables
	 * when they are close to running out of memory.
	 *
	 * @param   boolean  $memory  Flag to control how they should be toggled.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.0
	 * @throws  Exception on database error.
	 */
	protected function toggleTables($memory)
	{
		static $state;

		// Get the database adapter.
		$db = $this->db;

		// Check if we are setting the tables to the Memory engine.
		if ($memory === true && $state !== true)
		{
			// Set the tokens table to Memory.
			$db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens') . ' ENGINE = MEMORY');
			$db->execute();

			// Set the tokens aggregate table to Memory.
			$db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens_aggregate') . ' ENGINE = MEMORY');
			$db->execute();

			// Set the internal state.
			$state = $memory;
		}
		// We must be setting the tables to the MyISAM engine.
		elseif ($memory === false && $state !== false)
		{
			// Set the tokens table to MyISAM.
			$db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens') . ' ENGINE = MYISAM');
			$db->execute();

			// Set the tokens aggregate table to MyISAM.
			$db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens_aggregate') . ' ENGINE = MYISAM');
			$db->execute();

			// Set the internal state.
			$state = $memory;
		}

		return true;
	}
}
PKW|!]����h?h?indexer/driver/postgresql.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\String\StringHelper;

jimport('joomla.filesystem.file');

/**
 * Indexer class supporting PostgreSQL for the Finder indexer package.
 *
 * @since  3.0
 */
class FinderIndexerDriverPostgresql extends FinderIndexer
{
	/**
	 * Method to index a content item.
	 *
	 * @param   FinderIndexerResult  $item    The content item to index.
	 * @param   string               $format  The format of the content. [optional]
	 *
	 * @return  integer  The ID of the record in the links table.
	 *
	 * @since   3.0
	 * @throws  Exception on database error.
	 */
	public function index($item, $format = 'html')
	{
		// Mark beforeIndexing in the profiler.
		static::$profiler ? static::$profiler->mark('beforeIndexing') : null;
		$db = $this->db;
		$nd = $db->getNullDate();

		// Check if the item is in the database.
		$query = $db->getQuery(true)
			->select($db->quoteName('link_id') . ', ' . $db->quoteName('md5sum'))
			->from($db->quoteName('#__finder_links'))
			->where($db->quoteName('url') . ' = ' . $db->quote($item->url));

		// Load the item  from the database.
		$db->setQuery($query);
		$link = $db->loadObject();

		// Get the indexer state.
		$state = static::getState();

		// Get the signatures of the item.
		$curSig = static::getSignature($item);
		$oldSig = isset($link->md5sum) ? $link->md5sum : null;

		// Get the other item information.
		$linkId = empty($link->link_id) ? null : $link->link_id;
		$isNew = empty($link->link_id) ? true : false;

		// Check the signatures. If they match, the item is up to date.
		if (!$isNew && $curSig === $oldSig)
		{
			return $linkId;
		}

		/*
		 * If the link already exists, flush all the term maps for the item.
		 * Maps are stored in 16 tables so we need to iterate through and flush
		 * each table one at a time.
		 */
		if (!$isNew)
		{
			for ($i = 0; $i <= 15; $i++)
			{
				// Flush the maps for the link.
				$query->clear()
					->delete($db->quoteName('#__finder_links_terms' . dechex($i)))
					->where($db->quoteName('link_id') . ' = ' . (int) $linkId);
				$db->setQuery($query);
				$db->execute();
			}

			// Remove the taxonomy maps.
			FinderIndexerTaxonomy::removeMaps($linkId);
		}

		// Mark afterUnmapping in the profiler.
		static::$profiler ? static::$profiler->mark('afterUnmapping') : null;

		// Perform cleanup on the item data.
		$item->publish_start_date = (int) $item->publish_start_date != 0 ? $item->publish_start_date : $nd;
		$item->publish_end_date = (int) $item->publish_end_date != 0 ? $item->publish_end_date : $nd;
		$item->start_date = (int) $item->start_date != 0 ? $item->start_date : $nd;
		$item->end_date = (int) $item->end_date != 0 ? $item->end_date : $nd;

		// Prepare the item description.
		$item->description = FinderIndexerHelper::parse($item->summary);

		/*
		 * Now, we need to enter the item into the links table. If the item
		 * already exists in the database, we need to use an UPDATE query.
		 * Otherwise, we need to use an INSERT to get the link id back.
		 */

		$entry = new stdClass;
		$entry->url = $item->url;
		$entry->route = $item->route;
		$entry->title = $item->title;

		// We are shortening the description in order to not run into length issues with this field
		$entry->description = StringHelper::substr($item->description, 0, 32000);
		$entry->indexdate = Factory::getDate()->toSql();
		$entry->state = (int) $item->state;
		$entry->access = (int) $item->access;
		$entry->language = $item->language;
		$entry->type_id = (int) $item->type_id;
		$entry->object = '';
		$entry->publish_start_date = $item->publish_start_date;
		$entry->publish_end_date = $item->publish_end_date;
		$entry->start_date = $item->start_date;
		$entry->end_date = $item->end_date;
		$entry->list_price = (double) ($item->list_price ?: 0);
		$entry->sale_price = (double) ($item->sale_price ?: 0);

		if ($isNew)
		{
			// Insert the link and get its id.
			$db->insertObject('#__finder_links', $entry);
			$linkId = (int) $db->insertid();
		}
		else
		{
			// Update the link.
			$entry->link_id = $linkId;
			$db->updateObject('#__finder_links', $entry, 'link_id');
		}

		// Set up the variables we will need during processing.
		$count = 0;

		// Mark afterLinking in the profiler.
		static::$profiler ? static::$profiler->mark('afterLinking') : null;

		// Truncate the tokens tables.
		$db->truncateTable('#__finder_tokens');

		// Truncate the tokens aggregate table.
		$db->truncateTable('#__finder_tokens_aggregate');

		/*
		 * Process the item's content. The items can customize their
		 * processing instructions to define extra properties to process
		 * or rearrange how properties are weighted.
		 */
		foreach ($item->getInstructions() as $group => $properties)
		{
			// Iterate through the properties of the group.
			foreach ($properties as $property)
			{
				// Check if the property exists in the item.
				if (empty($item->$property))
				{
					continue;
				}

				// Tokenize the property.
				if (is_array($item->$property))
				{
					// Tokenize an array of content and add it to the database.
					foreach ($item->$property as $ip)
					{
						/*
						 * If the group is path, we need to a few extra processing
						 * steps to strip the extension and convert slashes and dashes
						 * to spaces.
						 */
						if ($group === static::PATH_CONTEXT)
						{
							$ip = JFile::stripExt($ip);
							$ip = str_replace(array('/', '-'), ' ', $ip);
						}

						// Tokenize a string of content and add it to the database.
						$count += $this->tokenizeToDb($ip, $group, $item->language, $format);

						// Check if we're approaching the memory limit of the token table.
						if ($count > static::$state->options->get('memory_table_limit', 30000))
						{
							$this->toggleTables(false);
						}
					}
				}
				else
				{
					/*
					 * If the group is path, we need to a few extra processing
					 * steps to strip the extension and convert slashes and dashes
					 * to spaces.
					 */
					if ($group === static::PATH_CONTEXT)
					{
						$item->$property = JFile::stripExt($item->$property);
						$item->$property = str_replace('/', ' ', $item->$property);
						$item->$property = str_replace('-', ' ', $item->$property);
					}

					// Tokenize a string of content and add it to the database.
					$count += $this->tokenizeToDb($item->$property, $group, $item->language, $format);

					// Check if we're approaching the memory limit of the token table.
					if ($count > static::$state->options->get('memory_table_limit', 30000))
					{
						$this->toggleTables(false);
					}
				}
			}
		}

		/*
		 * Process the item's taxonomy. The items can customize their
		 * taxonomy mappings to define extra properties to map.
		 */
		foreach ($item->getTaxonomy() as $branch => $nodes)
		{
			// Iterate through the nodes and map them to the branch.
			foreach ($nodes as $node)
			{
				// Add the node to the tree.
				$nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access);

				// Add the link => node map.
				FinderIndexerTaxonomy::addMap($linkId, $nodeId);
			}
		}

		// Mark afterProcessing in the profiler.
		static::$profiler ? static::$profiler->mark('afterProcessing') : null;

		/*
		 * At this point, all of the item's content has been parsed, tokenized
		 * and inserted into the #__finder_tokens table. Now, we need to
		 * aggregate all the data into that table into a more usable form. The
		 * aggregated data will be inserted into #__finder_tokens_aggregate
		 * table.
		 */
		$query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') .
			' (' . $db->quoteName('term_id') .
			', ' . $db->quoteName('map_suffix') .
			', ' . $db->quoteName('term') .
			', ' . $db->quoteName('stem') .
			', ' . $db->quoteName('common') .
			', ' . $db->quoteName('phrase') .
			', ' . $db->quoteName('term_weight') .
			', ' . $db->quoteName('context') .
			', ' . $db->quoteName('context_weight') .
			', ' . $db->quoteName('total_weight') .
			', ' . $db->quoteName('language') . ')' .
			' SELECT' .
			' COALESCE(t.term_id, 0), \'\', t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' .
			' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, 0, t1.language' .
			' FROM (' .
			'   SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
			'   FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' .
			'   WHERE t1.context = %d' .
			' ) AS t1' .
			' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term AND t2.language = t1.language' .
			' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term ' .
			' WHERE t2.context = %d' .
			' GROUP BY t1.term, t.term_id, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
			' ORDER BY t1.term DESC';

		// Iterate through the contexts and aggregate the tokens per context.
		foreach ($state->weights as $context => $multiplier)
		{
			// Run the query to aggregate the tokens for this context..
			$db->setQuery(sprintf($query, $multiplier, $context, $context));
			$db->execute();
		}

		// Mark afterAggregating in the profiler.
		static::$profiler ? static::$profiler->mark('afterAggregating') : null;

		/*
		 * When we pulled down all of the aggregate data, we did a LEFT JOIN
		 * over the terms table to try to find all the term ids that
		 * already exist for our tokens. If any of the rows in the aggregate
		 * table have a term of 0, then no term record exists for that
		 * term so we need to add it to the terms table.
		 */
		$db->setQuery(
			'INSERT INTO ' . $db->quoteName('#__finder_terms') .
			' (' . $db->quoteName('term') .
			', ' . $db->quoteName('stem') .
			', ' . $db->quoteName('common') .
			', ' . $db->quoteName('phrase') .
			', ' . $db->quoteName('weight') .
			', ' . $db->quoteName('soundex') .
			', ' . $db->quoteName('language') . ')' .
			' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' .
			' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' .
			' WHERE ta.term_id = 0' .
			' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language'
		);
		$db->execute();

		/*
		 * Now, we just inserted a bunch of new records into the terms table
		 * so we need to go back and update the aggregate table with all the
		 * new term ids.
		 */
		$query = $db->getQuery(true)
			->update($db->quoteName('#__finder_tokens_aggregate') . ' AS ta')
			->join('INNER', $db->quoteName('#__finder_terms') . ' AS t ON t.term = ta.term')
			->set('term_id = t.term_id')
			->where('ta.term_id = 0');
		$db->setQuery($query);
		$db->execute();

		// Mark afterTerms in the profiler.
		static::$profiler ? static::$profiler->mark('afterTerms') : null;

		/*
		 * After we've made sure that all of the terms are in the terms table
		 * and the aggregate table has the correct term ids, we need to update
		 * the links counter for each term by one.
		 */
		$query->clear()
			->update($db->quoteName('#__finder_terms') . ' AS t')
			->join('INNER', $db->quoteName('#__finder_tokens_aggregate') . ' AS ta ON ta.term_id = t.term_id')
			->set($db->quoteName('links') . ' = t.links + 1');
		$db->setQuery($query);
		$db->execute();

		// Mark afterTerms in the profiler.
		static::$profiler ? static::$profiler->mark('afterTerms') : null;

		/*
		 * Before we can insert all of the mapping rows, we have to figure out
		 * which mapping table the rows need to be inserted into. The mapping
		 * table for each term is based on the first character of the md5 of
		 * the first character of the term. In php, it would be expressed as
		 * substr(md5(substr($token, 0, 1)), 0, 1)
		 */
		$query->clear()
			->update($db->quoteName('#__finder_tokens_aggregate'))
			->set($db->quoteName('map_suffix') . ' = SUBSTR(MD5(SUBSTR(' . $db->quoteName('term') . ', 1, 1)), 1, 1)');
		$db->setQuery($query);
		$db->execute();

		/*
		 * At this point, the aggregate table contains a record for each
		 * term in each context. So, we're going to pull down all of that
		 * data while grouping the records by term and add all of the
		 * sub-totals together to arrive at the final total for each token for
		 * this link. Then, we insert all of that data into the appropriate
		 * mapping table.
		 */
		for ($i = 0; $i <= 15; $i++)
		{
			// Get the mapping table suffix.
			$suffix = dechex($i);

			/*
			 * We have to run this query 16 times, one for each link => term
			 * mapping table.
			 */
			$db->setQuery(
				'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) .
				' (' . $db->quoteName('link_id') .
				', ' . $db->quoteName('term_id') .
				', ' . $db->quoteName('weight') . ')' .
				' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' .
				' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' .
				' FROM ' . $db->quoteName('#__finder_tokens_aggregate') .
				' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) .
				' GROUP BY ' . $db->quoteName('term') . ', ' . $db->quoteName('term_id') .
				' ORDER BY ' . $db->quoteName('term') . ' DESC'
			);
			$db->execute();
		}

		// Mark afterMapping in the profiler.
		static::$profiler ? static::$profiler->mark('afterMapping') : null;

		// Update the signature.
		$object = serialize($item);
		$query->clear()
			->update($db->quoteName('#__finder_links'))
			->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig))
			->set($db->quoteName('object') . ' = ' . $db->quote(pg_escape_bytea($object)))
			->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId));
		$db->setQuery($query);
		$db->execute();

		// Mark afterSigning in the profiler.
		static::$profiler ? static::$profiler->mark('afterSigning') : null;

		// Truncate the tokens tables.
		$db->truncateTable('#__finder_tokens');

		// Truncate the tokens aggregate table.
		$db->truncateTable('#__finder_tokens_aggregate');

		// Toggle the token tables back to memory tables.
		$this->toggleTables(true);

		// Mark afterTruncating in the profiler.
		static::$profiler ? static::$profiler->mark('afterTruncating') : null;

		return $linkId;
	}

	/**
	 * Method to optimize the index. We use this method to remove unused terms
	 * and any other optimizations that might be necessary.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public function optimize()
	{
		// Get the database object.
		$db = $this->db;
		$query = $db->getQuery(true);

		// Delete all orphaned terms.
		$query->delete($db->quoteName('#__finder_terms'))
			->where($db->quoteName('links') . ' <= 0');
		$db->setQuery($query);
		$db->execute();

		// Optimize the links table.
		$db->setQuery('VACUUM ' . $db->quoteName('#__finder_links'));
		$db->execute();
		$db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_links'));
		$db->execute();

		for ($i = 0; $i <= 15; $i++)
		{
			// Optimize the terms mapping table.
			$db->setQuery('VACUUM ' . $db->quoteName('#__finder_links_terms' . dechex($i)));
			$db->execute();
			$db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_links_terms' . dechex($i)));
			$db->execute();
		}

		// Optimize the filters table.
		$db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_filters'));
		$db->execute();

		// Optimize the terms common table.
		$db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_terms_common'));
		$db->execute();

		// Optimize the types table.
		$db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_types'));
		$db->execute();

		// Remove the orphaned taxonomy nodes.
		FinderIndexerTaxonomy::removeOrphanNodes();

		// Optimize the taxonomy mapping table.
		$db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_taxonomy_map'));
		$db->execute();

		// Optimize the taxonomy table.
		$db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_taxonomy'));
		$db->execute();

		return true;
	}
}
PKW|!][i��:G:Gindexer/driver/sqlsrv.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

jimport('joomla.filesystem.file');

/**
 * Indexer class supporting SQL Server for the Finder indexer package.
 *
 * The indexer class provides the core functionality of the Finder
 * search engine. It is responsible for adding and updating the
 * content links table; extracting and scoring tokens; and maintaining
 * all referential information for the content.
 *
 * Note: All exceptions thrown from within this class should be caught
 * by the controller.
 *
 * @since  3.1
 */
class FinderIndexerDriverSqlsrv extends FinderIndexer
{
	/**
	 * Method to index a content item.
	 *
	 * @param   FinderIndexerResult  $item    The content item to index.
	 * @param   string               $format  The format of the content. [optional]
	 *
	 * @return  integer  The ID of the record in the links table.
	 *
	 * @since   3.1
	 * @throws  Exception on database error.
	 */
	public function index($item, $format = 'html')
	{
		// Mark beforeIndexing in the profiler.
		static::$profiler ? static::$profiler->mark('beforeIndexing') : null;
		$db = $this->db;
		$nd = $db->getNullDate();

		// Check if the item is in the database.
		$query = $db->getQuery(true)
			->select($db->quoteName('link_id') . ', ' . $db->quoteName('md5sum'))
			->from($db->quoteName('#__finder_links'))
			->where($db->quoteName('url') . ' = ' . $db->quote($item->url));

		// Load the item  from the database.
		$db->setQuery($query);
		$link = $db->loadObject();

		// Get the indexer state.
		$state = static::getState();

		// Get the signatures of the item.
		$curSig = static::getSignature($item);
		$oldSig = isset($link->md5sum) ? $link->md5sum : null;

		// Get the other item information.
		$linkId = empty($link->link_id) ? null : $link->link_id;
		$isNew = empty($link->link_id) ? true : false;

		// Check the signatures. If they match, the item is up to date.
		if (!$isNew && $curSig === $oldSig)
		{
			return $linkId;
		}

		/*
		 * If the link already exists, flush all the term maps for the item.
		 * Maps are stored in 16 tables so we need to iterate through and flush
		 * each table one at a time.
		 */
		if (!$isNew)
		{
			for ($i = 0; $i <= 15; $i++)
			{
				// Flush the maps for the link.
				$query->clear()
					->delete($db->quoteName('#__finder_links_terms' . dechex($i)))
					->where($db->quoteName('link_id') . ' = ' . (int) $linkId);
				$db->setQuery($query);
				$db->execute();
			}

			// Remove the taxonomy maps.
			FinderIndexerTaxonomy::removeMaps($linkId);
		}

		// Mark afterUnmapping in the profiler.
		static::$profiler ? static::$profiler->mark('afterUnmapping') : null;

		// Perform cleanup on the item data.
		$item->publish_start_date = (int) $item->publish_start_date != 0 ? $item->publish_start_date : $nd;
		$item->publish_end_date = (int) $item->publish_end_date != 0 ? $item->publish_end_date : $nd;
		$item->start_date = (int) $item->start_date != 0 ? $item->start_date : $nd;
		$item->end_date = (int) $item->end_date != 0 ? $item->end_date : $nd;

		// Prepare the item description.
		$item->description = FinderIndexerHelper::parse($item->summary);

		/*
		 * Now, we need to enter the item into the links table. If the item
		 * already exists in the database, we need to use an UPDATE query.
		 * Otherwise, we need to use an INSERT to get the link id back.
		 */

		if ($isNew)
		{
			$columnsArray = array(
				$db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'),
				$db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'),
				$db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'),
				$db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'),
				$db->quoteName('sale_price')
			);

			// Insert the link.
			$query->clear()
				->insert($db->quoteName('#__finder_links'))
				->columns($columnsArray)
				->values(
					$db->quote($item->url) . ', '
					. $db->quote($item->route) . ', '
					. $db->quote($item->title) . ', '
					. $db->quote($item->description) . ', '
					. $query->currentTimestamp() . ', '
					. '1, '
					. (int) $item->state . ', '
					. (int) $item->access . ', '
					. $db->quote($item->language) . ', '
					. (int) $item->type_id . ', '
					. $db->quote(serialize($item)) . ', '
					. $db->quote($item->publish_start_date) . ', '
					. $db->quote($item->publish_end_date) . ', '
					. $db->quote($item->start_date) . ', '
					. $db->quote($item->end_date) . ', '
					. (double) ($item->list_price ?: 0) . ', '
					. (double) ($item->sale_price ?: 0)
				);
			$db->setQuery($query);
			$db->execute();

			// Get the link id.
			$linkId = (int) $db->insertid();
		}
		else
		{
			// Update the link.
			$query->clear()
				->update($db->quoteName('#__finder_links'))
				->set($db->quoteName('route') . ' = ' . $db->quote($item->route))
				->set($db->quoteName('title') . ' = ' . $db->quote($item->title))
				->set($db->quoteName('description') . ' = ' . $db->quote($item->description))
				->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp())
				->set($db->quoteName('state') . ' = ' . (int) $item->state)
				->set($db->quoteName('access') . ' = ' . (int) $item->access)
				->set($db->quoteName('language') . ' = ' . $db->quote($item->language))
				->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id)
				->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item)))
				->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date))
				->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date))
				->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date))
				->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date))
				->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ?: 0))
				->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ?: 0))
				->where('link_id = ' . (int) $linkId);
			$db->setQuery($query);
			$db->execute();
		}

		// Set up the variables we will need during processing.
		$count = 0;

		// Mark afterLinking in the profiler.
		static::$profiler ? static::$profiler->mark('afterLinking') : null;

		// Truncate the tokens tables.
		$db->truncateTable('#__finder_tokens');

		// Truncate the tokens aggregate table.
		$db->truncateTable('#__finder_tokens_aggregate');

		/*
		 * Process the item's content. The items can customize their
		 * processing instructions to define extra properties to process
		 * or rearrange how properties are weighted.
		 */
		foreach ($item->getInstructions() as $group => $properties)
		{
			// Iterate through the properties of the group.
			foreach ($properties as $property)
			{
				// Check if the property exists in the item.
				if (empty($item->$property))
				{
					continue;
				}

				// Tokenize the property.
				if (is_array($item->$property))
				{
					// Tokenize an array of content and add it to the database.
					foreach ($item->$property as $ip)
					{
						/*
						 * If the group is path, we need to a few extra processing
						 * steps to strip the extension and convert slashes and dashes
						 * to spaces.
						 */
						if ($group === static::PATH_CONTEXT)
						{
							$ip = JFile::stripExt($ip);
							$ip = str_replace(array('/', '-'), ' ', $ip);
						}

						// Tokenize a string of content and add it to the database.
						$count += $this->tokenizeToDb($ip, $group, $item->language, $format);

						// Check if we're approaching the memory limit of the token table.
						if ($count > static::$state->options->get('memory_table_limit', 30000))
						{
							$this->toggleTables(false);
						}
					}
				}
				else
				{
					/*
					 * If the group is path, we need to a few extra processing
					 * steps to strip the extension and convert slashes and dashes
					 * to spaces.
					 */
					if ($group === static::PATH_CONTEXT)
					{
						$item->$property = JFile::stripExt($item->$property);
						$item->$property = str_replace('/', ' ', $item->$property);
						$item->$property = str_replace('-', ' ', $item->$property);
					}

					// Tokenize a string of content and add it to the database.
					$count += $this->tokenizeToDb($item->$property, $group, $item->language, $format);

					// Check if we're approaching the memory limit of the token table.
					if ($count > static::$state->options->get('memory_table_limit', 30000))
					{
						$this->toggleTables(false);
					}
				}
			}
		}

		/*
		 * Process the item's taxonomy. The items can customize their
		 * taxonomy mappings to define extra properties to map.
		 */
		foreach ($item->getTaxonomy() as $branch => $nodes)
		{
			// Iterate through the nodes and map them to the branch.
			foreach ($nodes as $node)
			{
				// Add the node to the tree.
				$nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access);

				// Add the link => node map.
				FinderIndexerTaxonomy::addMap($linkId, $nodeId);
			}
		}

		// Mark afterProcessing in the profiler.
		static::$profiler ? static::$profiler->mark('afterProcessing') : null;

		/*
		 * At this point, all of the item's content has been parsed, tokenized
		 * and inserted into the #__finder_tokens table. Now, we need to
		 * aggregate all the data into that table into a more usable form. The
		 * aggregated data will be inserted into #__finder_tokens_aggregate
		 * table.
		 */
		$query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') .
				' (' . $db->quoteName('term_id') .
				', ' . $db->quoteName('term') .
				', ' . $db->quoteName('stem') .
				', ' . $db->quoteName('common') .
				', ' . $db->quoteName('phrase') .
				', ' . $db->quoteName('term_weight') .
				', ' . $db->quoteName('context') .
				', ' . $db->quoteName('context_weight') .
				', ' . $db->quoteName('language') . ')' .
				' SELECT' .
				' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' .
				' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, t1.language' .
				' FROM (' .
				'   SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
				'   FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' .
				'   WHERE t1.context = %d' .
				' ) AS t1' .
				' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' .
				' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' .
				' WHERE t2.context = %d' .
				' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
				' ORDER BY t1.term DESC';

		// Iterate through the contexts and aggregate the tokens per context.
		foreach ($state->weights as $context => $multiplier)
		{
			// Run the query to aggregate the tokens for this context..
			$db->setQuery(sprintf($query, $multiplier, $context, $context));
			$db->execute();
		}

		// Mark afterAggregating in the profiler.
		static::$profiler ? static::$profiler->mark('afterAggregating') : null;

		/*
		 * When we pulled down all of the aggregate data, we did a LEFT JOIN
		 * over the terms table to try to find all the term ids that
		 * already exist for our tokens. If any of the rows in the aggregate
		 * table have a term of 0, then no term record exists for that
		 * term so we need to add it to the terms table.
		 */
		$db->setQuery(
			'INSERT INTO ' . $db->quoteName('#__finder_terms') .
			' (' . $db->quoteName('term') .
			', ' . $db->quoteName('stem') .
			', ' . $db->quoteName('common') .
			', ' . $db->quoteName('phrase') .
			', ' . $db->quoteName('weight') .
			', ' . $db->quoteName('soundex') . ')' .
			' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term)' .
			' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' .
			' WHERE ta.term_id IS NULL' .
			' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight'
		);
		$db->execute();

		/*
		 * Now, we just inserted a bunch of new records into the terms table
		 * so we need to go back and update the aggregate table with all the
		 * new term ids.
		 */
		$query = $db->getQuery(true)
			->update('ta')
			->set('ta.term_id = t.term_id from #__finder_tokens_aggregate AS ta INNER JOIN #__finder_terms AS t ON t.term = ta.term')
			->where('ta.term_id IS NULL');
		$db->setQuery($query);
		$db->execute();

		// Mark afterTerms in the profiler.
		static::$profiler ? static::$profiler->mark('afterTerms') : null;

		/*
		 * After we've made sure that all of the terms are in the terms table
		 * and the aggregate table has the correct term ids, we need to update
		 * the links counter for each term by one.
		 */
		$query->clear()
			->update('t')
			->set('t.links = t.links + 1 FROM #__finder_terms AS t INNER JOIN #__finder_tokens_aggregate AS ta ON ta.term_id = t.term_id');
		$db->setQuery($query);
		$db->execute();

		// Mark afterTerms in the profiler.
		static::$profiler ? static::$profiler->mark('afterTerms') : null;

		/*
		 * Before we can insert all of the mapping rows, we have to figure out
		 * which mapping table the rows need to be inserted into. The mapping
		 * table for each term is based on the first character of the md5 of
		 * the first character of the term. In php, it would be expressed as
		 * substr(md5(substr($token, 0, 1)), 0, 1)
		 */
		$query->clear()
			->update($db->quoteName('#__finder_tokens_aggregate'))
			->set($db->quoteName('map_suffix') . " = SUBSTRING(HASHBYTES('MD5', SUBSTRING(" . $db->quoteName('term') . ', 1, 1)), 1, 1)');
		$db->setQuery($query);
		$db->execute();

		/*
		 * At this point, the aggregate table contains a record for each
		 * term in each context. So, we're going to pull down all of that
		 * data while grouping the records by term and add all of the
		 * sub-totals together to arrive at the final total for each token for
		 * this link. Then, we insert all of that data into the appropriate
		 * mapping table.
		 */
		for ($i = 0; $i <= 15; $i++)
		{
			// Get the mapping table suffix.
			$suffix = dechex($i);

			/*
			 * We have to run this query 16 times, one for each link => term
			 * mapping table.
			 */
			$db->setQuery(
				'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) .
				' (' . $db->quoteName('link_id') .
				', ' . $db->quoteName('term_id') .
				', ' . $db->quoteName('weight') . ')' .
				' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' .
				' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' .
				' FROM ' . $db->quoteName('#__finder_tokens_aggregate') .
				' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) .
				' GROUP BY term, term_id' .
				' ORDER BY ' . $db->quoteName('term') . ' DESC'
			);
			$db->execute();
		}

		// Mark afterMapping in the profiler.
		static::$profiler ? static::$profiler->mark('afterMapping') : null;

		// Update the signature.
		$query->clear()
			->update($db->quoteName('#__finder_links'))
			->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig))
			->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId));
		$db->setQuery($query);
		$db->execute();

		// Mark afterSigning in the profiler.
		static::$profiler ? static::$profiler->mark('afterSigning') : null;

		// Truncate the tokens tables.
		$db->truncateTable('#__finder_tokens');

		// Truncate the tokens aggregate table.
		$db->truncateTable('#__finder_tokens_aggregate');

		// Toggle the token tables back to memory tables.
		$this->toggleTables(true);

		// Mark afterTruncating in the profiler.
		static::$profiler ? static::$profiler->mark('afterTruncating') : null;

		return $linkId;
	}

	/**
	 * Method to remove a link from the index.
	 *
	 * @param   integer  $linkId  The id of the link.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.1
	 * @throws  Exception on database error.
	 */
	public function remove($linkId)
	{
		$db = $this->db;
		$query = $db->getQuery(true);

		// Update the link counts and remove the mapping records.
		for ($i = 0; $i <= 15; $i++)
		{
			// Update the link counts for the terms.
			$query->update('t')
				->set('t.links = t.links - 1 from #__finder_terms AS t INNER JOIN #__finder_links_terms' . dechex($i) . ' AS m ON m.term_id = t.term_id')
				->where('m.link_id = ' . $db->quote((int) $linkId));
			$db->setQuery($query);
			$db->execute();

			// Remove all records from the mapping tables.
			$query->clear()
				->delete($db->quoteName('#__finder_links_terms' . dechex($i)))
				->where($db->quoteName('link_id') . ' = ' . (int) $linkId);
			$db->setQuery($query);
			$db->execute();
		}

		// Delete all orphaned terms.
		$query->clear()
			->delete($db->quoteName('#__finder_terms'))
			->where($db->quoteName('links') . ' <= 0');
		$db->setQuery($query);
		$db->execute();

		// Delete the link from the index.
		$query->clear()
			->delete($db->quoteName('#__finder_links'))
			->where($db->quoteName('link_id') . ' = ' . $db->quote((int) $linkId));
		$db->setQuery($query);
		$db->execute();

		// Remove the taxonomy maps.
		FinderIndexerTaxonomy::removeMaps($linkId);

		// Remove the orphaned taxonomy nodes.
		FinderIndexerTaxonomy::removeOrphanNodes();

		return true;
	}

	/**
	 * Method to optimize the index. We use this method to remove unused terms
	 * and any other optimizations that might be necessary.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   3.1
	 * @throws  Exception on database error.
	 */
	public function optimize()
	{
		// Get the database object.
		$db = $this->db;
		$query = $db->getQuery(true);

		// Delete all orphaned terms.
		$query->delete($db->quoteName('#__finder_terms'))
			->where($db->quoteName('links') . ' <= 0');
		$db->setQuery($query);
		$db->execute();

		// Remove the orphaned taxonomy nodes.
		FinderIndexerTaxonomy::removeOrphanNodes();

		return true;
	}
}
PKW|!]��''indexer/stemmer/porter_en.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('FinderIndexerStemmer', dirname(__DIR__) . '/stemmer.php');

/**
 * Porter English stemmer class for the Finder indexer package.
 *
 * This class was adapted from one written by Richard Heyes.
 * See copyright and link information above.
 *
 * @since  2.5
 */
class FinderIndexerStemmerPorter_En extends FinderIndexerStemmer
{
	/**
	 * Regex for matching a consonant.
	 *
	 * @var    string
	 * @since  2.5
	 */
	private static $regex_consonant = '(?:[bcdfghjklmnpqrstvwxz]|(?<=[aeiou])y|^y)';

	/**
	 * Regex for matching a vowel
	 *
	 * @var    string
	 * @since  2.5
	 */
	private static $regex_vowel = '(?:[aeiou]|(?<![aeiou])y)';

	/**
	 * Method to stem a token and return the root.
	 *
	 * @param   string  $token  The token to stem.
	 * @param   string  $lang   The language of the token.
	 *
	 * @return  string  The root token.
	 *
	 * @since   2.5
	 */
	public function stem($token, $lang)
	{
		// Check if the token is long enough to merit stemming.
		if (strlen($token) <= 2)
		{
			return $token;
		}

		// Check if the language is English or All.
		if ($lang !== 'en' && $lang !== '*')
		{
			return $token;
		}

		// Stem the token if it is not in the cache.
		if (!isset($this->cache[$lang][$token]))
		{
			// Stem the token.
			$result = $token;
			$result = self::step1ab($result);
			$result = self::step1c($result);
			$result = self::step2($result);
			$result = self::step3($result);
			$result = self::step4($result);
			$result = self::step5($result);

			// Add the token to the cache.
			$this->cache[$lang][$token] = $result;
		}

		return $this->cache[$lang][$token];
	}

	/**
	 * Step 1
	 *
	 * @param   string  $word  The token to stem.
	 *
	 * @return  string
	 *
	 * @since   2.5
	 */
	private static function step1ab($word)
	{
		// Part a
		if (substr($word, -1) === 's')
		{
			self::replace($word, 'sses', 'ss')
			|| self::replace($word, 'ies', 'i')
			|| self::replace($word, 'ss', 'ss')
			|| self::replace($word, 's', '');
		}

		// Part b
		if (substr($word, -2, 1) !== 'e' || !self::replace($word, 'eed', 'ee', 0))
		{
			// First rule
			$v = self::$regex_vowel;

			// Words ending with ing and ed
			// Note use of && and OR, for precedence reasons
			if (preg_match("#$v+#", substr($word, 0, -3)) && self::replace($word, 'ing', '')
				|| preg_match("#$v+#", substr($word, 0, -2)) && self::replace($word, 'ed', ''))
			{
				// If one of above two test successful
				if (!self::replace($word, 'at', 'ate') && !self::replace($word, 'bl', 'ble') && !self::replace($word, 'iz', 'ize'))
				{
					// Double consonant ending
					$wordSubStr = substr($word, -2);

					if ($wordSubStr !== 'll' && $wordSubStr !== 'ss' && $wordSubStr !== 'zz' && self::doubleConsonant($word))
					{
						$word = substr($word, 0, -1);
					}
					elseif (self::m($word) === 1 && self::cvc($word))
					{
						$word .= 'e';
					}
				}
			}
		}

		return $word;
	}

	/**
	 * Step 1c
	 *
	 * @param   string  $word  The token to stem.
	 *
	 * @return  string
	 *
	 * @since   2.5
	 */
	private static function step1c($word)
	{
		$v = self::$regex_vowel;

		if (substr($word, -1) === 'y' && preg_match("#$v+#", substr($word, 0, -1)))
		{
			self::replace($word, 'y', 'i');
		}

		return $word;
	}

	/**
	 * Step 2
	 *
	 * @param   string  $word  The token to stem.
	 *
	 * @return  string
	 *
	 * @since   2.5
	 */
	private static function step2($word)
	{
		switch (substr($word, -2, 1))
		{
			case 'a':
				self::replace($word, 'ational', 'ate', 0)
				|| self::replace($word, 'tional', 'tion', 0);
				break;
			case 'c':
				self::replace($word, 'enci', 'ence', 0)
				|| self::replace($word, 'anci', 'ance', 0);
				break;
			case 'e':
				self::replace($word, 'izer', 'ize', 0);
				break;
			case 'g':
				self::replace($word, 'logi', 'log', 0);
				break;
			case 'l':
				self::replace($word, 'entli', 'ent', 0)
				|| self::replace($word, 'ousli', 'ous', 0)
				|| self::replace($word, 'alli', 'al', 0)
				|| self::replace($word, 'bli', 'ble', 0)
				|| self::replace($word, 'eli', 'e', 0);
				break;
			case 'o':
				self::replace($word, 'ization', 'ize', 0)
				|| self::replace($word, 'ation', 'ate', 0)
				|| self::replace($word, 'ator', 'ate', 0);
				break;
			case 's':
				self::replace($word, 'iveness', 'ive', 0)
				|| self::replace($word, 'fulness', 'ful', 0)
				|| self::replace($word, 'ousness', 'ous', 0)
				|| self::replace($word, 'alism', 'al', 0);
				break;
			case 't':
				self::replace($word, 'biliti', 'ble', 0)
				|| self::replace($word, 'aliti', 'al', 0)
				|| self::replace($word, 'iviti', 'ive', 0);
				break;
		}

		return $word;
	}

	/**
	 * Step 3
	 *
	 * @param   string  $word  The token to stem.
	 *
	 * @return  string
	 *
	 * @since   2.5
	 */
	private static function step3($word)
	{
		switch (substr($word, -2, 1))
		{
			case 'a':
				self::replace($word, 'ical', 'ic', 0);
				break;
			case 's':
				self::replace($word, 'ness', '', 0);
				break;
			case 't':
				self::replace($word, 'icate', 'ic', 0)
				|| self::replace($word, 'iciti', 'ic', 0);
				break;
			case 'u':
				self::replace($word, 'ful', '', 0);
				break;
			case 'v':
				self::replace($word, 'ative', '', 0);
				break;
			case 'z':
				self::replace($word, 'alize', 'al', 0);
				break;
		}

		return $word;
	}

	/**
	 * Step 4
	 *
	 * @param   string  $word  The token to stem.
	 *
	 * @return  string
	 *
	 * @since   2.5
	 */
	private static function step4($word)
	{
		switch (substr($word, -2, 1))
		{
			case 'a':
				self::replace($word, 'al', '', 1);
				break;
			case 'c':
				self::replace($word, 'ance', '', 1)
				|| self::replace($word, 'ence', '', 1);
				break;
			case 'e':
				self::replace($word, 'er', '', 1);
				break;
			case 'i':
				self::replace($word, 'ic', '', 1);
				break;
			case 'l':
				self::replace($word, 'able', '', 1)
				|| self::replace($word, 'ible', '', 1);
				break;
			case 'n':
				self::replace($word, 'ant', '', 1)
				|| self::replace($word, 'ement', '', 1)
				|| self::replace($word, 'ment', '', 1)
				|| self::replace($word, 'ent', '', 1);
				break;
			case 'o':
				$wordSubStr = substr($word, -4);

				if ($wordSubStr === 'tion' || $wordSubStr === 'sion')
				{
					self::replace($word, 'ion', '', 1);
				}
				else
				{
					self::replace($word, 'ou', '', 1);
				}
				break;
			case 's':
				self::replace($word, 'ism', '', 1);
				break;
			case 't':
				self::replace($word, 'ate', '', 1)
				|| self::replace($word, 'iti', '', 1);
				break;
			case 'u':
				self::replace($word, 'ous', '', 1);
				break;
			case 'v':
				self::replace($word, 'ive', '', 1);
				break;
			case 'z':
				self::replace($word, 'ize', '', 1);
				break;
		}

		return $word;
	}

	/**
	 * Step 5
	 *
	 * @param   string  $word  The token to stem.
	 *
	 * @return  string
	 *
	 * @since   2.5
	 */
	private static function step5($word)
	{
		// Part a
		if (substr($word, -1) === 'e')
		{
			if (self::m(substr($word, 0, -1)) > 1)
			{
				self::replace($word, 'e', '');
			}
			elseif (self::m(substr($word, 0, -1)) === 1)
			{
				if (!self::cvc(substr($word, 0, -1)))
				{
					self::replace($word, 'e', '');
				}
			}
		}

		// Part b
		if (self::m($word) > 1 && self::doubleConsonant($word) && substr($word, -1) === 'l')
		{
			$word = substr($word, 0, -1);
		}

		return $word;
	}

	/**
	 * Replaces the first string with the second, at the end of the string. If third
	 * arg is given, then the preceding string must match that m count at least.
	 *
	 * @param   string   $str    String to check
	 * @param   string   $check  Ending to check for
	 * @param   string   $repl   Replacement string
	 * @param   integer  $m      Optional minimum number of m() to meet
	 *
	 * @return  boolean  Whether the $check string was at the end
	 *                   of the $str string. True does not necessarily mean
	 *                   that it was replaced.
	 *
	 * @since   2.5
	 */
	private static function replace(&$str, $check, $repl, $m = null)
	{
		$len = 0 - strlen($check);

		if (substr($str, $len) === $check)
		{
			$substr = substr($str, 0, $len);

			if ($m === null || self::m($substr) > $m)
			{
				$str = $substr . $repl;
			}

			return true;
		}

		return false;
	}

	/**
	 * m() measures the number of consonant sequences in $str. if c is
	 * a consonant sequence and v a vowel sequence, and <..> indicates arbitrary
	 * presence,
	 *
	 * <c><v>       gives 0
	 * <c>vc<v>     gives 1
	 * <c>vcvc<v>   gives 2
	 * <c>vcvcvc<v> gives 3
	 *
	 * @param   string  $str  The string to return the m count for
	 *
	 * @return  integer  The m count
	 *
	 * @since   2.5
	 */
	private static function m($str)
	{
		$c = self::$regex_consonant;
		$v = self::$regex_vowel;

		$str = preg_replace("#^$c+#", '', $str);
		$str = preg_replace("#$v+$#", '', $str);

		preg_match_all("#($v+$c+)#", $str, $matches);

		return count($matches[1]);
	}

	/**
	 * Returns true/false as to whether the given string contains two
	 * of the same consonant next to each other at the end of the string.
	 *
	 * @param   string  $str  String to check
	 *
	 * @return  boolean  Result
	 *
	 * @since   2.5
	 */
	private static function doubleConsonant($str)
	{
		$c = self::$regex_consonant;

		return preg_match("#$c{2}$#", $str, $matches) && $matches[0][0] === $matches[0][1];
	}

	/**
	 * Checks for ending CVC sequence where second C is not W, X or Y
	 *
	 * @param   string  $str  String to check
	 *
	 * @return  boolean  Result
	 *
	 * @since   2.5
	 */
	private static function cvc($str)
	{
		$c = self::$regex_consonant;
		$v = self::$regex_vowel;

		return preg_match("#($c$v$c)$#", $str, $matches) && strlen($matches[1]) === 3 && $matches[1][2] !== 'w' && $matches[1][2] !== 'x'
			&& $matches[1][2] !== 'y';
	}
}
PKW|!]��9�[([(indexer/stemmer/fr.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('FinderIndexerStemmer', dirname(__DIR__) . '/stemmer.php');

/**
 * French stemmer class for Smart Search indexer.
 *
 * First contributed by Eric Sanou (bobotche@hotmail.fr)
 * This class is inspired in  Alexis Ulrich's French stemmer code (http://alx2002.free.fr)
 *
 * @since  3.0
 */
class FinderIndexerStemmerFr extends FinderIndexerStemmer
{
	/**
	 * Stemming rules.
	 *
	 * @var    array
	 * @since  3.0
	 */
	private static $stemRules;

	/**
	 * Method to stem a token and return the root.
	 *
	 * @param   string  $token  The token to stem.
	 * @param   string  $lang   The language of the token.
	 *
	 * @return  string  The root token.
	 *
	 * @since   3.0
	 */
	public function stem($token, $lang)
	{
		// Check if the token is long enough to merit stemming.
		if (strlen($token) <= 2)
		{
			return $token;
		}

		// Check if the language is French or All.
		if ($lang !== 'fr' && $lang !== '*')
		{
			return $token;
		}

		// Stem the token if it is not in the cache.
		if (!isset($this->cache[$lang][$token]))
		{
			// Stem the token.
			$result = self::getStem($token);

			// Add the token to the cache.
			$this->cache[$lang][$token] = $result;
		}

		return $this->cache[$lang][$token];
	}

	/**
	 * French stemmer rules variables.
	 *
	 * @return  array  The rules
	 *
	 * @since   3.0
	 */
	protected static function getStemRules()
	{
		if (self::$stemRules)
		{
			return self::$stemRules;
		}

		$vars = array();

		// French accented letters in ISO-8859-1 encoding
		$vars['accents'] = chr(224) . chr(226) . chr(232) . chr(233) . chr(234) . chr(235) . chr(238) . chr(239)
			. chr(244) . chr(251) . chr(249) . chr(231);

		// The rule patterns include all accented words for french language
		$vars['rule_pattern'] = '/^([a-z' . $vars['accents'] . ']*)(\*){0,1}(\d)([a-z' . $vars['accents'] . ']*)([.|>])/';

		// French vowels (including y) in ISO-8859-1 encoding
		$vars['vowels'] = chr(97) . chr(224) . chr(226) . chr(101) . chr(232) . chr(233) . chr(234) . chr(235)
			. chr(105) . chr(238) . chr(239) . chr(111) . chr(244) . chr(117) . chr(251) . chr(249) . chr(121);

		// The French rules in ISO-8859-1 encoding
		$vars['rules'] = array(
			'esre1>', 'esio1>', 'siol1.', 'siof0.', 'sioe0.', 'sio3>', 'st1>', 'sf1>', 'sle1>', 'slo1>', 's' . chr(233) . '1>', chr(233) . 'tuae5.',
			chr(233) . 'tuae2.', 'tnia0.', 'tniv1.', 'tni3>', 'suor1.', 'suo0.', 'sdrail5.', 'sdrai4.', 'er' . chr(232) . 'i1>', 'sesue3x>',
			'esuey5i.', 'esue2x>', 'se1>', 'er' . chr(232) . 'g3.', 'eca1>', 'esiah0.', 'esi1>', 'siss2.', 'sir2>', 'sit2>', 'egan' . chr(233) . '1.',
			'egalli6>', 'egass1.', 'egas0.', 'egat3.', 'ega3>', 'ette4>', 'ett2>', 'etio1.', 'tio' . chr(231) . '4c.', 'tio0.', 'et1>', 'eb1>',
			'snia1>', 'eniatnau8>', 'eniatn4.', 'enia1>', 'niatnio3.', 'niatg3.', 'e' . chr(233) . '1>', chr(233) . 'hcat1.', chr(233) . 'hca4.',
			chr(233) . 'tila5>', chr(233) . 'tici5.', chr(233) . 'tir1.', chr(233) . 'ti3>', chr(233) . 'gan1.', chr(233) . 'ga3>',
			chr(233) . 'tehc1.', chr(233) . 'te3>', chr(233) . 'it0.', chr(233) . '1>', 'eire4.', 'eirue5.', 'eio1.', 'eia1.', 'ei1>', 'eng1.',
			'xuaessi7.', 'xuae1>', 'uaes0.', 'uae3.', 'xuave2l.', 'xuav2li>', 'xua3la>', 'ela1>', 'lart2.', 'lani2>', 'la' . chr(233) . '2>',
			'siay4i.', 'siassia7.', 'siarv1*.', 'sia1>', 'tneiayo6i.', 'tneiay6i.', 'tneiassia9.', 'tneiareio7.', 'tneia5>', 'tneia4>', 'tiario4.',
			'tiarim3.', 'tiaria3.', 'tiaris3.', 'tiari5.', 'tiarve6>', 'tiare5>', 'iare4>', 'are3>', 'tiay4i.', 'tia3>', 'tnay4i.',
			'em' . chr(232) . 'iu5>', 'em' . chr(232) . 'i4>', 'tnaun3.', 'tnauqo3.', 'tnau4>', 'tnaf0.', 'tnat' . chr(233) . '2>', 'tna3>', 'tno3>',
			'zeiy4i.', 'zey3i.', 'zeire5>', 'zeird4.', 'zeirio4.', 'ze2>', 'ssiab0.', 'ssia4.', 'ssi3.', 'tnemma6>', 'tnemesuey9i.', 'tnemesue8>',
			'tnemevi7.', 'tnemessia5.', 'tnemessi8.', 'tneme5>', 'tnemia4.', 'tnem' . chr(233) . '5>', 'el2l>', 'lle3le>', 'let' . chr(244) . '0.',
			'lepp0.', 'le2>', 'srei1>', 'reit3.', 'reila2.', 'rei3>', 'ert' . chr(226) . 'e5.', 'ert' . chr(226) . chr(233) . '1.',
			'ert' . chr(226) . '4.', 'drai4.', 'erdro0.', 'erute5.', 'ruta0.', 'eruta1.', 'erutiov1.', 'erub3.', 'eruh3.', 'erul3.', 'er2r>', 'nn1>',
			'r' . chr(232) . 'i3.', 'srev0.', 'sr1>', 'rid2>', 're2>', 'xuei4.', 'esuei5.', 'lbati3.', 'lba3>', 'rueis0.', 'ruehcn4.', 'ecirta6.',
			'ruetai6.', 'rueta5.', 'rueir0.', 'rue3>', 'esseti6.', 'essere6>', 'esserd1.', 'esse4>', 'essiab1.', 'essia5.', 'essio1.', 'essi4.',
			'essal4.', 'essa1>', 'ssab1.', 'essurp1.', 'essu4.', 'essi1.', 'ssor1.', 'essor2.', 'esso1>', 'ess2>', 'tio3.', 'r' . chr(232) . 's2re.',
			'r' . chr(232) . '0e.', 'esn1.', 'eu1>', 'sua0.', 'su1>', 'utt1>', 'tu' . chr(231) . '3c.', 'u' . chr(231) . '2c.', 'ur1.', 'ehcn2>',
			'ehcu1>', 'snorr3.', 'snoru3.', 'snorua3.', 'snorv3.', 'snorio4.', 'snori5.', 'snore5>', 'snortt4>', 'snort' . chr(238) . 'a7.', 'snort3.',
			'snor4.', 'snossi6.', 'snoire6.', 'snoird5.', 'snoitai7.', 'snoita6.', 'snoits1>', 'noits0.', 'snoi4>', 'noitaci7>', 'noitai6.', 'noita5.',
			'noitu4.', 'noi3>', 'snoya0.', 'snoy4i.', 'sno' . chr(231) . 'a1.', 'sno' . chr(231) . 'r1.', 'snoe4.', 'snosiar1>', 'snola1.', 'sno3>',
			'sno1>', 'noll2.', 'tnennei4.', 'ennei2>', 'snei1>', 'sne' . chr(233) . '1>', 'enne' . chr(233) . '5e.', 'ne' . chr(233) . '3e.', 'neic0.',
			'neiv0.', 'nei3.', 'sc1.', 'sd1.', 'sg1.', 'sni1.', 'tiu0.', 'ti2.', 'sp1>', 'sna1>', 'sue1.', 'enn2>', 'nong2.', 'noss2.', 'rioe4.',
			'riot0.', 'riorc1.', 'riovec5.', 'rio3.', 'ric2.', 'ril2.', 'tnerim3.', 'tneris3>', 'tneri5.', 't' . chr(238) . 'a3.', 'riss2.',
			't' . chr(238) . '2.', 't' . chr(226) . '2>', 'ario2.', 'arim1.', 'ara1.', 'aris1.', 'ari3.', 'art1>', 'ardn2.', 'arr1.', 'arua1.',
			'aro1.', 'arv1.', 'aru1.', 'ar2.', 'rd1.', 'ud1.', 'ul1.', 'ini1.', 'rin2.', 'tnessiab3.', 'tnessia7.', 'tnessi6.', 'tnessni4.', 'sini2.',
			'sl1.', 'iard3.', 'iario3.', 'ia2>', 'io0.', 'iule2.', 'i1>', 'sid2.', 'sic2.', 'esoi4.', 'ed1.', 'ai2>', 'a1>', 'adr1.',
			'tner' . chr(232) . '5>', 'evir1.', 'evio4>', 'evi3.', 'fita4.', 'fi2>', 'enie1.', 'sare4>', 'sari4>', 'sard3.', 'sart2>', 'sa2.',
			'tnessa6>', 'tnessu6>', 'tnegna3.', 'tnegi3.', 'tneg0.', 'tneru5>', 'tnemg0.', 'tnerni4.', 'tneiv1.', 'tne3>', 'une1.', 'en1>', 'nitn2.',
			'ecnay5i.', 'ecnal1.', 'ecna4.', 'ec1>', 'nn1.', 'rit2>', 'rut2>', 'rud2.', 'ugn1>', 'eg1>', 'tuo0.', 'tul2>', 't' . chr(251) . '2>',
			'ev1>', 'v' . chr(232) . '2ve>', 'rtt1>', 'emissi6.', 'em1.', 'ehc1.', 'c' . chr(233) . 'i2c' . chr(232) . '.', 'libi2l.', 'llie1.',
			'liei4i.', 'xuev1.', 'xuey4i.', 'xueni5>', 'xuell4.', 'xuere5.', 'xue3>', 'rb' . chr(233) . '3rb' . chr(232) . '.', 'tur2.',
			'rir' . chr(233) . '4re.', 'rir2.', 'c' . chr(226) . '2ca.', 'snu1.', 'rt' . chr(238) . 'a4.', 'long2.', 'vec2.', chr(231) . '1c>',
			'ssilp3.', 'silp2.', 't' . chr(232) . 'hc2te.', 'n' . chr(232) . 'm2ne.', 'llepp1.', 'tan2.', 'rv' . chr(232) . '3rve.',
			'rv' . chr(233) . '3rve.', 'r' . chr(232) . '2re.', 'r' . chr(233) . '2re.', 't' . chr(232) . '2te.', 't' . chr(233) . '2te.', 'epp1.',
			'eya2i.', 'ya1i.', 'yo1i.', 'esu1.', 'ugi1.', 'tt1.', 'end0.'
		);

		self::$stemRules = $vars;

		return self::$stemRules;
	}

	/**
	 * Returns the number of the first rule from the rule number
	 * that can be applied to the given reversed input.
	 * returns -1 if no rule can be applied, ie the stem has been found
	 *
	 * @param   string   $reversedInput  The input to check in reversed order
	 * @param   integer  $ruleNumber     The rule number to check
	 *
	 * @return  integer  Number of the first rule
	 *
	 * @since   3.0
	 */
	private static function getFirstRule($reversedInput, $ruleNumber)
	{
		$vars = static::getStemRules();

		$nb_rules = count($vars['rules']);

		for ($i = $ruleNumber; $i < $nb_rules; $i++)
		{
			// Gets the letters from the current rule
			$rule = $vars['rules'][$i];
			$rule = preg_replace($vars['rule_pattern'], "\\1", $rule);

			if (strncasecmp(utf8_decode($rule), $reversedInput, strlen(utf8_decode($rule))) == 0)
			{
				return $i;
			}
		}

		return -1;
	}

	/**
	 * Check the acceptability of a stem for French language
	 *
	 * @param   string  $reversedStem  The stem to check in reverse form
	 *
	 * @return  boolean  True if stem is acceptable
	 *
	 * @since   3.0
	 */
	private static function check($reversedStem)
	{
		$vars = static::getStemRules();

		if (preg_match('/[' . $vars['vowels'] . ']$/', utf8_encode($reversedStem)))
		{
			// If the form starts with a vowel then at least two letters must remain after stemming (e.g.: "etaient" --> "et")
			return (strlen($reversedStem) > 2);
		}
		else
		{
			// If the reversed stem starts with a consonant then at least two letters must remain after stemming
			if (strlen($reversedStem) <= 2)
			{
				return false;
			}

			// And at least one of these must be a vowel or "y"
			return preg_match('/[' . $vars['vowels'] . ']/', utf8_encode($reversedStem));
		}
	}

	/**
	 * Paice/Husk stemmer which returns a stem for the given $input
	 *
	 * @param   string  $input  The word for which we want the stem in UTF-8
	 *
	 * @return  string  The stem
	 *
	 * @since   3.0
	 */
	private static function getStem($input)
	{
		$vars = static::getStemRules();

		$reversed_input = strrev(utf8_decode($input));
		$rule_number = 0;

		// This loop goes through the rules' array until it finds an ending one (ending by '.') or the last one ('end0.')
		while (true)
		{
			$rule_number = self::getFirstRule($reversed_input, $rule_number);

			if ($rule_number === -1)
			{
				// No other rule can be applied => the stem has been found
				break;
			}

			$rule = $vars['rules'][$rule_number];
			preg_match($vars['rule_pattern'], $rule, $matches);

			$reversed_stem = utf8_decode($matches[4]) . substr($reversed_input, $matches[3]);

			if (self::check($reversed_stem))
			{
				$reversed_input = $reversed_stem;

				if ($matches[5] === '.')
				{
					break;
				}
			}
			else
			{
				// Go to another rule
				$rule_number++;
			}
		}

		return utf8_encode(strrev($reversed_input));
	}
}
PKW|!]�hU8�
�
indexer/stemmer/snowball.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('FinderIndexerStemmer', dirname(__DIR__) . '/stemmer.php');

/**
 * Snowball stemmer class for the Finder indexer package.
 *
 * @since  2.5
 */
class FinderIndexerStemmerSnowball extends FinderIndexerStemmer
{
	/**
	 * Method to stem a token and return the root.
	 *
	 * @param   string  $token  The token to stem.
	 * @param   string  $lang   The language of the token.
	 *
	 * @return  string  The root token.
	 *
	 * @since   2.5
	 */
	public function stem($token, $lang)
	{
		// Language to use if All is specified.
		static $defaultLang = '';

		// If language is All then try to get site default language.
		if ($lang === '*' && $defaultLang === '')
		{
			$languages = JLanguageHelper::getLanguages();
			$defaultLang = isset($languages[0]->sef) ? $languages[0]->sef : '*';
			$lang = $defaultLang;
		}

		// Stem the token if it is not in the cache.
		if (!isset($this->cache[$lang][$token]))
		{
			// Get the stem function from the language string.
			switch ($lang)
			{
				// Danish stemmer.
				case 'da':
					$function = 'stem_danish';
					break;

				// German stemmer.
				case 'de':
					$function = 'stem_german';
					break;

				// English stemmer.
				default:
				case 'en':
					$function = 'stem_english';
					break;

				// Spanish stemmer.
				case 'es':
					$function = 'stem_spanish';
					break;

				// Finnish stemmer.
				case 'fi':
					$function = 'stem_finnish';
					break;

				// French stemmer.
				case 'fr':
					$function = 'stem_french';
					break;

				// Hungarian stemmer.
				case 'hu':
					$function = 'stem_hungarian';
					break;

				// Italian stemmer.
				case 'it':
					$function = 'stem_italian';
					break;

				// Norwegian stemmer.
				case 'nb':
					$function = 'stem_norwegian';
					break;

				// Dutch stemmer.
				case 'nl':
					$function = 'stem_dutch';
					break;

				// Portuguese stemmer.
				case 'pt':
					$function = 'stem_portuguese';
					break;

				// Romanian stemmer.
				case 'ro':
					$function = 'stem_romanian';
					break;

				// Russian stemmer.
				case 'ru':
					$function = 'stem_russian_unicode';
					break;

				// Swedish stemmer.
				case 'sv':
					$function = 'stem_swedish';
					break;

				// Turkish stemmer.
				case 'tr':
					$function = 'stem_turkish_unicode';
					break;
			}

			// Stem the word if the stemmer method exists.
			$this->cache[$lang][$token] = function_exists($function) ? $function($token) : $token;
		}

		return $this->cache[$lang][$token];
	}
}
PKW|!]�� ""indexer/result.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('FinderIndexer', __DIR__ . '/indexer.php');

/**
 * Result class for the Finder indexer package.
 *
 * This class uses magic __get() and __set() methods to prevent properties
 * being added that might confuse the system. All properties not explicitly
 * declared will be pushed into the elements array and can be accessed
 * explicitly using the getElement() method.
 *
 * @since  2.5
 */
class FinderIndexerResult
{
	/**
	 * An array of extra result properties.
	 *
	 * @var    array
	 * @since  2.5
	 */
	protected $elements = array();

	/**
	 * This array tells the indexer which properties should be indexed and what
	 * weights to use for those properties.
	 *
	 * @var    array
	 * @since  2.5
	 */
	protected $instructions = array(
		FinderIndexer::TITLE_CONTEXT => array('title', 'subtitle', 'id'),
		FinderIndexer::TEXT_CONTEXT  => array('summary', 'body'),
		FinderIndexer::META_CONTEXT  => array('meta', 'list_price', 'sale_price'),
		FinderIndexer::PATH_CONTEXT  => array('path', 'alias'),
		FinderIndexer::MISC_CONTEXT  => array('comments'),
	);

	/**
	 * The indexer will use this data to create taxonomy mapping entries for
	 * the item so that it can be filtered by type, label, category,
	 * or whatever.
	 *
	 * @var    array
	 * @since  2.5
	 */
	protected $taxonomy = array();

	/**
	 * The content URL.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $url;

	/**
	 * The content route.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $route;

	/**
	 * The content title.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $title;

	/**
	 * The content description.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $description;

	/**
	 * The published state of the result.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	public $published;

	/**
	 * The content published state.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	public $state;

	/**
	 * The content access level.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	public $access;

	/**
	 * The content language.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $language = '*';

	/**
	 * The publishing start date.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $publish_start_date;

	/**
	 * The publishing end date.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $publish_end_date;

	/**
	 * The generic start date.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $start_date;

	/**
	 * The generic end date.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $end_date;

	/**
	 * The item list price.
	 *
	 * @var    mixed
	 * @since  2.5
	 */
	public $list_price;

	/**
	 * The item sale price.
	 *
	 * @var    mixed
	 * @since  2.5
	 */
	public $sale_price;

	/**
	 * The content type id. This is set by the adapter.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	public $type_id;

	/**
	 * The default language for content.
	 *
	 * @var    string
	 * @since  3.0.2
	 */
	public $defaultLanguage;

	/**
	 * Constructor
	 *
	 * @since   3.0.3
	 */
	public function __construct()
	{
		$this->defaultLanguage = JComponentHelper::getParams('com_languages')->get('site', 'en-GB');
	}

	/**
	 * The magic set method is used to push additional values into the elements
	 * array in order to preserve the cleanliness of the object.
	 *
	 * @param   string  $name   The name of the element.
	 * @param   mixed   $value  The value of the element.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public function __set($name, $value)
	{
		$this->setElement($name, $value);
	}

	/**
	 * The magic get method is used to retrieve additional element values from the elements array.
	 *
	 * @param   string  $name  The name of the element.
	 *
	 * @return  mixed  The value of the element if set, null otherwise.
	 *
	 * @since   2.5
	 */
	public function __get($name)
	{
		return $this->getElement($name);
	}

	/**
	 * The magic isset method is used to check the state of additional element values in the elements array.
	 *
	 * @param   string  $name  The name of the element.
	 *
	 * @return  boolean  True if set, false otherwise.
	 *
	 * @since   2.5
	 */
	public function __isset($name)
	{
		return isset($this->elements[$name]);
	}

	/**
	 * The magic unset method is used to unset additional element values in the elements array.
	 *
	 * @param   string  $name  The name of the element.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public function __unset($name)
	{
		unset($this->elements[$name]);
	}

	/**
	 * Method to retrieve additional element values from the elements array.
	 *
	 * @param   string  $name  The name of the element.
	 *
	 * @return  mixed  The value of the element if set, null otherwise.
	 *
	 * @since   2.5
	 */
	public function getElement($name)
	{
		// Get the element value if set.
		if (array_key_exists($name, $this->elements))
		{
			return $this->elements[$name];
		}

		return null;
	}

	/**
	 * Method to retrieve all elements.
	 *
	 * @return  array  The elements
	 *
	 * @since   3.8.3
	 */
	public function getElements()
	{
		return $this->elements;
	}

	/**
	 * Method to set additional element values in the elements array.
	 *
	 * @param   string  $name   The name of the element.
	 * @param   mixed   $value  The value of the element.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public function setElement($name, $value)
	{
		$this->elements[$name] = $value;
	}

	/**
	 * Method to get all processing instructions.
	 *
	 * @return  array  An array of processing instructions.
	 *
	 * @since   2.5
	 */
	public function getInstructions()
	{
		return $this->instructions;
	}

	/**
	 * Method to add a processing instruction for an item property.
	 *
	 * @param   string  $group     The group to associate the property with.
	 * @param   string  $property  The property to process.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public function addInstruction($group, $property)
	{
		// Check if the group exists. We can't add instructions for unknown groups.
		// Check if the property exists in the group.
		if (array_key_exists($group, $this->instructions) && !in_array($property, $this->instructions[$group], true))
		{
			// Add the property to the group.
			$this->instructions[$group][] = $property;
		}
	}

	/**
	 * Method to remove a processing instruction for an item property.
	 *
	 * @param   string  $group     The group to associate the property with.
	 * @param   string  $property  The property to process.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public function removeInstruction($group, $property)
	{
		// Check if the group exists. We can't remove instructions for unknown groups.
		if (array_key_exists($group, $this->instructions))
		{
			// Search for the property in the group.
			$key = array_search($property, $this->instructions[$group]);

			// If the property was found, remove it.
			if ($key !== false)
			{
				unset($this->instructions[$group][$key]);
			}
		}
	}

	/**
	 * Method to get the taxonomy maps for an item.
	 *
	 * @param   string  $branch  The taxonomy branch to get. [optional]
	 *
	 * @return  array  An array of taxonomy maps.
	 *
	 * @since   2.5
	 */
	public function getTaxonomy($branch = null)
	{
		// Get the taxonomy branch if available.
		if ($branch !== null && isset($this->taxonomy[$branch]))
		{
			// Filter the input.
			$branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,_]+#mui', ' ', $branch);

			return $this->taxonomy[$branch];
		}

		return $this->taxonomy;
	}

	/**
	 * Method to add a taxonomy map for an item.
	 *
	 * @param   string   $branch  The title of the taxonomy branch to add the node to.
	 * @param   string   $title   The title of the taxonomy node.
	 * @param   integer  $state   The published state of the taxonomy node. [optional]
	 * @param   integer  $access  The access level of the taxonomy node. [optional]
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public function addTaxonomy($branch, $title, $state = 1, $access = 1)
	{
		// Filter the input.
		$branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,_]+#mui', ' ', $branch);

		// Create the taxonomy node.
		$node = new JObject;
		$node->title = $title;
		$node->state = (int) $state;
		$node->access = (int) $access;

		// Add the node to the taxonomy branch.
		$this->taxonomy[$branch][$node->title] = $node;
	}

	/**
	 * Method to set the item language
	 *
	 * @return  void
	 *
	 * @since   3.0
	 */
	public function setLanguage()
	{
		if ($this->language == '')
		{
			$this->language = $this->defaultLanguage;
		}
	}
}
PKW|!]⁵��indexer/token.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\String\StringHelper;

/**
 * Token class for the Finder indexer package.
 *
 * @since  2.5
 */
class FinderIndexerToken
{
	/**
	 * This is the term that will be referenced in the terms table and the
	 * mapping tables.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $term;

	/**
	 * The stem is used to match the root term and produce more potential
	 * matches when searching the index.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $stem;

	/**
	 * If the token is numeric, it is likely to be short and uncommon so the
	 * weight is adjusted to compensate for that situation.
	 *
	 * @var    boolean
	 * @since  2.5
	 */
	public $numeric;

	/**
	 * If the token is a common term, the weight is adjusted to compensate for
	 * the higher frequency of the term in relation to other terms.
	 *
	 * @var    boolean
	 * @since  2.5
	 */
	public $common;

	/**
	 * Flag for phrase tokens.
	 *
	 * @var    boolean
	 * @since  2.5
	 */
	public $phrase;

	/**
	 * The length is used to calculate the weight of the token.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	public $length;

	/**
	 * The weight is calculated based on token size and whether the token is
	 * considered a common term.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	public $weight;

	/**
	 * The simple language identifier for the token.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $language;

	/**
	 * The container for matches.
	 *
	 * @var    array
	 * @since  3.8.12
	 */
	public $matches = array();

	/**
	 * Is derived token (from individual words)
	 *
	 * @var    boolean
	 * @since  3.8.12
	 */
	public $derived;

	/**
	 * The suggested term
	 *
	 * @var    string
	 * @since  3.8.12
	 */
	public $suggestion;

	/**
	 * Method to construct the token object.
	 *
	 * @param   mixed   $term    The term as a string for words or an array for phrases.
	 * @param   string  $lang    The simple language identifier.
	 * @param   string  $spacer  The space separator for phrases. [optional]
	 *
	 * @since   2.5
	 */
	public function __construct($term, $lang, $spacer = ' ')
	{
		$this->language = $lang;

		// Tokens can be a single word or an array of words representing a phrase.
		if (is_array($term))
		{
			// Populate the token instance.
			$this->term = implode($spacer, $term);
			$this->stem = implode($spacer, array_map(array('FinderIndexerHelper', 'stem'), $term, array($lang)));
			$this->numeric = false;
			$this->common = false;
			$this->phrase = true;
			$this->length = StringHelper::strlen($this->term);

			/*
			 * Calculate the weight of the token.
			 *
			 * 1. Length of the token up to 30 and divide by 30, add 1.
			 * 2. Round weight to 4 decimal points.
			 */
			$this->weight = (($this->length >= 30 ? 30 : $this->length) / 30) + 1;
			$this->weight = round($this->weight, 4);
		}
		else
		{
			// Populate the token instance.
			$this->term = $term;
			$this->stem = FinderIndexerHelper::stem($this->term, $lang);
			$this->numeric = (is_numeric($this->term) || (bool) preg_match('#^[0-9,.\-\+]+$#', $this->term));
			$this->common = $this->numeric ? false : FinderIndexerHelper::isCommon($this->term, $lang);
			$this->phrase = false;
			$this->length = StringHelper::strlen($this->term);

			/*
			 * Calculate the weight of the token.
			 *
			 * 1. Length of the token up to 15 and divide by 15.
			 * 2. If common term, divide weight by 8.
			 * 3. If numeric, multiply weight by 1.5.
			 * 4. Round weight to 4 decimal points.
			 */
			$this->weight = ($this->length >= 15 ? 15 : $this->length) / 15;
			$this->weight = $this->common === true ? $this->weight / 8 : $this->weight;
			$this->weight = $this->numeric === true ? $this->weight * 1.5 : $this->weight;
			$this->weight = round($this->weight, 4);
		}
	}
}
PKW|!]��&��indexer/parser/txt.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('FinderIndexerParser', dirname(__DIR__) . '/parser.php');

/**
 * Text Parser class for the Finder indexer package.
 *
 * @since  2.5
 */
class FinderIndexerParserTxt extends FinderIndexerParser
{
	/**
	 * Method to process Text input and extract the plain text.
	 *
	 * @param   string  $input  The input to process.
	 *
	 * @return  string  The plain text input.
	 *
	 * @since   2.5
	 */
	protected function process($input)
	{
		return $input;
	}
}
PKW|!]����nnindexer/parser/html.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('FinderIndexerParser', dirname(__DIR__) . '/parser.php');

/**
 * HTML Parser class for the Finder indexer package.
 *
 * @since  2.5
 */
class FinderIndexerParserHtml extends FinderIndexerParser
{
	/**
	 * Method to parse input and extract the plain text. Because this method is
	 * called from both inside and outside the indexer, it needs to be able to
	 * batch out its parsing functionality to deal with the inefficiencies of
	 * regular expressions. We will parse recursively in 2KB chunks.
	 *
	 * @param   string  $input  The input to parse.
	 *
	 * @return  string  The plain text input.
	 *
	 * @since   2.5
	 */
	public function parse($input)
	{
		// Strip invalid UTF-8 characters.
		$input = iconv('utf-8', 'utf-8//IGNORE', $input);

		// Remove anything between <head> and </head> tags.  Do this first
		// because there might be <script> or <style> tags nested inside.
		$input = $this->removeBlocks($input, '<head>', '</head>');

		// Convert <style> and <noscript> tags to <script> tags
		// so we can remove them efficiently.
		$search = array(
			'<style', '</style',
			'<noscript', '</noscript',
		);
		$replace = array(
			'<script', '</script',
			'<script', '</script',
		);
		$input = str_replace($search, $replace, $input);

		// Strip all script blocks.
		$input = $this->removeBlocks($input, '<script', '</script>');

		// Decode HTML entities.
		$input = html_entity_decode($input, ENT_QUOTES, 'UTF-8');

		// Convert entities equivalent to spaces to actual spaces.
		$input = str_replace(array('&nbsp;', '&#160;'), ' ', $input);

		// Add a space before both the OPEN and CLOSE tags of BLOCK and LINE BREAKING elements,
		// e.g. 'all<h1><em>m</em>obile  List</h1>' will become 'all mobile  List'
		$input = preg_replace('/(<|<\/)(' .
			'address|article|aside|blockquote|br|canvas|dd|div|dl|dt|' .
			'fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|li|' .
			'main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video' .
			')\b/i', ' $1$2', $input
		);

		// Strip HTML tags.
		$input = strip_tags($input);

		return parent::parse($input);
	}

	/**
	 * Method to process HTML input and extract the plain text.
	 *
	 * @param   string  $input  The input to process.
	 *
	 * @return  string  The plain text input.
	 *
	 * @since   2.5
	 */
	protected function process($input)
	{
		// Replace any amount of white space with a single space.
		return preg_replace('#\s+#u', ' ', $input);
	}

	/**
	 * Method to remove blocks of text between a start and an end tag.
	 * Each block removed is effectively replaced by a single space.
	 *
	 * Note: The start tag and the end tag must be different.
	 * Note: Blocks must not be nested.
	 * Note: This method will function correctly with multi-byte strings.
	 *
	 * @param   string  $input     String to be processed.
	 * @param   string  $startTag  String representing the start tag.
	 * @param   string  $endTag    String representing the end tag.
	 *
	 * @return  string with blocks removed.
	 *
	 * @since   3.4
	 */
	private function removeBlocks($input, $startTag, $endTag)
	{
		$return = '';
		$offset = 0;
		$startTagLength = strlen($startTag);
		$endTagLength = strlen($endTag);

		// Find the first start tag.
		$start = stripos($input, $startTag);

		// If no start tags were found, return the string unchanged.
		if ($start === false)
		{
			return $input;
		}

		// Look for all blocks defined by the start and end tags.
		while ($start !== false)
		{
			// Accumulate the substring up to the start tag.
			$return .= substr($input, $offset, $start - $offset) . ' ';

			// Look for an end tag corresponding to the start tag.
			$end = stripos($input, $endTag, $start + $startTagLength);

			// If no corresponding end tag, leave the string alone.
			if ($end === false)
			{
				// Fix the offset so part of the string is not duplicated.
				$offset = $start;
				break;
			}

			// Advance the start position.
			$offset = $end + $endTagLength;

			// Look for the next start tag and loop.
			$start = stripos($input, $startTag, $offset);
		}

		// Add in the final substring after the last end tag.
		$return .= substr($input, $offset);

		return $return;
	}
}
PKW|!]{�;  indexer/parser/rtf.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('FinderIndexerParser', dirname(__DIR__) . '/parser.php');

/**
 * RTF Parser class for the Finder indexer package.
 *
 * @since  2.5
 */
class FinderIndexerParserRtf extends FinderIndexerParser
{
	/**
	 * Method to process RTF input and extract the plain text.
	 *
	 * @param   string  $input  The input to process.
	 *
	 * @return  string  The plain text input.
	 *
	 * @since   2.5
	 */
	protected function process($input)
	{
		// Remove embedded pictures.
		$input = preg_replace('#{\\\pict[^}]*}#mi', '', $input);

		// Remove control characters.
		$input = str_replace(array('{', '}', "\\\n"), array(' ', ' ', "\n"), $input);
		$input = preg_replace('#\\\([^;]+?);#m', ' ', $input);
		$input = preg_replace('#\\\[\'a-zA-Z0-9]+#mi', ' ', $input);

		return $input;
	}
}
PKW|!]<���8�8indexer/helper.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;
use Joomla\String\StringHelper;

JLoader::register('FinderIndexerParser', __DIR__ . '/parser.php');
JLoader::register('FinderIndexerStemmer', __DIR__ . '/stemmer.php');
JLoader::register('FinderIndexerToken', __DIR__ . '/token.php');

/**
 * Helper class for the Finder indexer package.
 *
 * @since  2.5
 */
class FinderIndexerHelper
{
	/**
	 * The token stemmer object. The stemmer is set by whatever class
	 * wishes to use it but it must be an instance of FinderIndexerStemmer.
	 *
	 * @var		FinderIndexerStemmer
	 * @since	2.5
	 */
	public static $stemmer;

	/**
	 * A state flag, in order to not constantly check if the stemmer is an instance of FinderIndexerStemmer
	 *
	 * @var		boolean
	 * @since	3.7.0
	 */
	protected static $stemmerOK;

	/**
	 * Method to parse input into plain text.
	 *
	 * @param   string  $input   The raw input.
	 * @param   string  $format  The format of the input. [optional]
	 *
	 * @return  string  The parsed input.
	 *
	 * @since   2.5
	 * @throws  Exception on invalid parser.
	 */
	public static function parse($input, $format = 'html')
	{
		// Get a parser for the specified format and parse the input.
		return FinderIndexerParser::getInstance($format)->parse($input);
	}

	/**
	 * Method to tokenize a text string.
	 *
	 * @param   string   $input   The input to tokenize.
	 * @param   string   $lang    The language of the input.
	 * @param   boolean  $phrase  Flag to indicate whether input could be a phrase. [optional]
	 *
	 * @return  array|FinderIndexerToken  An array of FinderIndexerToken objects or a single FinderIndexerToken object.
	 *
	 * @since   2.5
	 */
	public static function tokenize($input, $lang, $phrase = false)
	{
		static $cache;
		$store = StringHelper::strlen($input) < 128 ? md5($input . '::' . $lang . '::' . $phrase) : null;

		// Check if the string has been tokenized already.
		if ($store && isset($cache[$store]))
		{
			return $cache[$store];
		}

		$tokens = array();
		$quotes = html_entity_decode('&#8216;&#8217;&#39;', ENT_QUOTES, 'UTF-8');

		// Get the simple language key.
		$lang = static::getPrimaryLanguage($lang);

		/*
		 * Parsing the string input into terms is a multi-step process.
		 *
		 * Regexes:
		 *  1. Remove everything except letters, numbers, quotes, apostrophe, plus, dash, period, and comma.
		 *  2. Remove plus, dash, period, and comma characters located before letter characters.
		 *  3. Remove plus, dash, period, and comma characters located after other characters.
		 *  4. Remove plus, period, and comma characters enclosed in alphabetical characters. Ungreedy.
		 *  5. Remove orphaned apostrophe, plus, dash, period, and comma characters.
		 *  6. Remove orphaned quote characters.
		 *  7. Replace the assorted single quotation marks with the ASCII standard single quotation.
		 *  8. Remove multiple space characters and replaces with a single space.
		 */
		$input = StringHelper::strtolower($input);
		$input = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $input);
		$input = preg_replace('#(^|\s)[+-.,]+([\pL\pM]+)#mui', ' $1', $input);
		$input = preg_replace('#([\pL\pM\pN]+)[+-.,]+(\s|$)#mui', '$1 ', $input);
		$input = preg_replace('#([\pL\pM]+)[+.,]+([\pL\pM]+)#muiU', '$1 $2', $input);
		$input = preg_replace('#(^|\s)[\'+-.,]+(\s|$)#mui', ' ', $input);
		$input = preg_replace('#(^|\s)[\p{Pi}\p{Pf}]+(\s|$)#mui', ' ', $input);
		$input = preg_replace('#[' . $quotes . ']+#mui', '\'', $input);
		$input = preg_replace('#\s+#mui', ' ', $input);
		$input = trim($input);

		// Explode the normalized string to get the terms.
		$terms = explode(' ', $input);

		/*
		 * If we have Unicode support and are dealing with Chinese text, Chinese
		 * has to be handled specially because there are not necessarily any spaces
		 * between the "words". So, we have to test if the words belong to the Chinese
		 * character set and if so, explode them into single glyphs or "words".
		 */
		if ($lang === 'zh')
		{
			// Iterate through the terms and test if they contain Chinese.
			for ($i = 0, $n = count($terms); $i < $n; $i++)
			{
				$charMatches = array();
				$charCount   = preg_match_all('#[\p{Han}]#mui', $terms[$i], $charMatches);

				// Split apart any groups of Chinese characters.
				for ($j = 0; $j < $charCount; $j++)
				{
					$tSplit = StringHelper::str_ireplace($charMatches[0][$j], '', $terms[$i], false);

					if ((bool) $tSplit)
					{
						$terms[$i] = $tSplit;
					}
					else
					{
						unset($terms[$i]);
					}

					$terms[] = $charMatches[0][$j];
				}
			}

			// Reset array keys.
			$terms = array_values($terms);
		}

		/*
		 * If we have to handle the input as a phrase, that means we don't
		 * tokenize the individual terms and we do not create the two and three
		 * term combinations. The phrase must contain more than one word!
		 */
		if ($phrase === true && count($terms) > 1)
		{
			// Create tokens from the phrase.
			$tokens[] = new FinderIndexerToken($terms, $lang);
		}
		else
		{
			// Create tokens from the terms.
			for ($i = 0, $n = count($terms); $i < $n; $i++)
			{
				$tokens[] = new FinderIndexerToken($terms[$i], $lang);
			}

			// Create two and three word phrase tokens from the individual words.
			for ($i = 0, $n = count($tokens); $i < $n; $i++)
			{
				// Setup the phrase positions.
				$i2 = $i + 1;
				$i3 = $i + 2;

				// Create the two word phrase.
				if ($i2 < $n && isset($tokens[$i2]))
				{
					// Tokenize the two word phrase.
					$token          = new FinderIndexerToken(
						array(
							$tokens[$i]->term,
							$tokens[$i2]->term
						), $lang, $lang === 'zh' ? '' : ' '
					);
					$token->derived = true;

					// Add the token to the stack.
					$tokens[] = $token;
				}

				// Create the three word phrase.
				if ($i3 < $n && isset($tokens[$i3]))
				{
					// Tokenize the three word phrase.
					$token          = new FinderIndexerToken(
						array(
							$tokens[$i]->term,
							$tokens[$i2]->term,
							$tokens[$i3]->term
						), $lang, $lang === 'zh' ? '' : ' '
					);
					$token->derived = true;

					// Add the token to the stack.
					$tokens[] = $token;
				}
			}
		}

		if ($store)
		{
			$cache[$store] = count($tokens) > 1 ? $tokens : array_shift($tokens);

			return $cache[$store];
		}
		else
		{
			return count($tokens) > 1 ? $tokens : array_shift($tokens);
		}
	}

	/**
	 * Method to get the base word of a token. This method uses the public
	 * {@link FinderIndexerHelper::$stemmer} object if it is set. If no stemmer is set,
	 * the original token is returned.
	 *
	 * @param   string  $token  The token to stem.
	 * @param   string  $lang   The language of the token.
	 *
	 * @return  string  The root token.
	 *
	 * @since   2.5
	 */
	public static function stem($token, $lang)
	{
		// Trim apostrophes at either end of the token.
		$token = trim($token, '\'');

		// Trim everything after any apostrophe in the token.
		if ($res = explode('\'', $token))
		{
			$token = $res[0];
		}

		if (static::$stemmerOK === true)
		{
			return static::$stemmer->stem($token, $lang);
		}
		else
		{
			// Stem the token if we have a valid stemmer to use.
			if (static::$stemmer instanceof FinderIndexerStemmer)
			{
				static::$stemmerOK = true;

				return static::$stemmer->stem($token, $lang);
			}
		}

		return $token;
	}

	/**
	 * Method to add a content type to the database.
	 *
	 * @param   string  $title  The type of content. For example: PDF
	 * @param   string  $mime   The mime type of the content. For example: PDF [optional]
	 *
	 * @return  integer  The id of the content type.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function addContentType($title, $mime = null)
	{
		static $types;

		$db    = JFactory::getDbo();
		$query = $db->getQuery(true);

		// Check if the types are loaded.
		if (empty($types))
		{
			// Build the query to get the types.
			$query->select('*')
				->from($db->quoteName('#__finder_types'));

			// Get the types.
			$db->setQuery($query);
			$types = $db->loadObjectList('title');
		}

		// Check if the type already exists.
		if (isset($types[$title]))
		{
			return (int) $types[$title]->id;
		}

		// Add the type.
		$query->clear()
			->insert($db->quoteName('#__finder_types'))
			->columns(array($db->quoteName('title'), $db->quoteName('mime')))
			->values($db->quote($title) . ', ' . $db->quote($mime));
		$db->setQuery($query);
		$db->execute();

		// Return the new id.
		return (int) $db->insertid();
	}

	/**
	 * Method to check if a token is common in a language.
	 *
	 * @param   string  $token  The token to test.
	 * @param   string  $lang   The language to reference.
	 *
	 * @return  boolean  True if common, false otherwise.
	 *
	 * @since   2.5
	 */
	public static function isCommon($token, $lang)
	{
		static $data;
		static $default;

		$langCode = $lang;

		// If language requested is wildcard, use the default language.
		if ($default === null && $lang === '*')
		{
			$default = strstr(self::getDefaultLanguage(), '-', true);
			$langCode = $default;
		}

		// Load the common tokens for the language if necessary.
		if (!isset($data[$langCode]))
		{
			$data[$langCode] = self::getCommonWords($langCode);
		}

		// Check if the token is in the common array.
		return in_array($token, $data[$langCode], true);
	}

	/**
	 * Method to get an array of common terms for a language.
	 *
	 * @param   string  $lang  The language to use.
	 *
	 * @return  array  Array of common terms.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function getCommonWords($lang)
	{
		$db = JFactory::getDbo();

		// Create the query to load all the common terms for the language.
		$query = $db->getQuery(true)
			->select($db->quoteName('term'))
			->from($db->quoteName('#__finder_terms_common'))
			->where($db->quoteName('language') . ' = ' . $db->quote($lang));

		// Load all of the common terms for the language.
		$db->setQuery($query);

		return $db->loadColumn();
	}

	/**
	 * Method to get the default language for the site.
	 *
	 * @return  string  The default language string.
	 *
	 * @since   2.5
	 */
	public static function getDefaultLanguage()
	{
		static $lang;

		// We need to go to com_languages to get the site default language, it's the best we can guess.
		if (empty($lang))
		{
			$lang = JComponentHelper::getParams('com_languages')->get('site', 'en-GB');
		}

		return $lang;
	}

	/**
	 * Method to parse a language/locale key and return a simple language string.
	 *
	 * @param   string  $lang  The language/locale key. For example: en-GB
	 *
	 * @return  string  The simple language string. For example: en
	 *
	 * @since   2.5
	 */
	public static function getPrimaryLanguage($lang)
	{
		static $data;

		// Only parse the identifier if necessary.
		if (!isset($data[$lang]))
		{
			if (is_callable(array('Locale', 'getPrimaryLanguage')))
			{
				// Get the language key using the Locale package.
				$data[$lang] = Locale::getPrimaryLanguage($lang);
			}
			else
			{
				// Get the language key using string position.
				$data[$lang] = StringHelper::substr($lang, 0, StringHelper::strpos($lang, '-'));
			}
		}

		return $data[$lang];
	}

	/**
	 * Method to get the path (SEF route) for a content item.
	 *
	 * @param   string  $url  The non-SEF route to the content item.
	 *
	 * @return  string  The path for the content item.
	 *
	 * @since       2.5
	 * @deprecated  4.0
	 */
	public static function getContentPath($url)
	{
		static $router;

		// Only get the router once.
		if (!($router instanceof JRouter))
		{
			// Get and configure the site router.
			$config = JFactory::getConfig();
			$router = JRouter::getInstance('site');
			$router->setMode($config->get('sef', 1));
		}

		// Build the relative route.
		$uri   = $router->build($url);
		$route = $uri->toString(array('path', 'query', 'fragment'));
		$route = str_replace(JUri::base(true) . '/', '', $route);

		return $route;
	}

	/**
	 * Method to get extra data for a content before being indexed. This is how
	 * we add Comments, Tags, Labels, etc. that should be available to Finder.
	 *
	 * @param   FinderIndexerResult  $item  The item to index as a FinderIndexerResult object.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	public static function getContentExtras(FinderIndexerResult $item)
	{
		// Get the event dispatcher.
		$dispatcher = JEventDispatcher::getInstance();

		// Load the finder plugin group.
		JPluginHelper::importPlugin('finder');

		// Trigger the event.
		$results = $dispatcher->trigger('onPrepareFinderContent', array(&$item));

		// Check the returned results. This is for plugins that don't throw
		// exceptions when they encounter serious errors.
		if (in_array(false, $results))
		{
			throw new Exception($dispatcher->getError(), 500);
		}

		return true;
	}

	/**
	 * Method to process content text using the onContentPrepare event trigger.
	 *
	 * @param   string               $text    The content to process.
	 * @param   Registry             $params  The parameters object. [optional]
	 * @param   FinderIndexerResult  $item    The item which get prepared. [optional]
	 *
	 * @return  string  The processed content.
	 *
	 * @since   2.5
	 */
	public static function prepareContent($text, $params = null, FinderIndexerResult $item = null)
	{
		static $loaded;

		// Get the dispatcher.
		$dispatcher = JEventDispatcher::getInstance();

		// Load the content plugins if necessary.
		if (empty($loaded))
		{
			JPluginHelper::importPlugin('content');
			$loaded = true;
		}

		// Instantiate the parameter object if necessary.
		if (!($params instanceof Registry))
		{
			$registry = new Registry($params);
			$params = $registry;
		}

		// Create a mock content object.
		$content       = JTable::getInstance('Content');
		$content->text = $text;

		if ($item)
		{
			$content->bind((array) $item);
			$content->bind($item->getElements());
		}

		if ($item && !empty($item->context))
		{
			$content->context = $item->context;
		}

		// Fire the onContentPrepare event.
		$dispatcher->trigger('onContentPrepare', array('com_finder.indexer', &$content, &$params, 0));

		return $content->text;
	}
}
PKW|!]�W��U�Uindexer/adapter.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

JLoader::register('FinderIndexer', __DIR__ . '/indexer.php');
JLoader::register('FinderIndexerHelper', __DIR__ . '/helper.php');
JLoader::register('FinderIndexerResult', __DIR__ . '/result.php');
JLoader::register('FinderIndexerTaxonomy', __DIR__ . '/taxonomy.php');

/**
 * Prototype adapter class for the Finder indexer package.
 *
 * @since  2.5
 */
abstract class FinderIndexerAdapter extends JPlugin
{
	/**
	 * The context is somewhat arbitrary but it must be unique or there will be
	 * conflicts when managing plugin/indexer state. A good best practice is to
	 * use the plugin name suffix as the context. For example, if the plugin is
	 * named 'plgFinderContent', the context could be 'Content'.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $context;

	/**
	 * The extension name.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $extension;

	/**
	 * The sublayout to use when rendering the results.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $layout;

	/**
	 * The mime type of the content the adapter indexes.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $mime;

	/**
	 * The access level of an item before save.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	protected $old_access;

	/**
	 * The access level of a category before save.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	protected $old_cataccess;

	/**
	 * The type of content the adapter indexes.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $type_title;

	/**
	 * The type id of the content.
	 *
	 * @var    integer
	 * @since  2.5
	 */
	protected $type_id;

	/**
	 * The database object.
	 *
	 * @var    object
	 * @since  2.5
	 */
	protected $db;

	/**
	 * The table name.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $table;

	/**
	 * The indexer object.
	 *
	 * @var    FinderIndexer
	 * @since  3.0
	 */
	protected $indexer;

	/**
	 * The field the published state is stored in.
	 *
	 * @var    string
	 * @since  2.5
	 */
	protected $state_field = 'state';

	/**
	 * Method to instantiate the indexer adapter.
	 *
	 * @param   object  $subject  The object to observe.
	 * @param   array   $config   An array that holds the plugin configuration.
	 *
	 * @since   2.5
	 */
	public function __construct(&$subject, $config)
	{
		// Get the database object.
		$this->db = JFactory::getDbo();

		// Call the parent constructor.
		parent::__construct($subject, $config);

		// Get the type id.
		$this->type_id = $this->getTypeId();

		// Add the content type if it doesn't exist and is set.
		if (empty($this->type_id) && !empty($this->type_title))
		{
			$this->type_id = FinderIndexerHelper::addContentType($this->type_title, $this->mime);
		}

		// Check for a layout override.
		if ($this->params->get('layout'))
		{
			$this->layout = $this->params->get('layout');
		}

		// Get the indexer object
		$this->indexer = FinderIndexer::getInstance();
	}

	/**
	 * Method to get the adapter state and push it into the indexer.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 * @throws  Exception on error.
	 */
	public function onStartIndex()
	{
		// Get the indexer state.
		$iState = FinderIndexer::getState();

		// Get the number of content items.
		$total = (int) $this->getContentCount();

		// Add the content count to the total number of items.
		$iState->totalItems += $total;

		// Populate the indexer state information for the adapter.
		$iState->pluginState[$this->context]['total'] = $total;
		$iState->pluginState[$this->context]['offset'] = 0;

		// Set the indexer state.
		FinderIndexer::setState($iState);
	}

	/**
	 * Method to prepare for the indexer to be run. This method will often
	 * be used to include dependencies and things of that nature.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on error.
	 */
	public function onBeforeIndex()
	{
		// Get the indexer and adapter state.
		$iState = FinderIndexer::getState();
		$aState = $iState->pluginState[$this->context];

		// Check the progress of the indexer and the adapter.
		if ($iState->batchOffset == $iState->batchSize || $aState['offset'] == $aState['total'])
		{
			return true;
		}

		// Run the setup method.
		return $this->setup();
	}

	/**
	 * Method to index a batch of content items. This method can be called by
	 * the indexer many times throughout the indexing process depending on how
	 * much content is available for indexing. It is important to track the
	 * progress correctly so we can display it to the user.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on error.
	 */
	public function onBuildIndex()
	{
		// Get the indexer and adapter state.
		$iState = FinderIndexer::getState();
		$aState = $iState->pluginState[$this->context];

		// Check the progress of the indexer and the adapter.
		if ($iState->batchOffset == $iState->batchSize || $aState['offset'] == $aState['total'])
		{
			return true;
		}

		// Get the batch offset and size.
		$offset = (int) $aState['offset'];
		$limit = (int) ($iState->batchSize - $iState->batchOffset);

		// Get the content items to index.
		$items = $this->getItems($offset, $limit);

		// Iterate through the items and index them.
		for ($i = 0, $n = count($items); $i < $n; $i++)
		{
			// Index the item.
			$this->index($items[$i]);

			// Adjust the offsets.
			$offset++;
			$iState->batchOffset++;
			$iState->totalItems--;
		}

		// Update the indexer state.
		$aState['offset'] = $offset;
		$iState->pluginState[$this->context] = $aState;
		FinderIndexer::setState($iState);

		return true;
	}

	/**
	 * Method to change the value of a content item's property in the links
	 * table. This is used to synchronize published and access states that
	 * are changed when not editing an item directly.
	 *
	 * @param   string   $id        The ID of the item to change.
	 * @param   string   $property  The property that is being changed.
	 * @param   integer  $value     The new value of that property.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function change($id, $property, $value)
	{
		// Check for a property we know how to handle.
		if ($property !== 'state' && $property !== 'access')
		{
			return true;
		}

		// Get the URL for the content id.
		$item = $this->db->quote($this->getUrl($id, $this->extension, $this->layout));

		// Update the content items.
		$query = $this->db->getQuery(true)
			->update($this->db->quoteName('#__finder_links'))
			->set($this->db->quoteName($property) . ' = ' . (int) $value)
			->where($this->db->quoteName('url') . ' = ' . $item);
		$this->db->setQuery($query);
		$this->db->execute();

		return true;
	}

	/**
	 * Method to index an item.
	 *
	 * @param   FinderIndexerResult  $item  The item to index as a FinderIndexerResult object.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	abstract protected function index(FinderIndexerResult $item);

	/**
	 * Method to reindex an item.
	 *
	 * @param   integer  $id  The ID of the item to reindex.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function reindex($id)
	{
		// Run the setup method.
		$this->setup();

		// Remove the old item.
		$this->remove($id);

		// Get the item.
		$item = $this->getItem($id);

		// Index the item.
		$this->index($item);
	}

	/**
	 * Method to remove an item from the index.
	 *
	 * @param   string  $id  The ID of the item to remove.
	 *
	 * @return  boolean  True on success.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function remove($id)
	{
		// Get the item's URL
		$url = $this->db->quote($this->getUrl($id, $this->extension, $this->layout));

		// Get the link ids for the content items.
		$query = $this->db->getQuery(true)
			->select($this->db->quoteName('link_id'))
			->from($this->db->quoteName('#__finder_links'))
			->where($this->db->quoteName('url') . ' = ' . $url);
		$this->db->setQuery($query);
		$items = $this->db->loadColumn();

		// Check the items.
		if (empty($items))
		{
			return true;
		}

		// Remove the items.
		foreach ($items as $item)
		{
			$this->indexer->remove($item);
		}

		return true;
	}

	/**
	 * Method to setup the adapter before indexing.
	 *
	 * @return  boolean  True on success, false on failure.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	abstract protected function setup();

	/**
	 * Method to update index data on category access level changes
	 *
	 * @param   JTable  $row  A JTable object
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	protected function categoryAccessChange($row)
	{
		$query = clone $this->getStateQuery();
		$query->where('c.id = ' . (int) $row->id);

		// Get the access level.
		$this->db->setQuery($query);
		$items = $this->db->loadObjectList();

		// Adjust the access level for each item within the category.
		foreach ($items as $item)
		{
			// Set the access level.
			$temp = max($item->access, $row->access);

			// Update the item.
			$this->change((int) $item->id, 'access', $temp);

			// Reindex the item
			$this->reindex($row->id);
		}
	}

	/**
	 * Method to update index data on category access level changes
	 *
	 * @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
	 */
	protected function categoryStateChange($pks, $value)
	{
		/*
		 * The item's published state is tied to the category
		 * published state so we need to look up all published states
		 * before we change anything.
		 */
		foreach ($pks as $pk)
		{
			$query = clone $this->getStateQuery();
			$query->where('c.id = ' . (int) $pk);

			// Get the published states.
			$this->db->setQuery($query);
			$items = $this->db->loadObjectList();

			// Adjust the state for each item within the category.
			foreach ($items as $item)
			{
				// Translate the state.
				$temp = $this->translateState($item->state, $value);

				// Update the item.
				$this->change($item->id, 'state', $temp);

				// Reindex the item
				$this->reindex($item->id);
			}
		}
	}

	/**
	 * Method to check the existing access level for categories
	 *
	 * @param   JTable  $row  A JTable object
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	protected function checkCategoryAccess($row)
	{
		$query = $this->db->getQuery(true)
			->select($this->db->quoteName('access'))
			->from($this->db->quoteName('#__categories'))
			->where($this->db->quoteName('id') . ' = ' . (int) $row->id);
		$this->db->setQuery($query);

		// Store the access level to determine if it changes
		$this->old_cataccess = $this->db->loadResult();
	}

	/**
	 * Method to check the existing access level for items
	 *
	 * @param   JTable  $row  A JTable object
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	protected function checkItemAccess($row)
	{
		$query = $this->db->getQuery(true)
			->select($this->db->quoteName('access'))
			->from($this->db->quoteName($this->table))
			->where($this->db->quoteName('id') . ' = ' . (int) $row->id);
		$this->db->setQuery($query);

		// Store the access level to determine if it changes
		$this->old_access = $this->db->loadResult();
	}

	/**
	 * Method to get the number of content items available to index.
	 *
	 * @return  integer  The number of content items available to index.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function getContentCount()
	{
		$return = 0;

		// Get the list query.
		$query = $this->getListQuery();

		// Check if the query is valid.
		if (empty($query))
		{
			return $return;
		}

		// Tweak the SQL query to make the total lookup faster.
		if ($query instanceof JDatabaseQuery)
		{
			$query = clone $query;
			$query->clear('select')
				->select('COUNT(*)')
				->clear('order');
		}

		// Get the total number of content items to index.
		$this->db->setQuery($query);

		return (int) $this->db->loadResult();
	}

	/**
	 * Method to get a content item to index.
	 *
	 * @param   integer  $id  The id of the content item.
	 *
	 * @return  FinderIndexerResult  A FinderIndexerResult object.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function getItem($id)
	{
		// Get the list query and add the extra WHERE clause.
		$query = $this->getListQuery();
		$query->where('a.id = ' . (int) $id);

		// Get the item to index.
		$this->db->setQuery($query);
		$row = $this->db->loadAssoc();

		// Convert the item to a result object.
		$item = ArrayHelper::toObject((array) $row, 'FinderIndexerResult');

		// Set the item type.
		$item->type_id = $this->type_id;

		// Set the item layout.
		$item->layout = $this->layout;

		return $item;
	}

	/**
	 * Method to get a list of content items to index.
	 *
	 * @param   integer         $offset  The list offset.
	 * @param   integer         $limit   The list limit.
	 * @param   JDatabaseQuery  $query   A JDatabaseQuery object. [optional]
	 *
	 * @return  array  An array of FinderIndexerResult objects.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function getItems($offset, $limit, $query = null)
	{
		$items = array();

		// Get the content items to index.
		$this->db->setQuery($this->getListQuery($query), $offset, $limit);
		$rows = $this->db->loadAssocList();

		// Convert the items to result objects.
		foreach ($rows as $row)
		{
			// Convert the item to a result object.
			$item = ArrayHelper::toObject((array) $row, 'FinderIndexerResult');

			// Set the item type.
			$item->type_id = $this->type_id;

			// Set the mime type.
			$item->mime = $this->mime;

			// Set the item layout.
			$item->layout = $this->layout;

			// Set the extension if present
			if (isset($row->extension))
			{
				$item->extension = $row->extension;
			}

			// Add the item to the stack.
			$items[] = $item;
		}

		return $items;
	}

	/**
	 * Method to get the SQL query used to retrieve the list of content items.
	 *
	 * @param   mixed  $query  A JDatabaseQuery object. [optional]
	 *
	 * @return  JDatabaseQuery  A database object.
	 *
	 * @since   2.5
	 */
	protected function getListQuery($query = null)
	{
		// Check if we can use the supplied SQL query.
		return $query instanceof JDatabaseQuery ? $query : $this->db->getQuery(true);
	}

	/**
	 * Method to get the plugin type
	 *
	 * @param   integer  $id  The plugin ID
	 *
	 * @return  string  The plugin type
	 *
	 * @since   2.5
	 */
	protected function getPluginType($id)
	{
		// Prepare the query
		$query = $this->db->getQuery(true)
			->select($this->db->quoteName('element'))
			->from($this->db->quoteName('#__extensions'))
			->where($this->db->quoteName('extension_id') . ' = ' . (int) $id);
		$this->db->setQuery($query);

		return $this->db->loadResult();
	}

	/**
	 * Method to get a SQL query to load the published and access states for
	 * an article and category.
	 *
	 * @return  JDatabaseQuery  A database object.
	 *
	 * @since   2.5
	 */
	protected function getStateQuery()
	{
		$query = $this->db->getQuery(true);

		// Item ID
		$query->select('a.id');

		// Item and category published state
		$query->select('a.' . $this->state_field . ' AS state, c.published AS cat_state');

		// Item and category access levels
		$query->select('a.access, c.access AS cat_access')
			->from($this->table . ' AS a')
			->join('LEFT', '#__categories AS c ON c.id = a.catid');

		return $query;
	}

	/**
	 * Method to get the query clause for getting items to update by time.
	 *
	 * @param   string  $time  The modified timestamp.
	 *
	 * @return  JDatabaseQuery  A database object.
	 *
	 * @since   2.5
	 */
	protected function getUpdateQueryByTime($time)
	{
		// Build an SQL query based on the modified time.
		$query = $this->db->getQuery(true)
			->where('a.modified >= ' . $this->db->quote($time));

		return $query;
	}

	/**
	 * Method to get the query clause for getting items to update by id.
	 *
	 * @param   array  $ids  The ids to load.
	 *
	 * @return  JDatabaseQuery  A database object.
	 *
	 * @since   2.5
	 */
	protected function getUpdateQueryByIds($ids)
	{
		// Build an SQL query based on the item ids.
		$query = $this->db->getQuery(true)
			->where('a.id IN(' . implode(',', $ids) . ')');

		return $query;
	}

	/**
	 * Method to get the type id for the adapter content.
	 *
	 * @return  integer  The numeric type id for the content.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function getTypeId()
	{
		// Get the type id from the database.
		$query = $this->db->getQuery(true)
			->select($this->db->quoteName('id'))
			->from($this->db->quoteName('#__finder_types'))
			->where($this->db->quoteName('title') . ' = ' . $this->db->quote($this->type_title));
		$this->db->setQuery($query);

		return (int) $this->db->loadResult();
	}

	/**
	 * Method to get the URL for the item. The URL is how we look up the link
	 * in the Finder index.
	 *
	 * @param   integer  $id         The id of the item.
	 * @param   string   $extension  The extension the category is in.
	 * @param   string   $view       The view for the URL.
	 *
	 * @return  string  The URL of the item.
	 *
	 * @since   2.5
	 */
	protected function getUrl($id, $extension, $view)
	{
		return 'index.php?option=' . $extension . '&view=' . $view . '&id=' . $id;
	}

	/**
	 * Method to get the page title of any menu item that is linked to the
	 * content item, if it exists and is set.
	 *
	 * @param   string  $url  The URL of the item.
	 *
	 * @return  mixed  The title on success, null if not found.
	 *
	 * @since   2.5
	 * @throws  Exception on database error.
	 */
	protected function getItemMenuTitle($url)
	{
		$return = null;

		// Set variables
		$user = JFactory::getUser();
		$groups = implode(',', $user->getAuthorisedViewLevels());

		// Build a query to get the menu params.
		$query = $this->db->getQuery(true)
			->select($this->db->quoteName('params'))
			->from($this->db->quoteName('#__menu'))
			->where($this->db->quoteName('link') . ' = ' . $this->db->quote($url))
			->where($this->db->quoteName('published') . ' = 1')
			->where($this->db->quoteName('access') . ' IN (' . $groups . ')');

		// Get the menu params from the database.
		$this->db->setQuery($query);
		$params = $this->db->loadResult();

		// Check the results.
		if (empty($params))
		{
			return $return;
		}

		// Instantiate the params.
		$params = json_decode($params);

		// Get the page title if it is set.
		if (isset($params->page_title) && $params->page_title)
		{
			$return = $params->page_title;
		}

		return $return;
	}

	/**
	 * Method to update index data on access level changes
	 *
	 * @param   JTable  $row  A JTable object
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	protected function itemAccessChange($row)
	{
		$query = clone $this->getStateQuery();
		$query->where('a.id = ' . (int) $row->id);

		// Get the access level.
		$this->db->setQuery($query);
		$item = $this->db->loadObject();

		// Set the access level.
		$temp = max($row->access, $item->cat_access);

		// Update the item.
		$this->change((int) $row->id, 'access', $temp);
	}

	/**
	 * Method to update index data on published state changes
	 *
	 * @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
	 */
	protected function itemStateChange($pks, $value)
	{
		/*
		 * The item's published state is tied to the category
		 * published state so we need to look up all published states
		 * before we change anything.
		 */
		foreach ($pks as $pk)
		{
			$query = clone $this->getStateQuery();
			$query->where('a.id = ' . (int) $pk);

			// Get the published states.
			$this->db->setQuery($query);
			$item = $this->db->loadObject();

			// Translate the state.
			$temp = $this->translateState($value, $item->cat_state);

			// Update the item.
			$this->change($pk, 'state', $temp);

			// Reindex the item
			$this->reindex($pk);
		}
	}

	/**
	 * Method to update index data when a plugin is disabled
	 *
	 * @param   array  $pks  A list of primary key ids of the content that has changed state.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	protected function pluginDisable($pks)
	{
		// Since multiple plugins may be disabled at a time, we need to check first
		// that we're handling the appropriate one for the context
		foreach ($pks as $pk)
		{
			if ($this->getPluginType($pk) == strtolower($this->context))
			{
				// Get all of the items to unindex them
				$query = clone $this->getStateQuery();
				$this->db->setQuery($query);
				$items = $this->db->loadColumn();

				// Remove each item
				foreach ($items as $item)
				{
					$this->remove($item);
				}
			}
		}
	}

	/**
	 * Method to translate the native content states into states that the
	 * indexer can use.
	 *
	 * @param   integer  $item      The item state.
	 * @param   integer  $category  The category state. [optional]
	 *
	 * @return  integer  The translated indexer state.
	 *
	 * @since   2.5
	 */
	protected function translateState($item, $category = null)
	{
		// If category is present, factor in its states as well
		if ($category !== null && $category == 0)
		{
			$item = 0;
		}

		// Translate the state
		switch ($item)
		{
			// Published and archived items only should return a published state
			case 1;
			case 2:
				return 1;

			// All other states should return an unpublished state
			default:
			case 0:
				return 0;
		}
	}
}
PKW|!]OB"d��indexer/parser.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Parser base class for the Finder indexer package.
 *
 * @since  2.5
 */
abstract class FinderIndexerParser
{
	/**
	 * Method to get a parser, creating it if necessary.
	 *
	 * @param   string  $format  The type of parser to load.
	 *
	 * @return  FinderIndexerParser  A FinderIndexerParser instance.
	 *
	 * @since   2.5
	 * @throws  Exception on invalid parser.
	 */
	public static function getInstance($format)
	{
		static $instances;

		// Only create one parser for each format.
		if (isset($instances[$format]))
		{
			return $instances[$format];
		}

		// Create an array of instances if necessary.
		if (!is_array($instances))
		{
			$instances = array();
		}

		// Setup the adapter for the parser.
		$format = JFilterInput::getInstance()->clean($format, 'cmd');
		$path = __DIR__ . '/parser/' . $format . '.php';
		$class = 'FinderIndexerParser' . ucfirst($format);

		// Check if a parser exists for the format.
		if (!file_exists($path))
		{
			// Throw invalid format exception.
			throw new Exception(JText::sprintf('COM_FINDER_INDEXER_INVALID_PARSER', $format));
		}

		// Instantiate the parser.
		JLoader::register($class, $path);
		$instances[$format] = new $class;

		return $instances[$format];
	}

	/**
	 * Method to parse input and extract the plain text. Because this method is
	 * called from both inside and outside the indexer, it needs to be able to
	 * batch out its parsing functionality to deal with the inefficiencies of
	 * regular expressions. We will parse recursively in 2KB chunks.
	 *
	 * @param   string  $input  The input to parse.
	 *
	 * @return  string  The plain text input.
	 *
	 * @since   2.5
	 */
	public function parse($input)
	{
		// If the input is less than 2KB we can parse it in one go.
		if (strlen($input) <= 2048)
		{
			return $this->process($input);
		}

		// Input is longer than 2Kb so parse it in chunks of 2Kb or less.
		$start = 0;
		$end = strlen($input);
		$chunk = 2048;
		$return = null;

		while ($start < $end)
		{
			// Setup the string.
			$string = substr($input, $start, $chunk);

			// Find the last space character if we aren't at the end.
			$ls = (($start + $chunk) < $end ? strrpos($string, ' ') : false);

			// Truncate to the last space character.
			if ($ls !== false)
			{
				$string = substr($string, 0, $ls);
			}

			// Adjust the start position for the next iteration.
			$start += ($ls !== false ? ($ls + 1 - $chunk) + $chunk : $chunk);

			// Parse the chunk.
			$return .= $this->process($string);
		}

		return $return;
	}

	/**
	 * Method to process input and extract the plain text.
	 *
	 * @param   string  $input  The input to process.
	 *
	 * @return  string  The plain text input.
	 *
	 * @since   2.5
	 */
	abstract protected function process($input);
}
PKW|!]ƣj�vvindexer/stemmer.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Stemmer base class for the Finder indexer package.
 *
 * @since  2.5
 */
abstract class FinderIndexerStemmer
{
	/**
	 * An internal cache of stemmed tokens.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public $cache = array();

	/**
	 * Method to get a stemmer, creating it if necessary.
	 *
	 * @param   string  $adapter  The type of stemmer to load.
	 *
	 * @return  FinderIndexerStemmer  A FinderIndexerStemmer instance.
	 *
	 * @since   2.5
	 * @throws  Exception on invalid stemmer.
	 */
	public static function getInstance($adapter)
	{
		static $instances;

		// Only create one stemmer for each adapter.
		if (isset($instances[$adapter]))
		{
			return $instances[$adapter];
		}

		// Create an array of instances if necessary.
		if (!is_array($instances))
		{
			$instances = array();
		}

		// Setup the adapter for the stemmer.
		$adapter = JFilterInput::getInstance()->clean($adapter, 'cmd');
		$path = __DIR__ . '/stemmer/' . $adapter . '.php';
		$class = 'FinderIndexerStemmer' . ucfirst($adapter);

		// Check if a stemmer exists for the adapter.
		if (!file_exists($path))
		{
			// Throw invalid adapter exception.
			throw new Exception(JText::sprintf('COM_FINDER_INDEXER_INVALID_STEMMER', $adapter));
		}

		// Instantiate the stemmer.
		JLoader::register($class, $path);
		$instances[$adapter] = new $class;

		return $instances[$adapter];
	}

	/**
	 * Method to stem a token and return the root.
	 *
	 * @param   string  $token  The token to stem.
	 * @param   string  $lang   The language of the token.
	 *
	 * @return  string  The root token.
	 *
	 * @since   2.5
	 */
	abstract public function stem($token, $lang);
}
PKW|!]�u�AC	C	
finder.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Helper class for Finder.
 *
 * @since  2.5
 */
class FinderHelper
{
	/**
	 * The extension name.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public static $extension = 'com_finder';

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_FINDER_SUBMENU_INDEX'),
			'index.php?option=com_finder&view=index',
			$vName === 'index'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_FINDER_SUBMENU_MAPS'),
			'index.php?option=com_finder&view=maps',
			$vName === 'maps'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_FINDER_SUBMENU_FILTERS'),
			'index.php?option=com_finder&view=filters',
			$vName === 'filters'
		);
	}

	/**
	 * Gets the finder system plugin extension id.
	 *
	 * @return  integer  The finder system plugin extension id.
	 *
	 * @since   3.6.0
	 */
	public static function getFinderPluginId()
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('extension_id'))
			->from($db->quoteName('#__extensions'))
			->where($db->quoteName('folder') . ' = ' . $db->quote('content'))
			->where($db->quoteName('element') . ' = ' . $db->quote('finder'));
		$db->setQuery($query);

		try
		{
			$result = (int) $db->loadResult();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());
		}

		return $result;
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject  A JObject containing the allowed actions.
	 *
	 * @since   2.5
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions()
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		return JHelperContent::getActions('com_finder');
	}
}
PKW|!]����language.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_finder
 *
 * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Finder language helper class.
 *
 * @since  2.5
 */
class FinderHelperLanguage
{
	/**
	 * Method to return a plural language code for a taxonomy branch.
	 *
	 * @param   string  $branchName  Branch title.
	 *
	 * @return  string  Language key code.
	 *
	 * @since   2.5
	 */
	public static function branchPlural($branchName)
	{
		$return = preg_replace('/[^a-zA-Z0-9]+/', '_', strtoupper($branchName));

		if ($return !== '_')
		{
			return 'PLG_FINDER_QUERY_FILTER_BRANCH_P_' . $return;
		}

		return $branchName;
	}

	/**
	 * Method to return a singular language code for a taxonomy branch.
	 *
	 * @param   string  $branchName  Branch name.
	 *
	 * @return  string  Language key code.
	 *
	 * @since   2.5
	 */
	public static function branchSingular($branchName)
	{
		$return = preg_replace('/[^a-zA-Z0-9]+/', '_', strtoupper($branchName));

		return 'PLG_FINDER_QUERY_FILTER_BRANCH_S_' . $return;
	}

	/**
	 * Method to return the language name for a language taxonomy branch.
	 *
	 * @param   string  $branchName  Language branch name.
	 *
	 * @return  string  The language title.
	 *
	 * @since   3.6.0
	 */
	public static function branchLanguageTitle($branchName)
	{
		$title = $branchName;

		if ($branchName === '*')
		{
			$title = JText::_('JALL_LANGUAGE');
		}
		else
		{
			$languages = JLanguageHelper::getLanguages('lang_code');

			if (isset($languages[$branchName]))
			{
				$title = $languages[$branchName]->title;
			}
		}

		return $title;
	}

	/**
	 * Method to load Smart Search component language file.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public static function loadComponentLanguage()
	{
		JFactory::getLanguage()->load('com_finder', JPATH_SITE);
	}

	/**
	 * Method to load Smart Search plugin language files.
	 *
	 * @return  void
	 *
	 * @since   2.5
	 */
	public static function loadPluginLanguage()
	{
		static $loaded = false;

		// If already loaded, don't load again.
		if ($loaded)
		{
			return;
		}

		$loaded = true;

		// Get array of all the enabled Smart Search plugin names.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select(array($db->qn('name'), $db->qn('element')))
			->from($db->quoteName('#__extensions'))
			->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
			->where($db->quoteName('folder') . ' = ' . $db->quote('finder'))
			->where($db->quoteName('enabled') . ' = 1');
		$db->setQuery($query);
		$plugins = $db->loadObjectList();

		if (empty($plugins))
		{
			return;
		}

		// Load generic language strings.
		$lang = JFactory::getLanguage();
		$lang->load('plg_content_finder', JPATH_ADMINISTRATOR);

		// Load language file for each plugin.
		foreach ($plugins as $plugin)
		{
			$lang->load($plugin->name, JPATH_ADMINISTRATOR)
				|| $lang->load($plugin->name, JPATH_PLUGINS . '/finder/' . $plugin->element);
		}
	}
}
PK[|!]���\#\#
search.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_search
 *
 * @copyright   (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\String\StringHelper;

/**
 * Search component helper.
 *
 * @since  1.5
 */
class SearchHelper
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		// Not required.
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject
	 *
	 * @deprecated  3.2  Use JHelperContent::getActions() instead.
	 */
	public static function getActions()
	{
		// Log usage of deprecated function.
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions.
		return JHelperContent::getActions('com_search');
	}

	/**
	 * Sanitise search word.
	 *
	 * @param   string  &$searchword   Search word to be sanitised.
	 * @param   string  $searchphrase  Either 'all', 'any' or 'exact'.
	 *
	 * @return  boolean  True if search word needs to be sanitised.
	 */
	public static function santiseSearchWord(&$searchword, $searchphrase)
	{
		$ignored = false;

		$lang          = JFactory::getLanguage();
		$tag           = $lang->getTag();
		$search_ignore = $lang->getIgnoredSearchWords();

		// Deprecated in 1.6 use $lang->getIgnoredSearchWords instead.
		$ignoreFile = JLanguageHelper::getLanguagePath() . '/' . $tag . '/' . $tag . '.ignore.php';

		if (file_exists($ignoreFile))
		{
			include $ignoreFile;
		}

		// Check for words to ignore.
		$aterms = explode(' ', StringHelper::strtolower($searchword));

		// First case is single ignored word.
		if (count($aterms) == 1 && in_array(StringHelper::strtolower($searchword), $search_ignore))
		{
			$ignored = true;
		}

		// Filter out search terms that are too small.
		$lower_limit = $lang->getLowerLimitSearchWord();

		foreach ($aterms as $aterm)
		{
			if (StringHelper::strlen($aterm) < $lower_limit)
			{
				$search_ignore[] = $aterm;
			}
		}

		// Next is to remove ignored words from type 'all' or 'any' (not exact) searches with multiple words.
		if (count($aterms) > 1 && $searchphrase != 'exact')
		{
			$pruned     = array_diff($aterms, $search_ignore);
			$searchword = implode(' ', $pruned);
		}

		return $ignored;
	}

	/**
	 * Does search word need to be limited?
	 *
	 * @param   string  &$searchword  Search word to be checked.
	 *
	 * @return  boolean  True if search word should be limited; false otherwise.
	 *
	 * @since  1.5
	 */
	public static function limitSearchWord(&$searchword)
	{
		$restriction = false;

		$lang = JFactory::getLanguage();

		// Limit searchword to a maximum of characters.
		$upper_limit = $lang->getUpperLimitSearchWord();

		if (StringHelper::strlen($searchword) > $upper_limit)
		{
			$searchword  = StringHelper::substr($searchword, 0, $upper_limit - 1);
			$restriction = true;
		}

		// Searchword must contain a minimum of characters.
		if ($searchword && StringHelper::strlen($searchword) < $lang->getLowerLimitSearchWord())
		{
			$searchword  = '';
			$restriction = true;
		}

		return $restriction;
	}

	/**
	 * Logs a search term.
	 *
	 * @param   string  $searchTerm  The term being searched.
	 *
	 * @return  void
	 *
	 * @since   1.5
	 * @deprecated  4.0  Use \Joomla\CMS\Helper\SearchHelper::logSearch() instead.
	 */
	public static function logSearch($searchTerm)
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use \Joomla\CMS\Helper\SearchHelper::logSearch() instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		\Joomla\CMS\Helper\SearchHelper::logSearch($searchTerm, 'com_search');
	}

	/**
	 * Prepares results from search for display.
	 *
	 * @param   string  $text        The source string.
	 * @param   string  $searchword  The searchword to select around.
	 *
	 * @return  string
	 *
	 * @since   1.5
	 */
	public static function prepareSearchContent($text, $searchword)
	{
		// Strips tags won't remove the actual jscript.
		$text = preg_replace("'<script[^>]*>.*?</script>'si", '', $text);
		$text = preg_replace('/{.+?}/', '', $text);

		// $text = preg_replace('/<a\s+.*?href="([^"]+)"[^>]*>([^<]+)<\/a>/is','\2', $text);

		// Replace line breaking tags with whitespace.
		$text = preg_replace("'<(br[^/>]*?/|hr[^/>]*?/|/(div|h[1-6]|li|p|td))>'si", ' ', $text);

		return self::_smartSubstr(strip_tags($text), $searchword);
	}

	/**
	 * Checks an object for search terms (after stripping fields of HTML).
	 *
	 * @param   object  $object      The object to check.
	 * @param   string  $searchTerm  Search words to check for.
	 * @param   array   $fields      List of object variables to check against.
	 *
	 * @return  boolean True if searchTerm is in object, false otherwise.
	 */
	public static function checkNoHtml($object, $searchTerm, $fields)
	{
		$searchRegex = array(
			'#<script[^>]*>.*?</script>#si',
			'#<style[^>]*>.*?</style>#si',
			'#<!.*?(--|]])>#si',
			'#<[^>]*>#i'
		);
		$terms = explode(' ', $searchTerm);

		if (empty($fields))
		{
			return false;
		}

		foreach ($fields as $field)
		{
			if (!isset($object->$field))
			{
				continue;
			}

			$text = self::remove_accents($object->$field);

			foreach ($searchRegex as $regex)
			{
				$text = preg_replace($regex, '', $text);
			}

			foreach ($terms as $term)
			{
				$term = self::remove_accents($term);

				if (StringHelper::stristr($text, $term) !== false)
				{
					return true;
				}
			}
		}

		return false;
	}

	/**
	 * Transliterates given text to ASCII.
	 *
	 * @param   string  $str  String to remove accents from.
	 *
	 * @return  string
	 *
	 * @since   3.2
	 */
	public static function remove_accents($str)
	{
		$str = JLanguageTransliterate::utf8_latin_to_ascii($str);

		// @TODO: remove other prefixes as well?
		return preg_replace("/[\"'^]([a-z])/ui", '\1', $str);
	}

	/**
	 * Returns substring of characters around a searchword.
	 *
	 * @param   string   $text        The source string.
	 * @param   integer  $searchword  Number of chars to return.
	 *
	 * @return  string
	 *
	 * @since   1.5
	 */
	public static function _smartSubstr($text, $searchword)
	{
		$lang        = JFactory::getLanguage();
		$length      = $lang->getSearchDisplayedCharactersNumber();
		$ltext       = self::remove_accents($text);
		$textlen     = StringHelper::strlen($ltext);
		$lsearchword = StringHelper::strtolower(self::remove_accents($searchword));
		$wordfound   = false;
		$pos         = 0;
		$length      = $length > $textlen ? $textlen : $length;

		while ($wordfound === false && $pos + $length < $textlen)
		{
			if (($wordpos = @StringHelper::strpos($ltext, ' ', $pos + $length)) !== false)
			{
				$chunk_size = $wordpos - $pos;
			}
			else
			{
				$chunk_size = $length;
			}

			$chunk     = StringHelper::substr($ltext, $pos, $chunk_size);
			$wordfound = StringHelper::strpos(StringHelper::strtolower($chunk), $lsearchword);

			if ($wordfound === false)
			{
				$pos += $chunk_size + 1;
			}
		}

		if ($wordfound !== false)
		{
			// Check if original text is different length than searched text (changed by function self::remove_accents)
			// Displayed text only, adjust $chunk_size
			if ($pos === 0)
			{
				$iOriLen = StringHelper::strlen(StringHelper::substr($text, 0, $pos + $chunk_size));
				$iModLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, 0, $pos + $chunk_size)));

				$chunk_size += $iOriLen - $iModLen;
			}
			else
			{
				$iOriSkippedLen = StringHelper::strlen(StringHelper::substr($text, 0, $pos));
				$iModSkippedLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, 0, $pos)));

				// Adjust starting position $pos
				if ($iOriSkippedLen !== $iModSkippedLen)
				{
					$pos += $iOriSkippedLen - $iModSkippedLen;
				}

				$iOriReturnLen = StringHelper::strlen(StringHelper::substr($text, $pos, $chunk_size));
				$iModReturnLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, $pos, $chunk_size)));

				if ($iOriReturnLen !== $iModReturnLen)
				{
					$chunk_size += $iOriReturnLen - $iModReturnLen;
				}
			}

			$sPre = $pos > 0 ? '...&#160;' : '';
			$sPost = ($pos + $chunk_size) >= StringHelper::strlen($text) ? '' : '&#160;...';

			return $sPre . StringHelper::substr($text, $pos, $chunk_size) . $sPost;
		}
		else
		{
			if (($mbtextlen = StringHelper::strlen($text)) < $length)
			{
				$length = $mbtextlen;
			}

			if (($wordpos = StringHelper::strpos($text, ' ', $length)) !== false)
			{
				return StringHelper::substr($text, 0, $wordpos) . '&#160;...';
			}
			else
			{
				return StringHelper::substr($text, 0, $length);
			}
		}
	}
}
PK[|!]'˂��site.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_search
 *
 * @copyright   (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Mock JSite class used to fool the frontend search plugins because they route the results.
 *
 * @since  1.5
 */
class JSite extends JObject
{
	/**
	 * False method to fool the frontend search plugins.
	 *
	 * @return  JSite
	 *
	 * @since  1.5
	 */
	public function getMenu()
	{
		$result = new JSite;

		return $result;
	}

	/**
	 * False method to fool the frontend search plugins.
	 *
	 * @return  array
	 *
	 * @since  1.5
	 */
	public function getItems()
	{
		return array();
	}
}
PK\|!]c����joomlaupdate.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_joomlaupdate
 *
 * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Joomla! update helper.
 *
 * @since  2.5.4
 */
class JoomlaupdateHelper
{
	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject
	 *
	 * @since	2.5.4
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions()
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		return JHelperContent::getActions('com_joomlaupdate');
	}
}
PK\|!]��CK��
select.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_joomlaupdate
 *
 * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Joomla! update selection list helper.
 *
 * @since  2.5.4
 */
class JoomlaupdateHelperSelect
{
	/**
	 * Returns an HTML select element with the different extraction modes
	 *
	 * @param   string  $default  The default value of the select element
	 * @param   string  $name     The name of the form field
	 * @param   string  $id       The id of the select field
	 *
	 * @return  string
	 *
	 * @since   2.5.4
	 */
	public static function getMethods($default = 'hybrid', $name = 'method', $id = 'extraction_method')
	{
		$options = array();
		$options[] = JHtml::_('select.option', 'direct', JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_METHOD_DIRECT'));
		$options[] = JHtml::_('select.option', 'hybrid', JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_METHOD_HYBRID'));
		$options[] = JHtml::_('select.option', 'ftp', JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_METHOD_FTP'));

		return JHtml::_('select.genericlist', $options, $name, '', 'value', 'text', $default, $id);
	}
}
PK`|!]�E�-�
�
html/messages.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_messages
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * JHtml administrator messages class.
 *
 * @since  1.6
 */
class JHtmlMessages
{
	/**
	 * Get the HTML code of the state switcher
	 *
	 * @param   int      $value      The state value
	 * @param   int      $i          Row number
	 * @param   boolean  $canChange  Can the user change the state?
	 *
	 * @return  string
	 *
	 * @since   1.6
	 *
	 * @deprecated  4.0  Use JHtmlMessages::status() instead
	 */
	public static function state($value = 0, $i = 0, $canChange = false)
	{
		// Log deprecated message
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHtmlMessages::status() instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Note: $i is required but has to be an optional argument in the function call due to argument order
		if (null === $i)
		{
			throw new InvalidArgumentException('$i is a required argument in JHtmlMessages::state');
		}

		// Note: $canChange is required but has to be an optional argument in the function call due to argument order
		if (null === $canChange)
		{
			throw new InvalidArgumentException('$canChange is a required argument in JHtmlMessages::state');
		}

		return static::status($i, $value, $canChange);
	}

	/**
	 * Get the HTML code of the state switcher
	 *
	 * @param   int      $i          Row number
	 * @param   int      $value      The state value
	 * @param   boolean  $canChange  Can the user change the state?
	 *
	 * @return  string
	 *
	 * @since   3.4
	 */
	public static function status($i, $value = 0, $canChange = false)
	{
		// Array of image, task, title, action.
		$states = array(
			-2 => array('trash', 'messages.unpublish', 'JTRASHED', 'COM_MESSAGES_MARK_AS_UNREAD'),
			1  => array('publish', 'messages.unpublish', 'COM_MESSAGES_OPTION_READ', 'COM_MESSAGES_MARK_AS_UNREAD'),
			0  => array('unpublish', 'messages.publish', 'COM_MESSAGES_OPTION_UNREAD', 'COM_MESSAGES_MARK_AS_READ'),
		);

		$state = ArrayHelper::getValue($states, (int) $value, $states[0]);
		$icon  = $state[0];

		if ($canChange)
		{
			$html = '<a href="#" onclick="return listItemTask(\'cb' . $i . '\',\'' . $state[1] . '\')" class="btn btn-micro hasTooltip'
				. ($value == 1 ? ' active' : '') . '" title="' . JHtml::_('tooltipText', $state[3])
				. '"><span class="icon-' . $icon . '" aria-hidden="true"></span></a>';
		}

		return $html;
	}
}
PK`|!]6-llmessages.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_messages
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Messages helper class.
 *
 * @since  1.6
 */
class MessagesHelper
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_MESSAGES_ADD'),
			'index.php?option=com_messages&view=message&layout=edit',
			$vName == 'message'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_MESSAGES_READ'),
			'index.php?option=com_messages',
			$vName == 'messages'
		);
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject
	 *
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions()
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		return JHelperContent::getActions('com_messages');
	}

	/**
	 * Get a list of filter options for the state of a module.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   1.6
	 */
	public static function getStateOptions()
	{
		// Build the filter options.
		$options   = array();
		$options[] = JHtml::_('select.option', '1', JText::_('COM_MESSAGES_OPTION_READ'));
		$options[] = JHtml::_('select.option', '0', JText::_('COM_MESSAGES_OPTION_UNREAD'));
		$options[] = JHtml::_('select.option', '-2', JText::_('JTRASHED'));

		return $options;
	}
}
PK�|!](��	�	html/newsfeed.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_newsfeeds
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('NewsfeedsHelper', JPATH_ADMINISTRATOR . '/components/com_newsfeeds/helpers/newsfeeds.php');

/**
 * Utility class for creating HTML Grids.
 *
 * @since  1.5
 */
class JHtmlNewsfeed
{
	/**
	 * Get the associated language flags
	 *
	 * @param   int  $newsfeedid  The item id to search associations
	 *
	 * @return  string  The language HTML
	 *
	 * @throws  Exception  Throws a 500 Exception on Database failure
	 */
	public static function association($newsfeedid)
	{
		// Defaults
		$html = '';

		// Get the associations
		if ($associations = JLanguageAssociations::getAssociations('com_newsfeeds', '#__newsfeeds', 'com_newsfeeds.item', $newsfeedid))
		{
			foreach ($associations as $tag => $associated)
			{
				$associations[$tag] = (int) $associated->id;
			}

			// Get the associated newsfeed items
			$db = JFactory::getDbo();
			$query = $db->getQuery(true)
				->select('c.id, c.name as title')
				->select('l.sef as lang_sef, lang_code')
				->from('#__newsfeeds as c')
				->select('cat.title as category_title')
				->join('LEFT', '#__categories as cat ON cat.id=c.catid')
				->where('c.id IN (' . implode(',', array_values($associations)) . ')')
				->where('c.id != ' . $newsfeedid)
				->join('LEFT', '#__languages as l ON c.language=l.lang_code')
				->select('l.image')
				->select('l.title as language_title');
			$db->setQuery($query);

			try
			{
				$items = $db->loadObjectList('id');
			}
			catch (RuntimeException $e)
			{
				throw new Exception($e->getMessage(), 500);
			}

			if ($items)
			{
				foreach ($items as &$item)
				{
					$text = strtoupper($item->lang_sef);
					$url = JRoute::_('index.php?option=com_newsfeeds&task=newsfeed.edit&id=' . (int) $item->id);
					$tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '<br />' . JText::sprintf('JCATEGORY_SPRINTF', $item->category_title);
					$classes = 'hasPopover label label-association label-' . $item->lang_sef;

					$item->link = '<a href="' . $url . '" title="' . $item->language_title . '" class="' . $classes
						. '" data-content="' . $tooltip . '" data-placement="top">'
						. $text . '</a>';
				}
			}

			JHtml::_('bootstrap.popover');

			$html = JLayoutHelper::render('joomla.content.associations', $items);
		}

		return $html;
	}
}
PK�|!]I�����
newsfeeds.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_newsfeeds
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Newsfeeds component helper.
 *
 * @since  1.6
 */
class NewsfeedsHelper extends JHelperContent
{
	public static $extension = 'com_newsfeeds';

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_NEWSFEEDS_SUBMENU_NEWSFEEDS'),
			'index.php?option=com_newsfeeds&view=newsfeeds',
			$vName == 'newsfeeds'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_NEWSFEEDS_SUBMENU_CATEGORIES'),
			'index.php?option=com_categories&extension=com_newsfeeds',
			$vName == 'categories'
		);
	}

	/**
	 * Adds Count Items for Category Manager.
	 *
	 * @param   stdClass[]  &$items  The category objects
	 *
	 * @return  stdClass[]
	 *
	 * @since   3.5
	 */
	public static function countItems(&$items)
	{
		$config = (object) array(
			'related_tbl'   => 'newsfeeds',
			'state_col'     => 'published',
			'group_col'     => 'catid',
			'relation_type' => 'category_or_group',
		);

		return parent::countRelations($items, $config);
	}

	/**
	 * Adds Count Items for Tag Manager.
	 *
	 * @param   stdClass[]  &$items     The tag objects
	 * @param   string      $extension  The name of the active view.
	 *
	 * @return  stdClass[]
	 *
	 * @since   3.6
	 */
	public static function countTagItems(&$items, $extension)
	{
		$parts   = explode('.', $extension);
		$section = count($parts) > 1 ? $parts[1] : null;

		$config = (object) array(
			'related_tbl'   => ($section === 'category' ? 'categories' : 'newsfeeds'),
			'state_col'     => 'published',
			'group_col'     => 'tag_id',
			'extension'     => $extension,
			'relation_type' => 'tag_assigments',
		);

		return parent::countRelations($items, $config);
	}
}
PK�|!]v�@�
�
associations.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_content
 *
 * @copyright   (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Association\AssociationExtensionHelper;

/**
 * Content associations helper.
 *
 * @since  3.7.0
 */
class ContentAssociationsHelper extends AssociationExtensionHelper
{
	/**
	 * The extension name
	 *
	 * @var     array   $extension
	 *
	 * @since   3.7.0
	 */
	protected $extension = 'com_content';

	/**
	 * Array of item types
	 *
	 * @var     array   $itemTypes
	 *
	 * @since   3.7.0
	 */
	protected $itemTypes = array('article', 'category');

	/**
	 * Has the extension association support
	 *
	 * @var     boolean   $associationsSupport
	 *
	 * @since   3.7.0
	 */
	protected $associationsSupport = true;

	/**
	 * Get the associated items for an item
	 *
	 * @param   string  $typeName  The item type
	 * @param   int     $id        The id of item for which we need the associated items
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public function getAssociations($typeName, $id)
	{
		$type = $this->getType($typeName);

		$context    = $this->extension . '.item';
		$catidField = 'catid';

		if ($typeName === 'category')
		{
			$context    = 'com_categories.item';
			$catidField = '';
		}

		// Get the associations.
		$associations = JLanguageAssociations::getAssociations(
			$this->extension,
			$type['tables']['a'],
			$context,
			$id,
			'id',
			'alias',
			$catidField
		);

		return $associations;
	}

	/**
	 * Get item information
	 *
	 * @param   string  $typeName  The item type
	 * @param   int     $id        The id of item for which we need the associated items
	 *
	 * @return  JTable|null
	 *
	 * @since   3.7.0
	 */
	public function getItem($typeName, $id)
	{
		if (empty($id))
		{
			return null;
		}

		$table = null;

		switch ($typeName)
		{
			case 'article':
				$table = JTable::getInstance('Content');
				break;

			case 'category':
				$table = JTable::getInstance('Category');
				break;
		}

		if (is_null($table))
		{
			return null;
		}

		$table->load($id);

		return $table;
	}

	/**
	 * Get information about the type
	 *
	 * @param   string  $typeName  The item type
	 *
	 * @return  array  Array of item types
	 *
	 * @since   3.7.0
	 */
	public function getType($typeName = '')
	{
		$fields  = $this->getFieldsTemplate();
		$tables  = array();
		$joins   = array();
		$support = $this->getSupportTemplate();
		$title   = '';

		if (in_array($typeName, $this->itemTypes))
		{
			switch ($typeName)
			{
				case 'article':

					$support['state'] = true;
					$support['acl'] = true;
					$support['checkout'] = true;
					$support['category'] = true;
					$support['save2copy'] = true;

					$tables = array(
						'a' => '#__content'
					);

					$title = 'article';
					break;

				case 'category':
					$fields['created_user_id'] = 'a.created_user_id';
					$fields['ordering'] = 'a.lft';
					$fields['level'] = 'a.level';
					$fields['catid'] = '';
					$fields['state'] = 'a.published';

					$support['state'] = true;
					$support['acl'] = true;
					$support['checkout'] = true;
					$support['level'] = true;

					$tables = array(
						'a' => '#__categories'
					);

					$title = 'category';
					break;
			}
		}

		return array(
			'fields'  => $fields,
			'support' => $support,
			'tables'  => $tables,
			'joins'   => $joins,
			'title'   => $title
		);
	}
}
PK�|!]k�+m"m"icagenda.phpnu&1i�<?php
/**
 *------------------------------------------------------------------------------
 *  iCagenda v3 by Jooml!C - Events Management Extension for Joomla! 2.5 / 3.x
 *------------------------------------------------------------------------------
 * @package     com_icagenda
 * @copyright   Copyright (c)2012-2015 Cyril Rezé, Jooml!C - All rights reserved
 *
 * @license     GNU General Public License version 3 or later; see LICENSE.txt
 * @author      Cyril Rezé (Lyr!C)
 * @link        http://www.joomlic.com
 *
 * @version     3.4.0 2014-07-02
 * @since       1.0
 *------------------------------------------------------------------------------
*/

// No direct access to this file
defined('_JEXEC') or die();

// Access check.
if (!JFactory::getUser()->authorise('core.manage', 'com_icagenda')) {
	return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
}

/**
 * iCagenda helper.
 */
class iCagendaHelper
{
	/**
	 * Configure the Linkbar.
	 */
	public static function addSubmenu($submenu)
	{
		if(version_compare(JVERSION, '3.0', 'lt'))
		{
			JSubMenuHelper::addEntry(
				JText::_('COM_ICAGENDA_TITLE_ICAGENDA'),
				'index.php?option=com_icagenda&view=icagenda',
				$submenu == 'icagenda'
			);
			if (JFactory::getUser()->authorise('icagenda.access.categories', 'com_icagenda'))
			{
				JSubMenuHelper::addEntry(
					JText::_('COM_ICAGENDA_TITLE_CATEGORIES'),
					'index.php?option=com_icagenda&view=categories',
					$submenu == 'categories'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.events', 'com_icagenda'))
			{
				JSubMenuHelper::addEntry(
					JText::_('COM_ICAGENDA_TITLE_EVENTS'),
					'index.php?option=com_icagenda&view=events',
					$submenu == 'events'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.registrations', 'com_icagenda'))
			{
				JSubMenuHelper::addEntry(
					JText::_('COM_ICAGENDA_TITLE_REGISTRATION'),
					'index.php?option=com_icagenda&view=registrations',
					$submenu == 'registrations'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.newsletter', 'com_icagenda'))
			{
				JSubMenuHelper::addEntry(
					JText::_('COM_ICAGENDA_TITLE_NEWSLETTER'),
					'index.php?option=com_icagenda&view=mail&layout=edit',
					$submenu == 'newsletter'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.customfields', 'com_icagenda'))
			{
				JSubMenuHelper::addEntry(
					JText::_('COM_ICAGENDA_TITLE_CUSTOMFIELDS'),
					'index.php?option=com_icagenda&view=customfields',
					$submenu == 'customfields'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.features', 'com_icagenda'))
			{
				JSubMenuHelper::addEntry(
					JText::_('COM_ICAGENDA_TITLE_FEATURES'),
					'index.php?option=com_icagenda&view=features',
					$submenu == 'features'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.themes', 'com_icagenda'))
			{
				JSubMenuHelper::addEntry(
					JText::_('COM_ICAGENDA_THEMES'),
					'index.php?option=com_icagenda&view=themes',
					$submenu == 'themes'
				);
			}
			JSubMenuHelper::addEntry(
				JText::_('COM_ICAGENDA_INFO'),
				'index.php?option=com_icagenda&view=info',
				$submenu == 'info'
			);

			$document = JFactory::getDocument();

			/**
			 * Set Titles iCagenda
			 */
			if ($submenu == 'icagenda')
			{
				$document->setTitle(JText::_('COM_ICAGENDA'));
			}
			if ($submenu == 'categories')
			{
				$document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_CATEGORIES'));
			}
			if ($submenu == 'events')
			{
				$document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_EVENTS'));
			}
			if ($submenu == 'registrations')
			{
				$document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_REGISTRATION'));
			}
			if ($submenu == 'newsletter')
			{
				$document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_NEWSLETTER'));
			}
			if ($submenu == 'customfields')
			{
				$document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_CUSTOMFIELDS'));
			}
			if ($submenu == 'features')
			{
				$document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_FEATURES'));
			}
			if ($submenu == 'themes')
			{
				$document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_THEMES'));
			}
			if ($submenu == 'info')
			{
				$document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_INFO'));
			}

			$document->addStyleDeclaration('
				.icon48icagenda{background: url(../media/com_icagenda/images/XXX.png);}
				.icon-48-events {background: url(../media/com_icagenda/images/all_events-48.png) no-repeat;}
				.icon-48-event {background: url(../media/com_icagenda/images/new_event-48.png) no-repeat;}
				.icon-48-registration {background: url(../media/com_icagenda/images/registration-48.png) no-repeat;}
				.icon-48-categories {background: url(../media/com_icagenda/images/all_cats-48.png) no-repeat;}
				.icon-48-category {background: url(../media/com_icagenda/images/new_cat-48.png) no-repeat;}
				.icon-48-generic {background: url(../media/com_icagenda/images/iconicagenda48.png) no-repeat;}
				.icon-48-mail {background: url(../media/com_icagenda/images/newsletter-48.png) no-repeat;}
				.icon-48-themes {background: url(../media/com_icagenda/images/themes-48.png) no-repeat;}
				.icon-48-customfields {background: url(../media/com_icagenda/images/customfields-48.png) no-repeat;}
				.icon-48-info {background: url(../media/com_icagenda/images/info-48.png) no-repeat;}
			');
		}
		else
		{
			JHtmlSidebar::addEntry(
				JText::_('COM_ICAGENDA_TITLE_ICAGENDA'),
				'index.php?option=com_icagenda&view=icagenda',
				$submenu == 'icagenda'
			);
			if (JFactory::getUser()->authorise('icagenda.access.categories', 'com_icagenda'))
			{
				JHtmlSidebar::addEntry(
					JText::_('COM_ICAGENDA_TITLE_CATEGORIES'),
					'index.php?option=com_icagenda&view=categories',
					$submenu == 'categories'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.events', 'com_icagenda'))
			{
				JHtmlSidebar::addEntry(
					JText::_('COM_ICAGENDA_TITLE_EVENTS'),
					'index.php?option=com_icagenda&view=events',
					$submenu == 'events'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.registrations', 'com_icagenda'))
			{
				JHtmlSidebar::addEntry(
					JText::_('COM_ICAGENDA_TITLE_REGISTRATION'),
					'index.php?option=com_icagenda&view=registrations',
					$submenu == 'registrations'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.newsletter', 'com_icagenda'))
			{
				JHtmlSidebar::addEntry(
					JText::_('COM_ICAGENDA_TITLE_NEWSLETTER'),
					'index.php?option=com_icagenda&view=mail&layout=edit',
					$submenu == 'newsletter'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.customfields', 'com_icagenda'))
			{
				JHtmlSidebar::addEntry(
					JText::_('COM_ICAGENDA_TITLE_CUSTOMFIELDS'),
					'index.php?option=com_icagenda&view=customfields',
					$submenu == 'customfields'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.features', 'com_icagenda'))
			{
				JHtmlSidebar::addEntry(
					JText::_('COM_ICAGENDA_TITLE_FEATURES'),
					'index.php?option=com_icagenda&view=features',
					$submenu == 'features'
				);
			}
			if (JFactory::getUser()->authorise('icagenda.access.themes', 'com_icagenda'))
			{
				JHtmlSidebar::addEntry(
					JText::_('COM_ICAGENDA_THEMES'),
					'index.php?option=com_icagenda&view=themes',
					$submenu == 'themes'
				);
			}
			JHtmlSidebar::addEntry(
				JText::_('COM_ICAGENDA_INFO'),
				'index.php?option=com_icagenda&view=info',
				$submenu == 'info'
			);
		}
	}

	/**
	 * Gets a list of the actions that can be performed.
	 */
	public static function getActions($messageId = 0)
	{
		$user   = JFactory::getUser();
		$result = new JObject;

		if (empty($messageId))
		{
			$assetName = 'com_icagenda';
		}
		else
		{
			$assetName = 'com_icagenda.message.'.(int) $messageId;
		}

		$actions = array(
			'core.admin',
			'core.manage',
			'core.create',
			'core.edit',
			'core.delete',
			'core.edit.state',
			'core.edit.own',
			'icagenda.access.categories',
			'icagenda.access.events',
			'icagenda.access.registrations',
			'icagenda.access.newsletter',
			'icagenda.access.customfields',
			'icagenda.access.features',
			'icagenda.access.themes'
		);

		foreach ($actions as $action)
		{
			$result->set($action, $user->authorise($action, $assetName));
		}

		return $result;
	}

	/**
	 * Tests whether a string is serialized before attempting to unserialize it
	 *
	 * ( TO BE REMOVED WHEN ALL CALLS FROM IC LIBRARY !!! )
	 */
	public static function isSerialized($str)
	{
		return ($str == serialize(false) || @unserialize($str) !== false);
	}
}
PK�|!]
:i��html/events.phpnu&1i�<?php
/**
 *------------------------------------------------------------------------------
 *  iCagenda v3 by Jooml!C - Events Management Extension for Joomla! 2.5 / 3.x
 *------------------------------------------------------------------------------
 * @package     com_icagenda
 * @copyright   Copyright (c)2012-2015 Cyril Rezé, Jooml!C - All rights reserved
 *
 * @license     GNU General Public License version 3 or later; see LICENSE.txt
 * @author      Cyril Rezé (Lyr!C)
 * @link        http://www.joomlic.com
 *
 * @version     3.1.10 2013-09-11
 * @since       3.2
 *------------------------------------------------------------------------------
*/

// No direct access to this file
defined('_JEXEC') or die();

/**
 * Extended Utility class for the iCagenda component.
 *
 * @package     Joomla.Administrator
 * @subpackage  com_iCagenda
 * @since       3.2
 */
class JHtmlEvents
{

	public static function approveEvents()
	{
		$states = array(
			1	=> array(
				'img'				=> 'tick.png',
				'task'				=> 'approve',
				'text'				=> '',
				'active_title'		=> 'COM_ICAGENDA_TOOLBAR_APPROVE',
				'inactive_title'	=> '',
				'tip'				=> true,
				'active_class'		=> 'unpublish',
				'inactive_class'	=> 'unpublish'
			),
			0	=> array(
				'img'				=> 'publish_x.png',
				'task'				=> '',
				'text'				=> '',
				'active_title'		=> '',
				'inactive_title'	=> 'COM_ICAGENDA_APPROVED',
				'tip'				=> true,
				'active_class'		=> 'publish',
				'inactive_class'	=> 'publish'
			)
		);
		return $states;
	}
}
PK�|!]�6�html/index.htmlnu&1i�<!DOCTYPE html><title></title>PKw}!]X�1�7�7html/filter.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;

JLoader::register('FinderHelperLanguage', JPATH_ADMINISTRATOR . '/components/com_finder/helpers/language.php');

/**
 * Filter HTML Behaviors for Finder.
 *
 * @since  2.5
 */
abstract class JHtmlFilter
{
	/**
	 * Method to generate filters using the slider widget and decorated
	 * with the FinderFilter JavaScript behaviors.
	 *
	 * @param   array  $options  An array of configuration options. [optional]
	 *
	 * @return  mixed  A rendered HTML widget on success, null otherwise.
	 *
	 * @since   2.5
	 */
	public static function slider($options = array())
	{
		$db     = JFactory::getDbo();
		$query  = $db->getQuery(true);
		$user   = JFactory::getUser();
		$groups = implode(',', $user->getAuthorisedViewLevels());
		$html   = '';
		$filter = null;

		// Get the configuration options.
		$filterId    = array_key_exists('filter_id', $options) ? $options['filter_id'] : null;
		$activeNodes = array_key_exists('selected_nodes', $options) ? $options['selected_nodes'] : array();
		$classSuffix = array_key_exists('class_suffix', $options) ? $options['class_suffix'] : '';

		// Load the predefined filter if specified.
		if (!empty($filterId))
		{
			$query->select('f.data, f.params')
				->from($db->quoteName('#__finder_filters') . ' AS f')
				->where('f.filter_id = ' . (int) $filterId);

			// Load the filter data.
			$db->setQuery($query);

			try
			{
				$filter = $db->loadObject();
			}
			catch (RuntimeException $e)
			{
				return null;
			}

			// Initialize the filter parameters.
			if ($filter)
			{
				$filter->params = new Registry($filter->params);
			}
		}

		// Build the query to get the branch data and the number of child nodes.
		$query->clear()
			->select('t.*, count(c.id) AS children')
			->from($db->quoteName('#__finder_taxonomy') . ' AS t')
			->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id')
			->where('t.parent_id = 1')
			->where('t.state = 1')
			->where('t.access IN (' . $groups . ')')
			->group('t.id, t.parent_id, t.state, t.access, t.ordering, t.title, c.parent_id')
			->order('t.ordering, t.title');

		// Limit the branch children to a predefined filter.
		if ($filter)
		{
			$query->where('c.id IN(' . $filter->data . ')');
		}

		// Load the branches.
		$db->setQuery($query);

		try
		{
			$branches = $db->loadObjectList('id');
		}
		catch (RuntimeException $e)
		{
			return null;
		}

		// Check that we have at least one branch.
		if (count($branches) === 0)
		{
			return null;
		}

		$branch_keys = array_keys($branches);
		$html .= JHtml::_('bootstrap.startAccordion', 'accordion', array('parent' => true, 'active' => 'accordion-' . $branch_keys[0])
		);

		// Load plugin language files.
		FinderHelperLanguage::loadPluginLanguage();

		// Iterate through the branches and build the branch groups.
		foreach ($branches as $bk => $bv)
		{
			// If the multi-lang plugin is enabled then drop the language branch.
			if ($bv->title === 'Language' && JLanguageMultilang::isEnabled())
			{
				continue;
			}

			// Build the query to get the child nodes for this branch.
			$query->clear()
				->select('t.*')
				->from($db->quoteName('#__finder_taxonomy') . ' AS t')
				->where('t.parent_id = ' . (int) $bk)
				->where('t.state = 1')
				->where('t.access IN (' . $groups . ')')
				->order('t.ordering, t.title');

			// Self-join to get the parent title.
			$query->select('e.title AS parent_title')
				->join('LEFT', $db->quoteName('#__finder_taxonomy', 'e') . ' ON ' . $db->quoteName('e.id') . ' = ' . $db->quoteName('t.parent_id'));

			// Load the branches.
			$db->setQuery($query);

			try
			{
				$nodes = $db->loadObjectList('id');
			}
			catch (RuntimeException $e)
			{
				return null;
			}

			// Translate node titles if possible.
			$lang = JFactory::getLanguage();

			foreach ($nodes as $nk => $nv)
			{
				if (trim($nv->parent_title, '**') === 'Language')
				{
					$title = FinderHelperLanguage::branchLanguageTitle($nv->title);
				}
				else
				{
					$key = FinderHelperLanguage::branchPlural($nv->title);
					$title = $lang->hasKey($key) ? JText::_($key) : $nv->title;
				}

				$nodes[$nk]->title = $title;
			}

			// Adding slides
			$html .= JHtml::_('bootstrap.addSlide',
				'accordion',
				JText::sprintf('COM_FINDER_FILTER_BRANCH_LABEL',
					JText::_(FinderHelperLanguage::branchSingular($bv->title)) . ' - ' . count($nodes)
				),
				'accordion-' . $bk
			);

			// Populate the toggle button.
			$html .= '<button class="btn jform-rightbtn" type="button" onclick="jQuery(\'[id=&quot;tax-'
				. $bk . '&quot;]\').each(function(){this.click();});"><span class="icon-checkbox-partial"></span> '
				. JText::_('JGLOBAL_SELECTION_INVERT') . '</button><hr/>';

			// Populate the group with nodes.
			foreach ($nodes as $nk => $nv)
			{
				// Determine if the node should be checked.
				$checked = in_array($nk, $activeNodes) ? ' checked="checked"' : '';

				// Build a node.
				$html .= '<div class="control-group">';
				$html .= '<div class="controls">';
				$html .= '<label class="checkbox">';
				$html .= '<input type="checkbox" class="selector filter-node' . $classSuffix . '" value="' . $nk . '" name="t[]" id="tax-'
					. $bk . '"' . $checked . ' />';
				$html .= $nv->title;
				$html .= '</label>';
				$html .= '</div>';
				$html .= '</div>';
			}

			$html .= JHtml::_('bootstrap.endSlide');
		}

		$html .= JHtml::_('bootstrap.endAccordion');

		return $html;
	}

	/**
	 * Method to generate filters using select box dropdown controls.
	 *
	 * @param   FinderIndexerQuery  $idxQuery  A FinderIndexerQuery object.
	 * @param   array               $options   An array of options.
	 *
	 * @return  mixed  A rendered HTML widget on success, null otherwise.
	 *
	 * @since   2.5
	 */
	public static function select($idxQuery, $options)
	{
		$user   = JFactory::getUser();
		$groups = implode(',', $user->getAuthorisedViewLevels());
		$filter = null;

		// Get the configuration options.
		$classSuffix = $options->get('class_suffix', null);
		$showDates   = $options->get('show_date_filters', false);

		// Try to load the results from cache.
		$cache   = JFactory::getCache('com_finder', '');
		$cacheId = 'filter_select_' . serialize(array($idxQuery->filter, $options, $groups, JFactory::getLanguage()->getTag()));

		// Check the cached results.
		if ($cache->contains($cacheId))
		{
			$branches = $cache->get($cacheId);
		}
		else
		{
			$db    = JFactory::getDbo();
			$query = $db->getQuery(true);

			// Load the predefined filter if specified.
			if (!empty($idxQuery->filter))
			{
				$query->select('f.data, ' . $db->quoteName('f.params'))
					->from($db->quoteName('#__finder_filters') . ' AS f')
					->where('f.filter_id = ' . (int) $idxQuery->filter);

				// Load the filter data.
				$db->setQuery($query);

				try
				{
					$filter = $db->loadObject();
				}
				catch (RuntimeException $e)
				{
					return null;
				}

				// Initialize the filter parameters.
				if ($filter)
				{
					$filter->params = new Registry($filter->params);
				}
			}

			// Build the query to get the branch data and the number of child nodes.
			$query->clear()
				->select('t.*, count(c.id) AS children')
				->from($db->quoteName('#__finder_taxonomy') . ' AS t')
				->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id')
				->where('t.parent_id = 1')
				->where('t.state = 1')
				->where('t.access IN (' . $groups . ')')
				->where('c.state = 1')
				->where('c.access IN (' . $groups . ')')
				->group($db->quoteName('t.id'))
				->order('t.ordering, t.title');

			// Limit the branch children to a predefined filter.
			if (!empty($filter->data))
			{
				$query->where('c.id IN(' . $filter->data . ')');
			}

			// Load the branches.
			$db->setQuery($query);

			try
			{
				$branches = $db->loadObjectList('id');
			}
			catch (RuntimeException $e)
			{
				return null;
			}

			// Check that we have at least one branch.
			if (count($branches) === 0)
			{
				return null;
			}

			// Iterate through the branches and build the branch groups.
			foreach ($branches as $bk => $bv)
			{
				// If the multi-lang plugin is enabled then drop the language branch.
				if ($bv->title === 'Language' && JLanguageMultilang::isEnabled())
				{
					continue;
				}

				// Build the query to get the child nodes for this branch.
				$query->clear()
					->select('t.*')
					->from($db->quoteName('#__finder_taxonomy') . ' AS t')
					->where('t.parent_id = ' . (int) $bk)
					->where('t.state = 1')
					->where('t.access IN (' . $groups . ')')
					->order('t.ordering, t.title');

				// Self-join to get the parent title.
				$query->select('e.title AS parent_title')
					->join('LEFT', $db->quoteName('#__finder_taxonomy', 'e') . ' ON ' . $db->quoteName('e.id') . ' = ' . $db->quoteName('t.parent_id'));

				// Limit the nodes to a predefined filter.
				if (!empty($filter->data))
				{
					$query->where('t.id IN(' . $filter->data . ')');
				}

				// Load the branches.
				$db->setQuery($query);

				try
				{
					$branches[$bk]->nodes = $db->loadObjectList('id');
				}
				catch (RuntimeException $e)
				{
					return null;
				}

				// Translate branch nodes if possible.
				$language = JFactory::getLanguage();

				foreach ($branches[$bk]->nodes as $node_id => $node)
				{
					if (trim($node->parent_title, '**') === 'Language')
					{
						$title = FinderHelperLanguage::branchLanguageTitle($node->title);
					}
					else
					{
						$key = FinderHelperLanguage::branchPlural($node->title);
						$title = $language->hasKey($key) ? JText::_($key) : $node->title;
					}

					$branches[$bk]->nodes[$node_id]->title = $title;
				}

				// Add the Search All option to the branch.
				array_unshift($branches[$bk]->nodes, array('id' => null, 'title' => JText::_('COM_FINDER_FILTER_SELECT_ALL_LABEL')));
			}

			// Store the data in cache.
			$cache->store($branches, $cacheId);
		}

		$html = '';

		// Add the dates if enabled.
		if ($showDates)
		{
			$html .= JHtml::_('filter.dates', $idxQuery, $options);
		}

		$html .= '<div class="filter-branch' . $classSuffix . ' control-group clearfix">';

		// Iterate through all branches and build code.
		foreach ($branches as $bk => $bv)
		{
			// If the multi-lang plugin is enabled then drop the language branch.
			if ($bv->title === 'Language' && JLanguageMultilang::isEnabled())
			{
				continue;
			}

			$active = null;

			// Check if the branch is in the filter.
			if (array_key_exists($bv->title, $idxQuery->filters))
			{
				// Get the request filters.
				$temp   = JFactory::getApplication()->input->request->get('t', array(), 'array');

				// Search for active nodes in the branch and get the active node.
				$active = array_intersect($temp, $idxQuery->filters[$bv->title]);
				$active = count($active) === 1 ? array_shift($active) : null;
			}

			// Build a node.
			$html .= '<div class="controls finder-selects">';
			$html .= '<label for="tax-' . JFilterOutput::stringURLSafe($bv->title) . '" class="control-label">';
			$html .= JText::sprintf('COM_FINDER_FILTER_BRANCH_LABEL', JText::_(FinderHelperLanguage::branchSingular($bv->title)));
			$html .= '</label>';
			$html .= '<br />';
			$html .= JHtml::_(
				'select.genericlist',
				$branches[$bk]->nodes, 't[]', 'class="inputbox advancedSelect"', 'id', 'title', $active,
				'tax-' . JFilterOutput::stringURLSafe($bv->title)
			);
			$html .= '</div>';
		}

		$html .= '</div>';

		return $html;
	}

	/**
	 * Method to generate fields for filtering dates
	 *
	 * @param   FinderIndexerQuery  $idxQuery  A FinderIndexerQuery object.
	 * @param   array               $options   An array of options.
	 *
	 * @return  mixed  A rendered HTML widget on success, null otherwise.
	 *
	 * @since   2.5
	 */
	public static function dates($idxQuery, $options)
	{
		$html = '';

		// Get the configuration options.
		$classSuffix = $options->get('class_suffix', null);
		$loadMedia   = $options->get('load_media', true);
		$showDates   = $options->get('show_date_filters', false);

		if (!empty($showDates))
		{
			// Build the date operators options.
			$operators   = array();
			$operators[] = JHtml::_('select.option', 'before', JText::_('COM_FINDER_FILTER_DATE_BEFORE'));
			$operators[] = JHtml::_('select.option', 'exact', JText::_('COM_FINDER_FILTER_DATE_EXACTLY'));
			$operators[] = JHtml::_('select.option', 'after', JText::_('COM_FINDER_FILTER_DATE_AFTER'));

			// Load the CSS/JS resources.
			if ($loadMedia)
			{
				JHtml::_('stylesheet', 'com_finder/dates.css', array('version' => 'auto', 'relative' => true));
			}

			// Open the widget.
			$html .= '<ul id="finder-filter-select-dates">';

			// Start date filter.
			$attribs['class'] = 'input-medium';
			$html .= '<li class="filter-date' . $classSuffix . '">';
			$html .= '<label for="filter_date1" class="hasTooltip" title ="' . JText::_('COM_FINDER_FILTER_DATE1_DESC') . '">';
			$html .= JText::_('COM_FINDER_FILTER_DATE1');
			$html .= '</label>';
			$html .= '<br />';
			$html .= JHtml::_(
				'select.genericlist',
				$operators, 'w1', 'class="inputbox filter-date-operator advancedSelect"', 'value', 'text', $idxQuery->when1, 'finder-filter-w1'
			);
			$html .= JHtml::_('calendar', $idxQuery->date1, 'd1', 'filter_date1', '%Y-%m-%d', $attribs);
			$html .= '</li>';

			// End date filter.
			$html .= '<li class="filter-date' . $classSuffix . '">';
			$html .= '<label for="filter_date2" class="hasTooltip" title ="' . JText::_('COM_FINDER_FILTER_DATE2_DESC') . '">';
			$html .= JText::_('COM_FINDER_FILTER_DATE2');
			$html .= '</label>';
			$html .= '<br />';
			$html .= JHtml::_(
				'select.genericlist',
				$operators, 'w2', 'class="inputbox filter-date-operator advancedSelect"', 'value', 'text', $idxQuery->when2, 'finder-filter-w2'
			);
			$html .= JHtml::_('calendar', $idxQuery->date2, 'd2', 'filter_date2', '%Y-%m-%d', $attribs);
			$html .= '</li>';

			// Close the widget.
			$html .= '</ul>';
		}

		return $html;
	}
}
PKw}!]�ش���html/query.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_finder
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Query HTML behavior class for Finder.
 *
 * @since  2.5
 */
abstract class JHtmlQuery
{
	/**
	 * Method to get the explained (human-readable) search query.
	 *
	 * @param   FinderIndexerQuery  $query  A FinderIndexerQuery object to explain.
	 *
	 * @return  mixed  String if there is data to explain, null otherwise.
	 *
	 * @since   2.5
	 */
	public static function explained(FinderIndexerQuery $query)
	{
		$parts = array();

		// Process the required tokens.
		foreach ($query->included as $token)
		{
			if ($token->required && (!isset($token->derived) || $token->derived == false))
			{
				$parts[] = '<span class="query-required">' . JText::sprintf('COM_FINDER_QUERY_TOKEN_REQUIRED', $token->term) . '</span>';
			}
		}

		// Process the optional tokens.
		foreach ($query->included as $token)
		{
			if (!$token->required && (!isset($token->derived) || $token->derived == false))
			{
				$parts[] = '<span class="query-optional">' . JText::sprintf('COM_FINDER_QUERY_TOKEN_OPTIONAL', $token->term) . '</span>';
			}
		}

		// Process the excluded tokens.
		foreach ($query->excluded as $token)
		{
			if (!isset($token->derived) || $token->derived === false)
			{
				$parts[] = '<span class="query-excluded">' . JText::sprintf('COM_FINDER_QUERY_TOKEN_EXCLUDED', $token->term) . '</span>';
			}
		}

		// Process the start date.
		if ($query->date1)
		{
			$date = JFactory::getDate($query->date1)->format(JText::_('DATE_FORMAT_LC'));
			$datecondition = JText::_('COM_FINDER_QUERY_DATE_CONDITION_' . strtoupper($query->when1));
			$parts[] = '<span class="query-start-date">' . JText::sprintf('COM_FINDER_QUERY_START_DATE', $datecondition, $date) . '</span>';
		}

		// Process the end date.
		if ($query->date2)
		{
			$date = JFactory::getDate($query->date2)->format(JText::_('DATE_FORMAT_LC'));
			$datecondition = JText::_('COM_FINDER_QUERY_DATE_CONDITION_' . strtoupper($query->when2));
			$parts[] = '<span class="query-end-date">' . JText::sprintf('COM_FINDER_QUERY_END_DATE', $datecondition, $date) . '</span>';
		}

		// Process the taxonomy filters.
		if (!empty($query->filters))
		{
			// Get the filters in the request.
			$t = JFactory::getApplication()->input->request->get('t', array(), 'array');

			// Process the taxonomy branches.
			foreach ($query->filters as $branch => $nodes)
			{
				// Process the taxonomy nodes.
				$lang = JFactory::getLanguage();

				foreach ($nodes as $title => $id)
				{
					// Translate the title for Types
					$key = FinderHelperLanguage::branchPlural($title);

					if ($lang->hasKey($key))
					{
						$title = JText::_($key);
					}

					// Don't include the node if it is not in the request.
					if (!in_array($id, $t))
					{
						continue;
					}

					// Add the node to the explanation.
					$parts[] = '<span class="query-taxonomy">'
						. JText::sprintf('COM_FINDER_QUERY_TAXONOMY_NODE', $title, JText::_(FinderHelperLanguage::branchSingular($branch)))
						. '</span>';
				}
			}
		}

		// Build the interpreted query.
		return count($parts) ? JText::sprintf('COM_FINDER_QUERY_TOKEN_INTERPRETED', implode(JText::_('COM_FINDER_QUERY_TOKEN_GLUE'), $parts)) : null;
	}

	/**
	 * Method to get the suggested search query.
	 *
	 * @param   FinderIndexerQuery  $query  A FinderIndexerQuery object.
	 *
	 * @return  mixed  String if there is a suggestion, false otherwise.
	 *
	 * @since   2.5
	 */
	public static function suggested(FinderIndexerQuery $query)
	{
		$suggested = false;

		// Check if the query input is empty.
		if (empty($query->input))
		{
			return $suggested;
		}

		// Check if there were any ignored or included keywords.
		if (count($query->ignored) || count($query->included))
		{
			$suggested = $query->input;

			// Replace the ignored keyword suggestions.
			foreach (array_reverse($query->ignored) as $token)
			{
				if (isset($token->suggestion))
				{
					$suggested = str_ireplace($token->term, $token->suggestion, $suggested);
				}
			}

			// Replace the included keyword suggestions.
			foreach (array_reverse($query->included) as $token)
			{
				if (isset($token->suggestion))
				{
					$suggested = str_ireplace($token->term, $token->suggestion, $suggested);
				}
			}

			// Check if we made any changes.
			if ($suggested == $query->input)
			{
				$suggested = false;
			}
		}

		return $suggested;
	}
}
PK�}!]�s�1��	media.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_media
 *
 * @copyright   (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Object\CMSObject;

/**
 * Media helper class.
 *
 * @since       1.6
 * @deprecated  4.0  Use JHelperMedia instead
 */
abstract class MediaHelper
{
	/**
	 * Checks if the file is an image
	 *
	 * @param   string  $fileName  The filename
	 *
	 * @return  boolean
	 *
	 * @since   1.5
	 * @deprecated  4.0  Use JHelperMedia::isImage instead
	 */
	public static function isImage($fileName)
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperMedia::isImage() instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		$mediaHelper = new JHelperMedia;

		return $mediaHelper->isImage($fileName);
	}

	/**
	 * Gets the file extension for the purpose of using an icon.
	 *
	 * @param   string  $fileName  The filename
	 *
	 * @return  string  File extension
	 *
	 * @since   1.5
	 * @deprecated  4.0  Use JHelperMedia::getTypeIcon instead
	 */
	public static function getTypeIcon($fileName)
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperMedia::getTypeIcon() instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		$mediaHelper = new JHelperMedia;

		return $mediaHelper->getTypeIcon($fileName);
	}

	/**
	 * Checks if the file can be uploaded
	 *
	 * @param   array   $file   File information
	 * @param   string  $error  An error message to be returned
	 *
	 * @return  boolean
	 *
	 * @since   1.5
	 * @deprecated  4.0  Use JHelperMedia::canUpload instead
	 */
	public static function canUpload($file, $error = '')
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperMedia::canUpload() instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		$mediaHelper = new JHelperMedia;

		return $mediaHelper->canUpload($file, 'com_media');
	}

	/**
	 * Method to parse a file size
	 *
	 * @param   integer  $size  The file size in bytes
	 *
	 * @return  string  The converted file size
	 *
	 * @since   1.6
	 * @deprecated  4.0  Use JHtml::_('number.bytes') instead
	 */
	public static function parseSize($size)
	{
		try
		{
			JLog::add(
				sprintf("%s() is deprecated. Use JHtml::_('number.bytes') instead.", __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		return JHtml::_('number.bytes', $size);
	}

	/**
	 * Calculate the size of a resized image
	 *
	 * @param   integer  $width   Image width
	 * @param   integer  $height  Image height
	 * @param   integer  $target  Target size
	 *
	 * @return  array  The new width and height
	 *
	 * @since   3.2
	 * @deprecated  4.0  Use JHelperMedia::imageResize instead
	 */
	public static function imageResize($width, $height, $target)
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperMedia::imageResize() instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		$mediaHelper = new JHelperMedia;

		return $mediaHelper->imageResize($width, $height, $target);
	}

	/**
	 * Counts the files and directories in a directory that are not php or html files.
	 *
	 * @param   string  $dir  Directory name
	 *
	 * @return  array  The number of files and directories in the given directory
	 *
	 * @since   1.5
	 * @deprecated  4.0  Use JHelperMedia::countFiles instead
	 */
	public static function countFiles($dir)
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperMedia::countFiles() instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		$mediaHelper = new JHelperMedia;

		return $mediaHelper->countFiles($dir);
	}

	/**
	 * Generates the URL to the object in the action logs component
	 *
	 * @param   string     $contentType  The content type
	 * @param   integer    $id           The integer id
	 * @param   CMSObject  $mediaObject  The media object being uploaded
	 *
	 * @return  string  The link for the action log
	 *
	 * @since   3.9.27
	 */
	public static function getContentTypeLink($contentType, $id, CMSObject $mediaObject)
	{
		if ($contentType === 'com_media.file')
		{
			return '';
		}

		$link         = 'index.php?option=com_media&view=media';
		$uploadedPath = substr($mediaObject->get('filepath'), strlen(COM_MEDIA_BASE) + 1);

		// Now remove the filename
		$uploadedBasePath = substr_replace(
			$uploadedPath,
			'',
			(strlen(DIRECTORY_SEPARATOR . $mediaObject->get('name')) * -1)
		);

		if (!empty($uploadedBasePath))
		{
			$link = $link . '&folder=' . $uploadedBasePath;
		}

		return $link;
	}
}
PK�!]WcH���category.phpnu&1i�<?php
/**
 * @version $Id$
 * @package DJ-ImageSlider
 * @subpackage DJ-ImageSlider Component
 * @copyright Copyright (C) 2017 DJ-Extensions.com, All rights reserved.
 * @license http://www.gnu.org/licenses GNU/GPL
 * @author url: http://dj-extensions.com
 * @author email contact@dj-extensions.com
 * @developer Szymon Woronowski - szymon.woronowski@design-joomla.eu
 *
 *
 * DJ-ImageSlider is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DJ-ImageSlider is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with DJ-ImageSlider. If not, see <http://www.gnu.org/licenses/>.
 *
 */


defined('_JEXEC') or die;


class DJImageSliderCategories extends JCategories
{
    /**
     * Class constructor
     *
     * @param   array  $options  Array of options
     *
     * @since   11.1
     */
    public function __construct($options = array())
    {
        $options['table'] = '#__djimageslider` ';
        $options['extension'] = 'com_djimageslider';
        $options['field'] = 'catid';
        parent::__construct($options);
    }
}PK�!]Aؽb��
banner.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_banners
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Banner Helper Class
 *
 * @since  1.6
 */
abstract class BannerHelper
{
	/**
	 * Checks if a URL is an image
	 *
	 * @param   string  $url  The URL path to the potential image
	 *
	 * @return  boolean  True if an image of type bmp, gif, jp(e)g or png, false otherwise
	 *
	 * @since   1.6
	 */
	public static function isImage($url)
	{
		return preg_match('#\.(?:bmp|gif|jpe?g|png)$#i', $url);
	}

	/**
	 * Checks if a URL is a Flash file
	 *
	 * @param   string  $url  The URL path to the potential flash file
	 *
	 * @return  boolean  True if an image of type bmp, gif, jp(e)g or png, false otherwise
	 *
	 * @since   1.6
	 */
	public static function isFlash($url)
	{
		return preg_match('#\.swf$#i', $url);
	}
}
PKl�!]��bb	cache.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_cache
 *
 * @copyright   (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Cache component helper.
 *
 * @since  1.6
 */
class CacheHelper
{
	/**
	 * Get a list of filter options for the application clients.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @deprecated  4.0  No replacement.
	 */
	public static function getClientOptions()
	{
		// Build the filter options.
		$options   = array();
		$options[] = JHtml::_('select.option', '0', JText::_('JSITE'));
		$options[] = JHtml::_('select.option', '1', JText::_('JADMINISTRATOR'));

		return $options;
	}

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('JGLOBAL_SUBMENU_CHECKIN'),
			'index.php?option=com_checkin',
			$vName == 'com_checkin'
		);

		JHtmlSidebar::addEntry(
			JText::_('JGLOBAL_SUBMENU_CLEAR_CACHE'),
			'index.php?option=com_cache',
			$vName == 'cache'
		);
		JHtmlSidebar::addEntry(
			JText::_('JGLOBAL_SUBMENU_PURGE_EXPIRED_CACHE'),
			'index.php?option=com_cache&view=purge',
			$vName == 'purge'
		);
	}
}
PK�!]���qb$b$actionlogs.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_actionlogs
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Date\Date;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\Path;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\String\StringHelper;

/**
 * Actionlogs component helper.
 *
 * @since  3.9.0
 */
class ActionlogsHelper
{
	/**
	 * Array of characters starting a formula
	 *
	 * @var    array
	 * @since  3.9.7
	 */
	private static $characters = array('=', '+', '-', '@');

	/**
	 * Method to convert logs objects array to an iterable type for use with a CSV export
	 *
	 * @param   array|Traversable  $data  The logs data objects to be exported
	 *
	 * @return  array|Generator  For PHP 5.5 and newer, a Generator is returned; PHP 5.4 and earlier use an array
	 *
	 * @since   3.9.0
	 * @throws  InvalidArgumentException
	 */
	public static function getCsvData($data)
	{
		if (!is_iterable($data))
		{
			throw new InvalidArgumentException(
				sprintf(
					'%s() requires an array or object implementing the Traversable interface, a %s was given.',
					__METHOD__,
					gettype($data) === 'object' ? get_class($data) : gettype($data)
				)
			);
		}

		if (version_compare(PHP_VERSION, '5.5', '>='))
		{
			// Only include the PHP 5.5 helper in this conditional to prevent the potential of parse errors for PHP 5.4 or earlier
			JLoader::register('ActionlogsHelperPhp55', __DIR__ . '/actionlogsphp55.php');

			return ActionlogsHelperPhp55::getCsvAsGenerator($data);
		}

		$disabledText = Text::_('COM_ACTIONLOGS_DISABLED');

		$rows = array();

		// Header row
		$rows[] = array('Id', 'Message', 'Date', 'Extension', 'User', 'Ip');

		foreach ($data as $log)
		{
			$date      = new Date($log->log_date, new DateTimeZone('UTC'));
			$extension = strtok($log->extension, '.');

			static::loadTranslationFiles($extension);

			$rows[] = array(
				'id'         => $log->id,
				'message'    => self::escapeCsvFormula(strip_tags(static::getHumanReadableLogMessage($log, false))),
				'date'       => $date->format('Y-m-d H:i:s T'),
				'extension'  => self::escapeCsvFormula(Text::_($extension)),
				'name'       => self::escapeCsvFormula($log->name),
				'ip_address' => self::escapeCsvFormula($log->ip_address === 'COM_ACTIONLOGS_DISABLED' ? $disabledText : $log->ip_address)
			);
		}

		return $rows;
	}

	/**
	 * Load the translation files for an extension
	 *
	 * @param   string  $extension  Extension name
	 *
	 * @return  void
	 *
	 * @since   3.9.0
	 */
	public static function loadTranslationFiles($extension)
	{
		static $cache = array();
		$extension = strtolower($extension);

		if (isset($cache[$extension]))
		{
			return;
		}

		$lang   = Factory::getLanguage();
		$source = '';

		switch (substr($extension, 0, 3))
		{
			case 'com':
			default:
				$source = JPATH_ADMINISTRATOR . '/components/' . $extension;
				break;

			case 'lib':
				$source = JPATH_LIBRARIES . '/' . substr($extension, 4);
				break;

			case 'mod':
				$source = JPATH_SITE . '/modules/' . $extension;
				break;

			case 'plg':
				$parts = explode('_', $extension, 3);

				if (count($parts) > 2)
				{
					$source = JPATH_PLUGINS . '/' . $parts[1] . '/' . $parts[2];
				}
				break;

			case 'pkg':
				$source = JPATH_SITE;
				break;

			case 'tpl':
				$source = JPATH_BASE . '/templates/' . substr($extension, 4);
				break;

		}

		$lang->load($extension, JPATH_ADMINISTRATOR, null, false, true)
			|| $lang->load($extension, $source, null, false, true);

		if (!$lang->hasKey(strtoupper($extension)))
		{
			$lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, true)
				|| $lang->load($extension . '.sys', $source, null, false, true);
		}

		$cache[$extension] = true;
	}

	/**
	 * Get parameters to be
	 *
	 * @param   string  $context  The context of the content
	 *
	 * @return  mixed  An object contains content type parameters, or null if not found
	 *
	 * @since   3.9.0
	 */
	public static function getLogContentTypeParams($context)
	{
		$db = Factory::getDbo();
		$query = $db->getQuery(true)
			->select('a.*')
			->from($db->quoteName('#__action_log_config', 'a'))
			->where($db->quoteName('a.type_alias') . ' = ' . $db->quote($context));

		$db->setQuery($query);

		return $db->loadObject();
	}

	/**
	 * Get human readable log message for a User Action Log
	 *
	 * @param   stdClass  $log            A User Action log message record
	 * @param   boolean   $generateLinks  Flag to disable link generation when creating a message
	 *
	 * @return  string
	 *
	 * @since   3.9.0
	 */
	public static function getHumanReadableLogMessage($log, $generateLinks = true)
	{
		static $links = array();

		$message     = Text::_($log->message_language_key);
		$messageData = json_decode($log->message, true);

		// Special handling for translation extension name
		if (isset($messageData['extension_name']))
		{
			static::loadTranslationFiles($messageData['extension_name']);
			$messageData['extension_name'] = Text::_($messageData['extension_name']);
		}

		// Translating application
		if (isset($messageData['app']))
		{
			$messageData['app'] = Text::_($messageData['app']);
		}

		// Translating type
		if (isset($messageData['type']))
		{
			$messageData['type'] = Text::_($messageData['type']);
		}

		$linkMode = Factory::getApplication()->get('force_ssl', 0) >= 1 ? Route::TLS_FORCE : Route::TLS_IGNORE;

		foreach ($messageData as $key => $value)
		{
			// Escape any markup in the values to prevent XSS attacks
			$value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');

			// Convert relative url to absolute url so that it is clickable in action logs notification email
			if ($generateLinks && StringHelper::strpos($value, 'index.php?') === 0)
			{
				if (!isset($links[$value]))
				{
					$links[$value] = Route::link('administrator', $value, false, $linkMode, true);
				}

				$value = $links[$value];
			}

			$message = str_replace('{' . $key . '}', $value, $message);
		}

		return $message;
	}

	/**
	 * Get link to an item of given content type
	 *
	 * @param   string   $component
	 * @param   string   $contentType
	 * @param   integer  $id
	 * @param   string   $urlVar
	 * @param   JObject  $object
	 *
	 * @return  string  Link to the content item
	 *
	 * @since   3.9.0
	 */
	public static function getContentTypeLink($component, $contentType, $id, $urlVar = 'id', $object = null)
	{
		// Try to find the component helper.
		$eName = str_replace('com_', '', $component);
		$file  = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php');

		if (file_exists($file))
		{
			$prefix = ucfirst(str_replace('com_', '', $component));
			$cName  = $prefix . 'Helper';

			JLoader::register($cName, $file);

			if (class_exists($cName) && is_callable(array($cName, 'getContentTypeLink')))
			{
				return $cName::getContentTypeLink($contentType, $id, $object);
			}
		}

		if (empty($urlVar))
		{
			$urlVar = 'id';
		}

		// Return default link to avoid having to implement getContentTypeLink in most of our components
		return 'index.php?option=' . $component . '&task=' . $contentType . '.edit&' . $urlVar . '=' . $id;
	}

	/**
	 * Load both enabled and disabled actionlog plugins language file.
	 *
	 * It is used to make sure actions log is displayed properly instead of only language items displayed when a plugin is disabled.
	 *
	 * @return  void
	 *
	 * @since   3.9.0
	 */
	public static function loadActionLogPluginsLanguage()
	{
		$lang = Factory::getLanguage();
		$db   = Factory::getDbo();

		// Get all (both enabled and disabled) actionlog plugins
		$query = $db->getQuery(true)
			->select(
				$db->quoteName(
					array(
						'folder',
						'element',
						'params',
						'extension_id'
					),
					array(
						'type',
						'name',
						'params',
						'id'
					)
				)
			)
			->from('#__extensions')
			->where('type = ' . $db->quote('plugin'))
			->where('folder = ' . $db->quote('actionlog'))
			->where('state IN (0,1)')
			->order('ordering');
		$db->setQuery($query);

		try
		{
			$rows = $db->loadObjectList();
		}
		catch (RuntimeException $e)
		{
			$rows = array();
		}

		if (empty($rows))
		{
			return;
		}

		foreach ($rows as $row)
		{
			$name      = $row->name;
			$type      = $row->type;
			$extension = 'Plg_' . $type . '_' . $name;
			$extension = strtolower($extension);

			// If language already loaded, don't load it again.
			if ($lang->getPaths($extension))
			{
				continue;
			}

			$lang->load($extension, JPATH_ADMINISTRATOR, null, false, true)
			|| $lang->load($extension, JPATH_PLUGINS . '/' . $type . '/' . $name, null, false, true);
		}

		// Load com_privacy too.
		$lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true);
	}

	/**
	 * Escapes potential characters that start a formula in a CSV value to prevent injection attacks
	 *
	 * @param   mixed  $value  csv field value
	 *
	 * @return  mixed
	 *
	 * @since   3.9.7
	 */
	protected static function escapeCsvFormula($value)
	{
		if ($value == '')
		{
			return $value;
		}

		if (in_array($value[0], self::$characters, true))
		{
			$value = ' ' . $value;
		}

		return $value;
	}
}
PK�!]�� 8i
i
actionlogsphp55.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_actionlogs
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Date\Date;
use Joomla\CMS\Language\Text;

/**
 * Actionlogs component helper for newer PHP versions.
 *
 * This file should only be included in environments running PHP 5.5 or newer and may potentially cause a parse error on older versions.
 *
 * @since       3.9.0
 * @deprecated  Will be inlined back into ActionlogsHelper when PHP 5.5 or newer is the minimum supported PHP version
 * @internal
 */
class ActionlogsHelperPhp55
{
	/**
	 * Array of characters starting a formula
	 *
	 * @var    array
	 * @since  3.9.7
	 */
	private static $characters = array('=', '+', '-', '@');

	/**
	 * Method to convert logs objects array to a Generator for use with a CSV export
	 *
	 * @param   array|Traversable  $data  The logs data objects to be exported
	 *
	 * @return  Generator
	 *
	 * @since   3.9.0
	 * @throws  InvalidArgumentException
	 */
	public static function getCsvAsGenerator($data)
	{
		if (!is_iterable($data))
		{
			throw new InvalidArgumentException(
				sprintf(
					'%s() requires an array or object implementing the Traversable interface, a %s was given.',
					__METHOD__,
					gettype($data) === 'object' ? get_class($data) : gettype($data)
				)
			);
		}

		$disabledText = Text::_('COM_ACTIONLOGS_DISABLED');

		// Header row
		yield array('Id', 'Message', 'Date', 'Extension', 'User', 'Ip');

		foreach ($data as $log)
		{
			$extension = strtok($log->extension, '.');

			ActionlogsHelper::loadTranslationFiles($extension);

			yield array(
				'id'         => $log->id,
				'message'    => self::escapeCsvFormula(strip_tags(ActionlogsHelper::getHumanReadableLogMessage($log, false))),
				'date'       => (new Date($log->log_date, new DateTimeZone('UTC')))->format('Y-m-d H:i:s T'),
				'extension'  => self::escapeCsvFormula(Text::_($extension)),
				'name'       => self::escapeCsvFormula($log->name),
				'ip_address' => self::escapeCsvFormula($log->ip_address === 'COM_ACTIONLOGS_DISABLED' ? $disabledText : $log->ip_address)
			);
		}
	}

	/**
	 * Escapes potential characters that start a formula in a CSV value to prevent injection attacks
	 *
	 * @param   mixed  $value  csv field value
	 *
	 * @return  mixed
	 *
	 * @since   3.9.7
	 */
	protected static function escapeCsvFormula($value)
	{
		if ($value == '')
		{
			return $value;
		}

		if (in_array($value[0], self::$characters, true))
		{
			$value = ' ' . $value;
		}

		return $value;
	}
}
PK�!]j�/�			users.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Users component helper.
 *
 * @since  1.6
 */
class UsersHelper
{
	/**
	 * @var    JObject  A cache for the available actions.
	 * @since  1.6
	 */
	protected static $actions;

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_USERS_SUBMENU_USERS'),
			'index.php?option=com_users&view=users',
			$vName == 'users'
		);

		// Groups and Levels are restricted to core.admin
		$canDo = JHelperContent::getActions('com_users');

		if ($canDo->get('core.admin'))
		{
			JHtmlSidebar::addEntry(
				JText::_('COM_USERS_SUBMENU_GROUPS'),
				'index.php?option=com_users&view=groups',
				$vName == 'groups'
			);
			JHtmlSidebar::addEntry(
				JText::_('COM_USERS_SUBMENU_LEVELS'),
				'index.php?option=com_users&view=levels',
				$vName == 'levels'
			);
		}

		if (JComponentHelper::isEnabled('com_fields') && JComponentHelper::getParams('com_users')->get('custom_fields_enable', '1'))
		{
			JHtmlSidebar::addEntry(
				JText::_('JGLOBAL_FIELDS'),
				'index.php?option=com_fields&context=com_users.user',
				$vName == 'fields.fields'
			);
			JHtmlSidebar::addEntry(
				JText::_('JGLOBAL_FIELD_GROUPS'),
				'index.php?option=com_fields&view=groups&context=com_users.user',
				$vName == 'fields.groups'
			);
		}

		JHtmlSidebar::addEntry(
			JText::_('COM_USERS_SUBMENU_NOTES'),
			'index.php?option=com_users&view=notes',
			$vName == 'notes'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_USERS_SUBMENU_NOTE_CATEGORIES'),
			'index.php?option=com_categories&extension=com_users',
			$vName == 'categories'
		);
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject
	 *
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions()
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		return JHelperContent::getActions('com_users');
	}

	/**
	 * Get a list of filter options for the blocked state of a user.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   1.6
	 */
	public static function getStateOptions()
	{
		// Build the filter options.
		$options = array();
		$options[] = JHtml::_('select.option', '0', JText::_('JENABLED'));
		$options[] = JHtml::_('select.option', '1', JText::_('JDISABLED'));

		return $options;
	}

	/**
	 * Get a list of filter options for the activated state of a user.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   1.6
	 */
	public static function getActiveOptions()
	{
		// Build the filter options.
		$options = array();
		$options[] = JHtml::_('select.option', '0', JText::_('COM_USERS_ACTIVATED'));
		$options[] = JHtml::_('select.option', '1', JText::_('COM_USERS_UNACTIVATED'));

		return $options;
	}

	/**
	 * Get a list of the user groups for filtering.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   1.6
	 */
	public static function getGroups()
	{
		$options = JHelperUsergroups::getInstance()->getAll();

		foreach ($options as &$option)
		{
			$option->value = $option->id;
			$option->text = str_repeat('- ', $option->level) . $option->title;
		}

		return $options;
	}

	/**
	 * Creates a list of range options used in filter select list
	 * used in com_users on users view
	 *
	 * @return  array
	 *
	 * @since   2.5
	 */
	public static function getRangeOptions()
	{
		$options = array(
			JHtml::_('select.option', 'today', JText::_('COM_USERS_OPTION_RANGE_TODAY')),
			JHtml::_('select.option', 'past_week', JText::_('COM_USERS_OPTION_RANGE_PAST_WEEK')),
			JHtml::_('select.option', 'past_1month', JText::_('COM_USERS_OPTION_RANGE_PAST_1MONTH')),
			JHtml::_('select.option', 'past_3month', JText::_('COM_USERS_OPTION_RANGE_PAST_3MONTH')),
			JHtml::_('select.option', 'past_6month', JText::_('COM_USERS_OPTION_RANGE_PAST_6MONTH')),
			JHtml::_('select.option', 'past_year', JText::_('COM_USERS_OPTION_RANGE_PAST_YEAR')),
			JHtml::_('select.option', 'post_year', JText::_('COM_USERS_OPTION_RANGE_POST_YEAR')),
		);

		return $options;
	}

	/**
	 * Creates a list of two factor authentication methods used in com_users
	 * on user view
	 *
	 * @return  array
	 *
	 * @since   3.2.0
	 */
	public static function getTwoFactorMethods()
	{
		FOFPlatform::getInstance()->importPlugin('twofactorauth');
		$identities = FOFPlatform::getInstance()->runPlugins('onUserTwofactorIdentify', array());

		$options = array(
			JHtml::_('select.option', 'none', JText::_('JGLOBAL_OTPMETHOD_NONE'), 'value', 'text'),
		);

		if (!empty($identities))
		{
			foreach ($identities as $identity)
			{
				if (!is_object($identity))
				{
					continue;
				}

				$options[] = JHtml::_('select.option', $identity->method, $identity->title, 'value', 'text');
			}
		}

		return $options;
	}

	/**
	 * Get a list of the User Groups for Viewing Access Levels
	 *
	 * @param   string  $rules  User Groups in JSON format
	 *
	 * @return  string  $groups  Comma separated list of User Groups
	 *
	 * @since   3.6
	 */
	public static function getVisibleByGroups($rules)
	{
		$rules = json_decode($rules);

		if (!$rules)
		{
			return false;
		}

		$rules = implode(',', $rules);

		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('a.title AS text')
			->from('#__usergroups as a')
			->where('a.id IN (' . $rules . ')');
		$db->setQuery($query);

		$groups = $db->loadColumn();
		$groups = implode(', ', $groups);

		return $groups;
	}

	/**
	 * Returns a valid section for users. If it is not valid then null
	 * is returned.
	 *
	 * @param   string  $section  The section to get the mapping for
	 *
	 * @return  string|null  The new section
	 *
	 * @since   3.7.0
	 */
	public static function validateSection($section)
	{
		if (JFactory::getApplication()->isClient('site'))
		{
			switch ($section)
			{
				case 'registration':
				case 'profile':
					$section = 'user';
			}
		}

		if ($section != 'user')
		{
			// We don't know other sections
			return null;
		}

		return $section;
	}

	/**
	 * Returns valid contexts
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public static function getContexts()
	{
		JFactory::getLanguage()->load('com_users', JPATH_ADMINISTRATOR);

		$contexts = array(
			'com_users.user' => JText::_('COM_USERS'),
		);

		return $contexts;
	}
}
PK�!]��TA��html/users.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Extended Utility class for the Users component.
 *
 * @since  2.5
 */
class JHtmlUsers
{
	/**
	 * Display an image.
	 *
	 * @param   string  $src  The source of the image
	 *
	 * @return  string  A <img> element if the specified file exists, otherwise, a null string
	 *
	 * @since   2.5
	 */
	public static function image($src)
	{
		$src = preg_replace('#[^A-Z0-9\-_\./]#i', '', $src);
		$file = JPATH_SITE . '/' . $src;

		jimport('joomla.filesystem.path');
		JPath::check($file);

		if (!file_exists($file))
		{
			return '';
		}

		return '<img src="' . JUri::root() . $src . '" alt="" />';
	}

	/**
	 * Displays an icon to add a note for this user.
	 *
	 * @param   integer  $userId  The user ID
	 *
	 * @return  string  A link to add a note
	 *
	 * @since   2.5
	 */
	public static function addNote($userId)
	{
		$title = JText::_('COM_USERS_ADD_NOTE');

		return '<a href="' . JRoute::_('index.php?option=com_users&task=note.add&u_id=' . (int) $userId) . '" class="hasTooltip btn btn-mini" title="'
			. $title . '"><span class="icon-vcard" aria-hidden="true"></span><span class="hidden-phone">' . $title . '</span></a>';
	}

	/**
	 * Displays an icon to filter the notes list on this user.
	 *
	 * @param   integer  $count   The number of notes for the user
	 * @param   integer  $userId  The user ID
	 *
	 * @return  string  A link to apply a filter
	 *
	 * @since   2.5
	 */
	public static function filterNotes($count, $userId)
	{
		if (empty($count))
		{
			return '';
		}

		$title = JText::_('COM_USERS_FILTER_NOTES');

		return '<a href="' . JRoute::_('index.php?option=com_users&view=notes&filter[search]=uid:' . (int) $userId)
			. '" class="hasTooltip btn btn-mini" title="' . $title . '"><span class="icon-filter"></span></a>';
	}

	/**
	 * Displays a note icon.
	 *
	 * @param   integer  $count   The number of notes for the user
	 * @param   integer  $userId  The user ID
	 *
	 * @return  string  A link to a modal window with the user notes
	 *
	 * @since   2.5
	 */
	public static function notes($count, $userId)
	{
		if (empty($count))
		{
			return '';
		}

		$title = JText::plural('COM_USERS_N_USER_NOTES', $count);

		return '<button type="button" data-target="#userModal_' . (int) $userId . '" id="modal-' . (int) $userId . '" data-toggle="modal"'
			. ' class="hasTooltip btn btn-mini" title="' . $title . '">'
			. '<span class="icon-drawer-2" aria-hidden="true"></span><span class="hidden-phone">' . $title . '</span></button>';
	}

	/**
	 * Renders the modal html.
	 *
	 * @param   integer  $count   The number of notes for the user
	 * @param   integer  $userId  The user ID
	 *
	 * @return  string   The html for the rendered modal
	 *
	 * @since   3.4.1
	 */
	public static function notesModal($count, $userId)
	{
		if (empty($count))
		{
			return '';
		}

		$title = JText::plural('COM_USERS_N_USER_NOTES', $count);
		$footer = '<button type="button" class="btn" data-dismiss="modal">'
			. JText::_('JTOOLBAR_CLOSE') . '</button>';

		return JHtml::_(
			'bootstrap.renderModal',
			'userModal_' . (int) $userId,
			array(
				'title'       => $title,
				'backdrop'    => 'static',
				'keyboard'    => true,
				'closeButton' => true,
				'footer'      => $footer,
				'url'         => JRoute::_('index.php?option=com_users&view=notes&tmpl=component&layout=modal&filter[user_id]=' . (int) $userId),
				'height'      => '300px',
				'width'       => '800px',
			)
		);

	}

	/**
	 * Build an array of block/unblock user states to be used by jgrid.state,
	 * State options will be different for any user
	 * and for currently logged in user
	 *
	 * @param   boolean  $self  True if state array is for currently logged in user
	 *
	 * @return  array  a list of possible states to display
	 *
	 * @since  3.0
	 */
	public static function blockStates( $self = false)
	{
		if ($self)
		{
			$states = array(
				1 => array(
					'task'           => 'unblock',
					'text'           => '',
					'active_title'   => 'COM_USERS_USER_FIELD_BLOCK_DESC',
					'inactive_title' => '',
					'tip'            => true,
					'active_class'   => 'unpublish',
					'inactive_class' => 'unpublish',
				),
				0 => array(
					'task'           => 'block',
					'text'           => '',
					'active_title'   => '',
					'inactive_title' => 'COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF',
					'tip'            => true,
					'active_class'   => 'publish',
					'inactive_class' => 'publish',
				)
			);
		}
		else
		{
			$states = array(
				1 => array(
					'task'           => 'unblock',
					'text'           => '',
					'active_title'   => 'COM_USERS_TOOLBAR_UNBLOCK',
					'inactive_title' => '',
					'tip'            => true,
					'active_class'   => 'unpublish',
					'inactive_class' => 'unpublish',
				),
				0 => array(
					'task'           => 'block',
					'text'           => '',
					'active_title'   => 'COM_USERS_USER_FIELD_BLOCK_DESC',
					'inactive_title' => '',
					'tip'            => true,
					'active_class'   => 'publish',
					'inactive_class' => 'publish',
				)
			);
		}

		return $states;
	}

	/**
	 * Build an array of activate states to be used by jgrid.state,
	 *
	 * @return  array  a list of possible states to display
	 *
	 * @since  3.0
	 */
	public static function activateStates()
	{
		$states = array(
			1 => array(
				'task'           => 'activate',
				'text'           => '',
				'active_title'   => 'COM_USERS_TOOLBAR_ACTIVATE',
				'inactive_title' => '',
				'tip'            => true,
				'active_class'   => 'unpublish',
				'inactive_class' => 'unpublish',
			),
			0 => array(
				'task'           => '',
				'text'           => '',
				'active_title'   => '',
				'inactive_title' => 'COM_USERS_ACTIVATED',
				'tip'            => true,
				'active_class'   => 'publish',
				'inactive_class' => 'publish',
			)
		);

		return $states;
	}
}
PK�!]=ΓsKK	debug.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_users
 *
 * @copyright   (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * Users component debugging helper.
 *
 * @since  1.6
 */
class UsersHelperDebug
{
	/**
	 * Get a list of the components.
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public static function getComponents()
	{
		// Initialise variable.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('name AS text, element AS value')
			->from('#__extensions')
			->where('enabled >= 1')
			->where('type =' . $db->quote('component'));

		$items = $db->setQuery($query)->loadObjectList();

		if (count($items))
		{
			$lang = JFactory::getLanguage();

			foreach ($items as &$item)
			{
				// Load language
				$extension = $item->value;
				$source = JPATH_ADMINISTRATOR . '/components/' . $extension;
				$lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true)
					|| $lang->load("$extension.sys", $source, null, false, true);

				// Translate component name
				$item->text = JText::_($item->text);
			}

			// Sort by component name
			$items = ArrayHelper::sortObjects($items, 'text', 1, true, true);
		}

		return $items;
	}

	/**
	 * Get a list of the actions for the component or code actions.
	 *
	 * @param   string  $component  The name of the component.
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public static function getDebugActions($component = null)
	{
		$actions = array();

		// Try to get actions for the component
		if (!empty($component))
		{
			$component_actions = JAccess::getActions($component);

			if (!empty($component_actions))
			{
				foreach ($component_actions as &$action)
				{
					$actions[$action->title] = array($action->name, $action->description);
				}
			}
		}

		// Use default actions from configuration if no component selected or component doesn't have actions
		if (empty($actions))
		{
			$filename = JPATH_ADMINISTRATOR . '/components/com_config/model/form/application.xml';

			if (is_file($filename))
			{
				$xml = simplexml_load_file($filename);

				foreach ($xml->children()->fieldset as $fieldset)
				{
					if ('permissions' == (string) $fieldset['name'])
					{
						foreach ($fieldset->children() as $field)
						{
							if ('rules' == (string) $field['name'])
							{
								foreach ($field->children() as $action)
								{
									$actions[(string) $action['title']] = array(
										(string) $action['name'],
										(string) $action['description']
									);
								}

								break;
							}
						}
					}
				}

				// Load language
				$lang = JFactory::getLanguage();
				$extension = 'com_config';
				$source = JPATH_ADMINISTRATOR . '/components/' . $extension;

				$lang->load($extension, JPATH_ADMINISTRATOR, null, false, false)
					|| $lang->load($extension, $source, null, false, false)
					|| $lang->load($extension, JPATH_ADMINISTRATOR, $lang->getDefault(), false, false)
					|| $lang->load($extension, $source, $lang->getDefault(), false, false);
			}
		}

		return $actions;
	}

	/**
	 * Get a list of filter options for the levels.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 */
	public static function getLevelsOptions()
	{
		// Build the filter options.
		$options = array();
		$options[] = JHtml::_('select.option', '1', JText::sprintf('COM_USERS_OPTION_LEVEL_COMPONENT', 1));
		$options[] = JHtml::_('select.option', '2', JText::sprintf('COM_USERS_OPTION_LEVEL_CATEGORY', 2));
		$options[] = JHtml::_('select.option', '3', JText::sprintf('COM_USERS_OPTION_LEVEL_DEEPER', 3));
		$options[] = JHtml::_('select.option', '4', '4');
		$options[] = JHtml::_('select.option', '5', '5');
		$options[] = JHtml::_('select.option', '6', '6');

		return $options;
	}
}
PKM�!]�:L��multilangstatus.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_languages
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;
use Joomla\Registry\Registry;

/**
 * Multilang status helper.
 *
 * @since  1.7.1
 */
abstract class MultilangstatusHelper
{
	/**
	 * Method to get the number of published home pages.
	 *
	 * @return  integer
	 */
	public static function getHomes()
	{
		// Check for multiple Home pages.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('COUNT(*)')
			->from($db->quoteName('#__menu'))
			->where('home = 1')
			->where('published = 1')
			->where('client_id = 0');
		$db->setQuery($query);

		return $db->loadResult();
	}

	/**
	 * Method to get the number of published language switcher modules.
	 *
	 * @return  integer
	 */
	public static function getLangswitchers()
	{
		// Check if switcher is published.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('COUNT(*)')
			->from($db->quoteName('#__modules'))
			->where('module = ' . $db->quote('mod_languages'))
			->where('published = 1')
			->where('client_id = 0');
		$db->setQuery($query);

		return $db->loadResult();
	}

	/**
	 * Method to return a list of published content languages.
	 *
	 * @return  array of language objects.
	 */
	public static function getContentlangs()
	{
		// Check for published Content Languages.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('a.lang_code AS lang_code')
			->select('a.published AS published')
			->from('#__languages AS a');
		$db->setQuery($query);

		return $db->loadObjectList();
	}

	/**
	 * Method to return a list of published site languages.
	 *
	 * @return  array of language extension objects.
	 *
	 * @deprecated  4.0  Use JLanguageHelper::getInstalledLanguages(0) instead.
	 */
	public static function getSitelangs()
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated, use JLanguageHelper::getInstalledLanguages(0) instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		return JLanguageHelper::getInstalledLanguages(0);
	}

	/**
	 * Method to return a list of language home page menu items.
	 *
	 * @return  array of menu objects.
	 *
	 * @deprecated  4.0  Use JLanguageMultilang::getSiteHomePages() instead.
	 */
	public static function getHomepages()
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated, use JLanguageHelper::getSiteHomePages() instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		return JLanguageMultilang::getSiteHomePages();
	}

	/**
	 * Method to return combined language status.
	 *
	 * @return  array of language objects.
	 */
	public static function getStatus()
	{
		// Check for combined status.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);

		// Select all fields from the languages table.
		$query->select('a.*', 'l.home')
			->select('a.published AS published')
			->select('a.lang_code AS lang_code')
			->from('#__languages AS a');

		// Select the language home pages.
		$query->select('l.home AS home')
			->select('l.language AS home_language')
			->join('LEFT', '#__menu AS l ON l.language = a.lang_code AND l.home=1 AND l.published=1 AND l.language <> \'*\'')
			->select('e.enabled AS enabled')
			->select('e.element AS element')
			->join('LEFT', '#__extensions  AS e ON e.element = a.lang_code')
			->where('e.client_id = 0')
			->where('e.enabled = 1')
			->where('e.state = 0');

		$db->setQuery($query);

		return $db->loadObjectList();
	}

	/**
	 * Method to return a list of contact objects.
	 *
	 * @return  array of contact objects.
	 */
	public static function getContacts()
	{
		$db = JFactory::getDbo();
		$languages = count(JLanguageHelper::getLanguages());

		// Get the number of contact with all as language
		$alang = $db->getQuery(true)
			->select('count(*)')
			->from('#__contact_details AS cd')
			->where('cd.user_id=u.id')
			->where('cd.published=1')
			->where('cd.language=' . $db->quote('*'));

		// Get the number of languages for the contact
		$slang = $db->getQuery(true)
			->select('count(distinct(l.lang_code))')
			->from('#__languages as l')
			->join('LEFT', '#__contact_details AS cd ON cd.language=l.lang_code')
			->where('cd.user_id=u.id')
			->where('cd.published=1')
			->where('l.published=1');

		// Get the number of multiple contact/language
		$mlang = $db->getQuery(true)
			->select('count(*)')
			->from('#__languages as l')
			->join('LEFT', '#__contact_details AS cd ON cd.language=l.lang_code')
			->where('cd.user_id=u.id')
			->where('cd.published=1')
			->where('l.published=1')
			->group('l.lang_code')
			->having('count(*) > 1');

		// Get the contacts
		$query = $db->getQuery(true)
			->select('u.name, (' . $alang . ') as alang, (' . $slang . ') as slang, (' . $mlang . ') as mlang')
			->from('#__users AS u')
			->join('LEFT', '#__contact_details AS cd ON cd.user_id=u.id')
			->where('EXISTS (SELECT 1 from #__content as c where  c.created_by=u.id)')
			->group('u.id');

		$db->setQuery($query);
		$warnings = $db->loadObjectList();

		foreach ($warnings as $index => $warn)
		{
			if ($warn->alang == 1 && $warn->slang == 0)
			{
				unset($warnings[$index]);
			}

			if ($warn->alang == 0 && $warn->slang == 0 && empty($warn->mlang))
			{
				unset($warnings[$index]);
			}

			if ($warn->alang == 0 && $warn->slang == $languages && empty($warn->mlang))
			{
				unset($warnings[$index]);
			}
		}

		return $warnings;
	}

	/**
	 * Method to get the status of the module displaying the menutype of the default Home page set to All languages.
	 *
	 * @return  boolean True if the module is published, false otherwise.
	 *
	 * @since   3.7.0
	 */
	public static function getDefaultHomeModule()
	{
		// Find Default Home menutype.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select($db->qn('menutype'))
			->from($db->qn('#__menu'))
			->where($db->qn('home') . ' = ' . $db->q('1'))
			->where($db->qn('published') . ' = ' . $db->q('1'))
			->where($db->qn('client_id') . ' = ' . $db->q('0'))
			->where($db->qn('language') . ' = ' . $db->q('*'));

		$db->setQuery($query);

		$menutype = $db->loadResult();

		// Get published site menu modules titles.
		$query->clear()
			->select($db->qn('title'))
			->from($db->qn('#__modules'))
			->where($db->qn('module') . ' = ' . $db->q('mod_menu'))
			->where($db->qn('published') . ' = ' . $db->q('1'))
			->where($db->qn('client_id') . ' = ' . $db->q('0'));

		$db->setQuery($query);

		$menutitles = $db->loadColumn();

		// Do we have a published menu module displaying the default Home menu item set to all languages?
		foreach ($menutitles as $menutitle)
		{
			$module       = self::getModule('mod_menu', $menutitle);
			$moduleParams = new JRegistry($module->params);
			$param        = $moduleParams->get('menutype', '');

			if ($param && $param != $menutype)
			{
				continue;
			}

			return true;
		}
	}

	/**
	 * Get module by name
	 *
	 * @param   string  $moduleName     The name of the module
	 * @param   string  $instanceTitle  The title of the module, optional
	 *
	 * @return  stdClass  The Module object
	 *
	 * @since   3.7.0
	 */
	public static function getModule($moduleName, $instanceTitle = null)
	{
		$db = JFactory::getDbo();

		$query = $db->getQuery(true)
			->select('id, title, module, position, content, showtitle, params')
			->from($db->qn('#__modules'))
			->where($db->qn('module') . ' = ' . $db->q($moduleName))
			->where($db->qn('published') . ' = ' . $db->q('1'))
			->where($db->qn('client_id') . ' = ' . $db->q('0'));

		if ($instanceTitle)
		{
			$query->where($db->qn('title') . ' = ' . $db->q($instanceTitle));
		}

		$db->setQuery($query);

		try
		{
			$modules = $db->loadObject();
		}
		catch (RuntimeException $e)
		{
			JLog::add(JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage()), JLog::WARNING, 'jerror');
		}

		return $modules;
	}
}
PKM�!]Nbf�html/languages.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_languages
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Utility class working with languages
 *
 * @since  1.6
 */
abstract class JHtmlLanguages
{
	/**
	 * Method to generate an information about the default language.
	 *
	 * @param   boolean  $published  True if the language is the default.
	 *
	 * @return  string	HTML code.
	 */
	public static function published($published)
	{
		if (!$published)
		{
			return '&#160;';
		}

		return JHtml::_('image', 'menu/icon-16-default.png', JText::_('COM_LANGUAGES_HEADING_DEFAULT'), null, true);
	}

	/**
	 * Method to generate an input radio button.
	 *
	 * @param   integer  $rowNum    The row number.
	 * @param   string   $language  Language tag.
	 *
	 * @return  string	HTML code.
	 */
	public static function id($rowNum, $language)
	{
		return '<input'
			. ' type="radio"'
			. ' id="cb' . $rowNum . '"'
			. ' name="cid"'
			. ' value="' . htmlspecialchars($language, ENT_COMPAT, 'UTF-8') . '"'
			. ' onclick="Joomla.isChecked(this.checked);"'
			. ' title="' . ($rowNum + 1) . '"'
			. '/>';
	}

	/**
	 * Method to generate an array of clients.
	 *
	 * @return  array of client objects.
	 */
	public static function clients()
	{
		return array(
			JHtml::_('select.option', 0, JText::_('JSITE')),
			JHtml::_('select.option', 1, JText::_('JADMINISTRATOR'))
		);
	}

	/**
	 * Returns an array of published state filter options.
	 *
	 * @return  string  	The HTML code for the select tag.
	 *
	 * @since   1.6
	 */
	public static function publishedOptions()
	{
		// Build the active state filter options.
		$options   = array();
		$options[] = JHtml::_('select.option', '1', 'JPUBLISHED');
		$options[] = JHtml::_('select.option', '0', 'JUNPUBLISHED');
		$options[] = JHtml::_('select.option', '-2', 'JTRASHED');
		$options[] = JHtml::_('select.option', '*', 'JALL');

		return $options;
	}
}
PKM�!]RQ-��
�
jsonresponse.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_languages
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * JSON Response class.
 *
 * @since       2.5
 * @deprecated  4.0
 */
class JJsonResponse
{
	/**
	 * Determines whether the request was successful.
	 *
	 * @var    boolean
	 * @since  2.5
	 */
	public $success = true;

	/**
	 * Determines whether the request wasn't successful.
	 * This is always the negation of $this->success,
	 * so you can use both flags equivalently.
	 *
	 * @var    boolean
	 * @since  2.5
	 */
	public $error = false;

	/**
	 * The main response message.
	 *
	 * @var    string
	 * @since  2.5
	 */
	public $message = null;

	/**
	 * Array of messages gathered in the JApplication object.
	 *
	 * @var    array
	 * @since  2.5
	 */
	public $messages = null;

	/**
	 * The response data.
	 *
	 * @var    mixed
	 * @since  2.5
	 */
	public $data = null;

	/**
	 * Constructor
	 *
	 * @param   mixed    $response  The Response data.
	 * @param   string   $message   The main response message.
	 * @param   boolean  $error     True, if the success flag shall be set to false, defaults to false.
	 *
	 * @since		2.5
	 * @deprecated	4.0	 Use JResponseJson instead.
	 */
	public function __construct($response = null, $message = null, $error = false)
	{
		try
		{
			JLog::add(sprintf('%s is deprecated, use JResponseJson instead.', __CLASS__), JLog::WARNING, 'deprecated');
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		$this->message = $message;

		// Get the message queue.
		$messages = JFactory::getApplication()->getMessageQueue();

		// Build the sorted messages list.
		if (is_array($messages) && count($messages))
		{
			foreach ($messages as $message)
			{
				if (isset($message['type']) && isset($message['message']))
				{
					$lists[$message['type']][] = $message['message'];
				}
			}
		}

		// If messages exist add them to the output.
		if (isset($lists) && is_array($lists))
		{
			$this->messages = $lists;
		}

		// Check if we are dealing with an error.
		if ($response instanceof Exception)
		{
			// Prepare the error response.
			$this->success = false;
			$this->error   = true;
			$this->message = $response->getMessage();
		}
		else
		{
			// Prepare the response data.
			$this->success = !$error;
			$this->error   = $error;
			$this->data    = $response;
		}
	}

	/**
	 * Magic toString method for sending the response in JSON format.
	 *
	 * @return  string  The response in JSON format.
	 *
	 * @since   2.5
	 */
	public function __toString()
	{
		return json_encode($this);
	}
}
PKM�!]��1��
languages.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_languages
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Languages component helper.
 *
 * @since  1.6
 */
class LanguagesHelper
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName   The name of the active view.
	 * @param   int     $client  The client id of the active view. Maybe be 0 or 1.
	 *
	 * @return  void
	 *
	 * @deprecated  4.0 $client parameter is not needed anymore.
	 */
	public static function addSubmenu($vName, $client = 0)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_LANGUAGES_SUBMENU_INSTALLED'),
			'index.php?option=com_languages&view=installed',
			$vName == 'installed'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_LANGUAGES_SUBMENU_CONTENT'),
			'index.php?option=com_languages&view=languages',
			$vName == 'languages'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_LANGUAGES_SUBMENU_OVERRIDES'),
			'index.php?option=com_languages&view=overrides',
			$vName == 'overrides'
		);
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject
	 *
	 * @deprecated  3.2  Use JHelperContent::getActions() instead.
	 */
	public static function getActions()
	{
		// Log usage of deprecated function.
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions.
		return JHelperContent::getActions('com_languages');
	}

	/**
	 * Method for parsing ini files.
	 *
	 * @param   string  $fileName  Path and name of the ini file to parse.
	 *
	 * @return  array   Array of strings found in the file, the array indices will be the keys. On failure an empty array will be returned.
	 *
	 * @since   2.5
	 * @deprecated   3.9.0 Use JLanguageHelper::parseIniFile() instead.
	 */
	public static function parseFile($fileName)
	{
		return JLanguageHelper::parseIniFile($fileName);
	}

	/**
	 * Filter method for language keys.
	 * This method will be called by JForm while filtering the form data.
	 *
	 * @param   string  $value  The language key to filter.
	 *
	 * @return  string	The filtered language key.
	 *
	 * @since		2.5
	 */
	public static function filterKey($value)
	{
		$filter = JFilterInput::getInstance(null, null, 1, 1);

		return strtoupper($filter->clean($value, 'cmd'));
	}

	/**
	 * Filter method for language strings.
	 * This method will be called by JForm while filtering the form data.
	 *
	 * @param   string  $value  The language string to filter.
	 *
	 * @return  string	The filtered language string.
	 *
	 * @since		2.5
	 */
	public static function filterText($value)
	{
		$filter = JFilterInput::getInstance(null, null, 1, 1);

		return $filter->clean($value);
	}
}
PKh�!]�����association.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_content
 *
 * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('ContentHelper', JPATH_ADMINISTRATOR . '/components/com_content/helpers/content.php');
JLoader::register('ContentHelperRoute', JPATH_SITE . '/components/com_content/helpers/route.php');
JLoader::register('CategoryHelperAssociation', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/association.php');

/**
 * Content Component Association Helper
 *
 * @since  3.0
 */
abstract class ContentHelperAssociation extends CategoryHelperAssociation
{
	/**
	 * Method to get the associations for a given item
	 *
	 * @param   integer  $id      Id of the item
	 * @param   string   $view    Name of the view
	 * @param   string   $layout  View layout
	 *
	 * @return  array   Array of associations for the item
	 *
	 * @since  3.0
	 */
	public static function getAssociations($id = 0, $view = null, $layout = null)
	{
		$jinput    = JFactory::getApplication()->input;
		$view      = $view === null ? $jinput->get('view') : $view;
		$component = $jinput->getCmd('option');
		$id        = empty($id) ? $jinput->getInt('id') : $id;

		if ($layout === null && $jinput->get('view') == $view && $component == 'com_content')
		{
			$layout = $jinput->get('layout', '', 'string');
		}

		if ($view === 'article')
		{
			if ($id)
			{
				$user      = JFactory::getUser();
				$groups    = implode(',', $user->getAuthorisedViewLevels());
				$db        = JFactory::getDbo();
				$advClause = array();

				// Filter by user groups
				$advClause[] = 'c2.access IN (' . $groups . ')';

				// Filter by current language
				$advClause[] = 'c2.language != ' . $db->quote(JFactory::getLanguage()->getTag());

				if (!$user->authorise('core.edit.state', 'com_content') && !$user->authorise('core.edit', 'com_content'))
				{
					// Filter by start and end dates.
					$nullDate = $db->quote($db->getNullDate());
					$date = JFactory::getDate();

					$nowDate = $db->quote($date->toSql());

					$advClause[] = '(c2.publish_up = ' . $nullDate . ' OR c2.publish_up <= ' . $nowDate . ')';
					$advClause[] = '(c2.publish_down = ' . $nullDate . ' OR c2.publish_down >= ' . $nowDate . ')';

					// Filter by published
					$advClause[] = 'c2.state = 1';
				}

				$associations = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', $id, 'id', 'alias', 'catid', $advClause);

				$return = array();

				foreach ($associations as $tag => $item)
				{
					$return[$tag] = ContentHelperRoute::getArticleRoute($item->id, (int) $item->catid, $item->language, $layout);
				}

				return $return;
			}
		}

		if ($view === 'category' || $view === 'categories')
		{
			return self::getCategoryAssociations($id, 'com_content', $layout);
		}

		return array();
	}

	/**
	 * Method to display in frontend the associations for a given article
	 *
	 * @param   integer  $id  Id of the article
	 *
	 * @return  array  An array containing the association URL and the related language object
	 *
	 * @since  3.7.0
	 */
	public static function displayAssociations($id)
	{
		$return = array();

		if ($associations = self::getAssociations($id, 'article'))
		{
			$levels    = JFactory::getUser()->getAuthorisedViewLevels();
			$languages = JLanguageHelper::getLanguages();

			foreach ($languages as $language)
			{
				// Do not display language when no association
				if (empty($associations[$language->lang_code]))
				{
					continue;
				}

				// Do not display language without frontend UI
				if (!array_key_exists($language->lang_code, JLanguageHelper::getInstalledLanguages(0)))
				{
					continue;
				}

				// Do not display language without specific home menu
				if (!array_key_exists($language->lang_code, JLanguageMultilang::getSiteHomePages()))
				{
					continue;
				}

				// Do not display language without authorized access level
				if (isset($language->access) && $language->access && !in_array($language->access, $levels))
				{
					continue;
				}

				$return[$language->lang_code] = array('item' => $associations[$language->lang_code], 'language' => $language);
			}
		}

		return $return;
	}
}
PKh�!]�o��icon.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_content
 *
 * @copyright   (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;

/**
 * Content Component HTML Helper
 *
 * @since  1.5
 */
abstract class JHtmlIcon
{
	/**
	 * Method to generate a link to the create item page for the given category
	 *
	 * @param   object    $category  The category information
	 * @param   Registry  $params    The item parameters
	 * @param   array     $attribs   Optional attributes for the link
	 * @param   boolean   $legacy    True to use legacy images, false to use icomoon based graphic
	 *
	 * @return  string  The HTML markup for the create item link
	 */
	public static function create($category, $params, $attribs = array(), $legacy = false)
	{
		$uri = JUri::getInstance();

		$url = 'index.php?option=com_content&task=article.add&return=' . base64_encode($uri) . '&a_id=0&catid=' . $category->id;

		$text = JLayoutHelper::render('joomla.content.icons.create', array('params' => $params, 'legacy' => $legacy));

		// Add the button classes to the attribs array
		if (isset($attribs['class']))
		{
			$attribs['class'] .= ' btn btn-primary';
		}
		else
		{
			$attribs['class'] = 'btn btn-primary';
		}

		$button = JHtml::_('link', JRoute::_($url), $text, $attribs);

		$output = '<span class="hasTooltip" title="' . JHtml::_('tooltipText', 'COM_CONTENT_CREATE_ARTICLE') . '">' . $button . '</span>';

		return $output;
	}

	/**
	 * Method to generate a link to the email item page for the given article
	 *
	 * @param   object    $article  The article information
	 * @param   Registry  $params   The item parameters
	 * @param   array     $attribs  Optional attributes for the link
	 * @param   boolean   $legacy   True to use legacy images, false to use icomoon based graphic
	 *
	 * @return  string  The HTML markup for the email item link
	 *
	 * @deprecated 4.0 The functionality to email an article is removed in Joomla 4
	 */
	public static function email($article, $params, $attribs = array(), $legacy = false)
	{
		JLoader::register('MailtoHelper', JPATH_SITE . '/components/com_mailto/helpers/mailto.php');

		$uri      = JUri::getInstance();
		$base     = $uri->toString(array('scheme', 'host', 'port'));
		$template = JFactory::getApplication()->getTemplate();
		$link     = $base . JRoute::_(ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language), false);
		$url      = 'index.php?option=com_mailto&tmpl=component&template=' . $template . '&link=' . MailtoHelper::addLink($link);

		$height = JFactory::getApplication()->get('captcha', '0') === '0' ? 450 : 550;
		$status = 'width=400,height=' . $height . ',menubar=yes,resizable=yes';

		$text = JLayoutHelper::render('joomla.content.icons.email', array('params' => $params, 'legacy' => $legacy));

		$attribs['title']   = JText::_('JGLOBAL_EMAIL_TITLE');
		$attribs['onclick'] = "window.open(this.href,'win2','" . $status . "'); return false;";
		$attribs['rel']     = 'nofollow';

		return JHtml::_('link', JRoute::_($url), $text, $attribs);
	}

	/**
	 * Display an edit icon for the article.
	 *
	 * This icon will not display in a popup window, nor if the article is trashed.
	 * Edit access checks must be performed in the calling code.
	 *
	 * @param   object    $article  The article information
	 * @param   Registry  $params   The item parameters
	 * @param   array     $attribs  Optional attributes for the link
	 * @param   boolean   $legacy   True to use legacy images, false to use icomoon based graphic
	 *
	 * @return  string	The HTML for the article edit icon.
	 *
	 * @since   1.6
	 */
	public static function edit($article, $params, $attribs = array(), $legacy = false)
	{
		$user = JFactory::getUser();
		$uri  = JUri::getInstance();

		// Ignore if in a popup window.
		if ($params && $params->get('popup'))
		{
			return;
		}

		// Ignore if the state is negative (trashed).
		if ($article->state < 0)
		{
			return;
		}

		// Show checked_out icon if the article is checked out by a different user
		if (property_exists($article, 'checked_out')
			&& property_exists($article, 'checked_out_time')
			&& $article->checked_out > 0
			&& $article->checked_out != $user->get('id'))
		{
			$checkoutUser = JFactory::getUser($article->checked_out);
			$date         = JHtml::_('date', $article->checked_out_time);
			$tooltip      = JText::_('JLIB_HTML_CHECKED_OUT') . ' :: ' . JText::sprintf('COM_CONTENT_CHECKED_OUT_BY', $checkoutUser->name)
				. ' <br /> ' . $date;

			$text = JLayoutHelper::render('joomla.content.icons.edit_lock', array('tooltip' => $tooltip, 'legacy' => $legacy));

			$output = JHtml::_('link', '#', $text, $attribs);

			return $output;
		}

		$contentUrl = ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language);
		$url        = $contentUrl . '&task=article.edit&a_id=' . $article->id . '&return=' . base64_encode($uri);

		if ($article->state == 0)
		{
			$overlib = JText::_('JUNPUBLISHED');
		}
		else
		{
			$overlib = JText::_('JPUBLISHED');
		}

		$date   = JHtml::_('date', $article->created);
		$author = $article->created_by_alias ?: $article->author;

		$overlib .= '&lt;br /&gt;';
		$overlib .= $date;
		$overlib .= '&lt;br /&gt;';
		$overlib .= JText::sprintf('COM_CONTENT_WRITTEN_BY', htmlspecialchars($author, ENT_COMPAT, 'UTF-8'));

		$text = JLayoutHelper::render('joomla.content.icons.edit', array('article' => $article, 'overlib' => $overlib, 'legacy' => $legacy));

		$attribs['title']   = JText::_('JGLOBAL_EDIT_TITLE');
		$output = JHtml::_('link', JRoute::_($url), $text, $attribs);

		return $output;
	}

	/**
	 * Method to generate a popup link to print an article
	 *
	 * @param   object    $article  The article information
	 * @param   Registry  $params   The item parameters
	 * @param   array     $attribs  Optional attributes for the link
	 * @param   boolean   $legacy   True to use legacy images, false to use icomoon based graphic
	 *
	 * @return  string  The HTML markup for the popup link
	 */
	public static function print_popup($article, $params, $attribs = array(), $legacy = false)
	{
		$url  = ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language);
		$url .= '&tmpl=component&print=1&layout=default';

		$status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,width=640,height=480,directories=no,location=no';

		$text = JLayoutHelper::render('joomla.content.icons.print_popup', array('params' => $params, 'legacy' => $legacy));

		$attribs['title']   = JText::sprintf('JGLOBAL_PRINT_TITLE', htmlspecialchars($article->title, ENT_QUOTES, 'UTF-8'));
		$attribs['onclick'] = "window.open(this.href,'win2','" . $status . "'); return false;";
		$attribs['rel']     = 'nofollow';

		return JHtml::_('link', JRoute::_($url), $text, $attribs);
	}

	/**
	 * Method to generate a link to print an article
	 *
	 * @param   object    $article  Not used, @deprecated for 4.0
	 * @param   Registry  $params   The item parameters
	 * @param   array     $attribs  Not used, @deprecated for 4.0
	 * @param   boolean   $legacy   True to use legacy images, false to use icomoon based graphic
	 *
	 * @return  string  The HTML markup for the popup link
	 */
	public static function print_screen($article, $params, $attribs = array(), $legacy = false)
	{
		$text = JLayoutHelper::render('joomla.content.icons.print_screen', array('params' => $params, 'legacy' => $legacy));

		return '<a href="#" onclick="window.print();return false;">' . $text . '</a>';
	}
}
PKh�!]�oh			query.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_content
 *
 * @copyright   (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Content Component Query Helper
 *
 * @since  1.5
 */
class ContentHelperQuery
{
	/**
	 * Translate an order code to a field for primary category ordering.
	 *
	 * @param   string  $orderby  The ordering code.
	 *
	 * @return  string  The SQL field(s) to order by.
	 *
	 * @since   1.5
	 */
	public static function orderbyPrimary($orderby)
	{
		switch ($orderby)
		{
			case 'alpha' :
				$orderby = 'c.path, ';
				break;

			case 'ralpha' :
				$orderby = 'c.path DESC, ';
				break;

			case 'order' :
				$orderby = 'c.lft, ';
				break;

			default :
				$orderby = '';
				break;
		}

		return $orderby;
	}

	/**
	 * Translate an order code to a field for secondary category ordering.
	 *
	 * @param   string  $orderby    The ordering code.
	 * @param   string  $orderDate  The ordering code for the date.
	 *
	 * @return  string  The SQL field(s) to order by.
	 *
	 * @since   1.5
	 */
	public static function orderbySecondary($orderby, $orderDate = 'created')
	{
		$queryDate = self::getQueryDate($orderDate);

		switch ($orderby)
		{
			case 'date' :
				$orderby = $queryDate;
				break;

			case 'rdate' :
				$orderby = $queryDate . ' DESC ';
				break;

			case 'alpha' :
				$orderby = 'a.title';
				break;

			case 'ralpha' :
				$orderby = 'a.title DESC';
				break;

			case 'hits' :
				$orderby = 'a.hits DESC';
				break;

			case 'rhits' :
				$orderby = 'a.hits';
				break;

			case 'order' :
				$orderby = 'a.ordering';
				break;

			case 'rorder' :
				$orderby = 'a.ordering DESC';
				break;

			case 'author' :
				$orderby = 'author';
				break;

			case 'rauthor' :
				$orderby = 'author DESC';
				break;

			case 'front' :
				$orderby = 'a.featured DESC, fp.ordering, ' . $queryDate . ' DESC ';
				break;

			case 'random' :
				$orderby = JFactory::getDbo()->getQuery(true)->Rand();
				break;

			case 'vote' :
				$orderby = 'a.id DESC ';

				if (JPluginHelper::isEnabled('content', 'vote'))
				{
					$orderby = 'rating_count DESC ';
				}
				break;

			case 'rvote' :
				$orderby = 'a.id ASC ';

				if (JPluginHelper::isEnabled('content', 'vote'))
				{
					$orderby = 'rating_count ASC ';
				}
				break;

			case 'rank' :
				$orderby = 'a.id DESC ';

				if (JPluginHelper::isEnabled('content', 'vote'))
				{
					$orderby = 'rating DESC ';
				}
				break;

			case 'rrank' :
				$orderby = 'a.id ASC ';

				if (JPluginHelper::isEnabled('content', 'vote'))
				{
					$orderby = 'rating ASC ';
				}
				break;

			default :
				$orderby = 'a.ordering';
				break;
		}

		return $orderby;
	}

	/**
	 * Translate an order code to a field for primary category ordering.
	 *
	 * @param   string  $orderDate  The ordering code.
	 *
	 * @return  string  The SQL field(s) to order by.
	 *
	 * @since   1.6
	 */
	public static function getQueryDate($orderDate)
	{
		$db = JFactory::getDbo();

		switch ($orderDate)
		{
			case 'modified' :
				$queryDate = ' CASE WHEN a.modified = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.modified END';
				break;

			// Use created if publish_up is not set
			case 'published' :
				$queryDate = ' CASE WHEN a.publish_up = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.publish_up END ';
				break;

			case 'unpublished' :
				$queryDate = ' CASE WHEN a.publish_down = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.publish_down END ';
				break;
			case 'created' :
			default :
				$queryDate = ' a.created ';
				break;
		}

		return $queryDate;
	}

	/**
	 * Get join information for the voting query.
	 *
	 * @param   \Joomla\Registry\Registry  $params  An options object for the article.
	 *
	 * @return  array  A named array with "select" and "join" keys.
	 *
	 * @since   1.5
	 */
	public static function buildVotingQuery($params = null)
	{
		if (!$params)
		{
			$params = JComponentHelper::getParams('com_content');
		}

		$voting = $params->get('show_vote');

		if ($voting)
		{
			// Calculate voting count
			$select = ' , ROUND(v.rating_sum / v.rating_count) AS rating, v.rating_count';
			$join = ' LEFT JOIN #__content_rating AS v ON a.id = v.content_id';
		}
		else
		{
			$select = '';
			$join = '';
		}

		return array('select' => $select, 'join' => $join);
	}

	/**
	 * Method to order the intro articles array for ordering
	 * down the columns instead of across.
	 * The layout always lays the introtext articles out across columns.
	 * Array is reordered so that, when articles are displayed in index order
	 * across columns in the layout, the result is that the
	 * desired article ordering is achieved down the columns.
	 *
	 * @param   array    &$articles   Array of intro text articles
	 * @param   integer  $numColumns  Number of columns in the layout
	 *
	 * @return  array  Reordered array to achieve desired ordering down columns
	 *
	 * @since       1.6
	 * @deprecated  4.0 
	 */
	public static function orderDownColumns(&$articles, $numColumns = 1)
	{
		$count = count($articles);

		// Just return the same array if there is nothing to change
		if ($numColumns == 1 || !is_array($articles) || $count <= $numColumns)
		{
			$return = $articles;
		}
		// We need to re-order the intro articles array
		else
		{
			// We need to preserve the original array keys
			$keys = array_keys($articles);

			$maxRows = ceil($count / $numColumns);
			$numCells = $maxRows * $numColumns;
			$numEmpty = $numCells - $count;
			$index = array();

			// Calculate number of empty cells in the array

			// Fill in all cells of the array
			// Put -1 in empty cells so we can skip later
			for ($row = 1, $i = 1; $row <= $maxRows; $row++)
			{
				for ($col = 1; $col <= $numColumns; $col++)
				{
					if ($numEmpty > ($numCells - $i))
					{
						// Put -1 in empty cells
						$index[$row][$col] = -1;
					}
					else
					{
						// Put in zero as placeholder
						$index[$row][$col] = 0;
					}

					$i++;
				}
			}

			// Layout the articles in column order, skipping empty cells
			$i = 0;

			for ($col = 1; ($col <= $numColumns) && ($i < $count); $col++)
			{
				for ($row = 1; ($row <= $maxRows) && ($i < $count); $row++)
				{
					if ($index[$row][$col] != - 1)
					{
						$index[$row][$col] = $keys[$i];
						$i++;
					}
				}
			}

			// Now read the $index back row by row to get articles in right row/col
			// so that they will actually be ordered down the columns (when read by row in the layout)
			$return = array();
			$i = 0;

			for ($row = 1; ($row <= $maxRows) && ($i < $count); $row++)
			{
				for ($col = 1; ($col <= $numColumns) && ($i < $count); $col++)
				{
					$return[$keys[$i]] = $articles[$index[$row][$col]];
					$i++;
				}
			}
		}

		return $return;
	}
}
PKh�!]coJ�o'o'legacyrouter.phpnu&1i�<?php
/**
 * @package     Joomla.Site
 * @subpackage  com_content
 *
 * @copyright   (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Legacy routing rules class from com_content
 *
 * @since       3.6
 * @deprecated  4.0
 */
class ContentRouterRulesLegacy implements JComponentRouterRulesInterface
{
	/**
	 * Constructor for this legacy router
	 *
	 * @param   JComponentRouterView  $router  The router this rule belongs to
	 *
	 * @since       3.6
	 * @deprecated  4.0
	 */
	public function __construct($router)
	{
		$this->router = $router;
	}

	/**
	 * Preprocess the route for the com_content component
	 *
	 * @param   array  &$query  An array of URL arguments
	 *
	 * @return  void
	 *
	 * @since       3.6
	 * @deprecated  4.0
	 */
	public function preprocess(&$query)
	{
	}

	/**
	 * Build the route for the com_content component
	 *
	 * @param   array  &$query     An array of URL arguments
	 * @param   array  &$segments  The URL arguments to use to assemble the subsequent URL.
	 *
	 * @return  void
	 *
	 * @since       3.6
	 * @deprecated  4.0
	 */
	public function build(&$query, &$segments)
	{
		// Get a menu item based on Itemid or currently active
		$params = JComponentHelper::getParams('com_content');
		$advanced = $params->get('sef_advanced_link', 0);

		// We need a menu item.  Either the one specified in the query, or the current active one if none specified
		if (empty($query['Itemid']))
		{
			$menuItem = $this->router->menu->getActive();
			$menuItemGiven = false;
		}
		else
		{
			$menuItem = $this->router->menu->getItem($query['Itemid']);
			$menuItemGiven = true;
		}

		// Check again
		if ($menuItemGiven && isset($menuItem) && $menuItem->component != 'com_content')
		{
			$menuItemGiven = false;
			unset($query['Itemid']);
		}

		if (isset($query['view']))
		{
			$view = $query['view'];
		}
		else
		{
			// We need to have a view in the query or it is an invalid URL
			return;
		}

		// Are we dealing with an article or category that is attached to a menu item?
		if ($menuItem !== null
			&& isset($menuItem->query['view'], $query['view'], $menuItem->query['id'], $query['id'])
			&& $menuItem->query['view'] == $query['view']
			&& $menuItem->query['id'] == (int) $query['id'])
		{
			unset($query['view']);

			if (isset($query['catid']))
			{
				unset($query['catid']);
			}

			if (isset($query['layout']))
			{
				unset($query['layout']);
			}

			unset($query['id']);

			return;
		}

		if ($view == 'category' || $view == 'article')
		{
			if (!$menuItemGiven)
			{
				$segments[] = $view;
			}

			unset($query['view']);

			if ($view == 'article')
			{
				if (isset($query['id']) && isset($query['catid']) && $query['catid'])
				{
					$catid = $query['catid'];

					// Make sure we have the id and the alias
					if (strpos($query['id'], ':') === false)
					{
						$db = JFactory::getDbo();
						$dbQuery = $db->getQuery(true)
							->select('alias')
							->from('#__content')
							->where('id=' . (int) $query['id']);
						$db->setQuery($dbQuery);
						$alias = $db->loadResult();
						$query['id'] = $query['id'] . ':' . $alias;
					}
				}
				else
				{
					// We should have these two set for this view.  If we don't, it is an error
					return;
				}
			}
			else
			{
				if (isset($query['id']))
				{
					$catid = $query['id'];
				}
				else
				{
					// We should have id set for this view.  If we don't, it is an error
					return;
				}
			}

			if ($menuItemGiven && isset($menuItem->query['id']))
			{
				$mCatid = $menuItem->query['id'];
			}
			else
			{
				$mCatid = 0;
			}

			$categories = JCategories::getInstance('Content');
			$category = $categories->get($catid);

			if (!$category)
			{
				// We couldn't find the category we were given.  Bail.
				return;
			}

			$path = array_reverse($category->getPath());

			$array = array();

			foreach ($path as $id)
			{
				if ((int) $id == (int) $mCatid)
				{
					break;
				}

				list($tmp, $id) = explode(':', $id, 2);

				$array[] = $id;
			}

			$array = array_reverse($array);

			if (!$advanced && count($array))
			{
				$array[0] = (int) $catid . ':' . $array[0];
			}

			$segments = array_merge($segments, $array);

			if ($view == 'article')
			{
				if ($advanced)
				{
					list($tmp, $id) = explode(':', $query['id'], 2);
				}
				else
				{
					$id = $query['id'];
				}

				$segments[] = $id;
			}

			unset($query['id'], $query['catid']);
		}

		if ($view == 'archive')
		{
			if (!$menuItemGiven)
			{
				$segments[] = $view;
				unset($query['view']);
			}

			if (isset($query['year']))
			{
				if ($menuItemGiven)
				{
					$segments[] = $query['year'];
					unset($query['year']);
				}
			}

			if (isset($query['year']) && isset($query['month']))
			{
				if ($menuItemGiven)
				{
					$segments[] = $query['month'];
					unset($query['month']);
				}
			}
		}

		if ($view == 'featured')
		{
			if (!$menuItemGiven)
			{
				$segments[] = $view;
			}

			unset($query['view']);
		}

		/*
		 * If the layout is specified and it is the same as the layout in the menu item, we
		 * unset it so it doesn't go into the query string.
		 */
		if (isset($query['layout']))
		{
			if ($menuItemGiven && isset($menuItem->query['layout']))
			{
				if ($query['layout'] == $menuItem->query['layout'])
				{
					unset($query['layout']);
				}
			}
			else
			{
				if ($query['layout'] == 'default')
				{
					unset($query['layout']);
				}
			}
		}

		$total = count($segments);

		for ($i = 0; $i < $total; $i++)
		{
			$segments[$i] = str_replace(':', '-', $segments[$i]);
		}
	}

	/**
	 * Parse the segments of a URL.
	 *
	 * @param   array  &$segments  The segments of the URL to parse.
	 * @param   array  &$vars      The URL attributes to be used by the application.
	 *
	 * @return  void
	 *
	 * @since       3.6
	 * @deprecated  4.0
	 */
	public function parse(&$segments, &$vars)
	{
		$total = count($segments);

		for ($i = 0; $i < $total; $i++)
		{
			$segments[$i] = preg_replace('/-/', ':', $segments[$i], 1);
		}

		// Get the active menu item.
		$item = $this->router->menu->getActive();
		$params = JComponentHelper::getParams('com_content');
		$advanced = $params->get('sef_advanced_link', 0);
		$db = JFactory::getDbo();

		// Count route segments
		$count = count($segments);

		/*
		 * Standard routing for articles.  If we don't pick up an Itemid then we get the view from the segments
		 * the first segment is the view and the last segment is the id of the article or category.
		 */
		if (!isset($item))
		{
			$vars['view'] = $segments[0];
			$vars['id'] = $segments[$count - 1];

			return;
		}

		/*
		 * If there is only one segment, then it points to either an article or a category.
		 * We test it first to see if it is a category.  If the id and alias match a category,
		 * then we assume it is a category.  If they don't we assume it is an article
		 */
		if ($count == 1)
		{
			// We check to see if an alias is given.  If not, we assume it is an article
			if (strpos($segments[0], ':') === false)
			{
				$vars['view'] = 'article';
				$vars['id'] = (int) $segments[0];

				return;
			}

			list($id, $alias) = explode(':', $segments[0], 2);

			// First we check if it is a category
			$category = JCategories::getInstance('Content')->get($id);

			if ($category && $category->alias == $alias)
			{
				$vars['view'] = 'category';
				$vars['id'] = $id;

				return;
			}
			else
			{
				$query = $db->getQuery(true)
					->select($db->quoteName(array('alias', 'catid')))
					->from($db->quoteName('#__content'))
					->where($db->quoteName('id') . ' = ' . (int) $id);
				$db->setQuery($query);
				$article = $db->loadObject();

				if ($article)
				{
					if ($article->alias == $alias)
					{
						$vars['view'] = 'article';
						$vars['catid'] = (int) $article->catid;
						$vars['id'] = (int) $id;

						return;
					}
				}
			}
		}

		/*
		 * If there was more than one segment, then we can determine where the URL points to
		 * because the first segment will have the target category id prepended to it.  If the
		 * last segment has a number prepended, it is an article, otherwise, it is a category.
		 */
		if (!$advanced)
		{
			$cat_id = (int) $segments[0];

			$article_id = (int) $segments[$count - 1];

			if ($article_id > 0)
			{
				$vars['view'] = 'article';
				$vars['catid'] = $cat_id;
				$vars['id'] = $article_id;
			}
			else
			{
				$vars['view'] = 'category';
				$vars['id'] = $cat_id;
			}

			return;
		}

		// We get the category id from the menu item and search from there
		$id = $item->query['id'];
		$category = JCategories::getInstance('Content')->get($id);

		if (!$category)
		{
			JError::raiseError(404, JText::_('COM_CONTENT_ERROR_PARENT_CATEGORY_NOT_FOUND'));

			return;
		}

		$categories = $category->getChildren();
		$vars['catid'] = $id;
		$vars['id'] = $id;
		$found = 0;

		foreach ($segments as $segment)
		{
			$segment = str_replace(':', '-', $segment);

			foreach ($categories as $category)
			{
				if ($category->alias == $segment)
				{
					$vars['id'] = $category->id;
					$vars['catid'] = $category->id;
					$vars['view'] = 'category';
					$categories = $category->getChildren();
					$found = 1;
					break;
				}
			}

			if ($found == 0)
			{
				if ($advanced)
				{
					$db = JFactory::getDbo();
					$query = $db->getQuery(true)
						->select($db->quoteName('id'))
						->from('#__content')
						->where($db->quoteName('catid') . ' = ' . (int) $vars['catid'])
						->where($db->quoteName('alias') . ' = ' . $db->quote($segment));
					$db->setQuery($query);
					$cid = $db->loadResult();
				}
				else
				{
					$cid = $segment;
				}

				$vars['id'] = $cid;

				if ($item->query['view'] == 'archive' && $count != 1)
				{
					$vars['year'] = $count >= 2 ? $segments[$count - 2] : null;
					$vars['month'] = $segments[$count - 1];
					$vars['view'] = 'archive';
				}
				else
				{
					$vars['view'] = 'article';
				}
			}

			$found = 0;
		}
	}
}
PK"�!]^�Vrrhtml/modules.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_modules
 *
 * @copyright   (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * JHtml module helper class.
 *
 * @since  1.6
 */
abstract class JHtmlModules
{
	/**
	 * Builds an array of template options
	 *
	 * @param   integer  $clientId  The client id.
	 * @param   string   $state     The state of the template.
	 *
	 * @return  array
	 */
	public static function templates($clientId = 0, $state = '')
	{
		$options   = array();
		$templates = ModulesHelper::getTemplates($clientId, $state);

		foreach ($templates as $template)
		{
			$options[] = JHtml::_('select.option', $template->element, $template->name);
		}

		return $options;
	}

	/**
	 * Builds an array of template type options
	 *
	 * @return  array
	 */
	public static function types()
	{
		$options = array();
		$options[] = JHtml::_('select.option', 'user', 'COM_MODULES_OPTION_POSITION_USER_DEFINED');
		$options[] = JHtml::_('select.option', 'template', 'COM_MODULES_OPTION_POSITION_TEMPLATE_DEFINED');

		return $options;
	}

	/**
	 * Builds an array of template state options
	 *
	 * @return  array
	 */
	public static function templateStates()
	{
		$options = array();
		$options[] = JHtml::_('select.option', '1', 'JENABLED');
		$options[] = JHtml::_('select.option', '0', 'JDISABLED');

		return $options;
	}

	/**
	 * Returns a published state on a grid
	 *
	 * @param   integer  $value     The state value.
	 * @param   integer  $i         The row index
	 * @param   boolean  $enabled   An optional setting for access control on the action.
	 * @param   string   $checkbox  An optional prefix for checkboxes.
	 *
	 * @return  string        The Html code
	 *
	 * @see     JHtmlJGrid::state
	 * @since   1.7.1
	 */
	public static function state($value, $i, $enabled = true, $checkbox = 'cb')
	{
		$states = array(
			1  => array(
				'unpublish',
				'COM_MODULES_EXTENSION_PUBLISHED_ENABLED',
				'COM_MODULES_HTML_UNPUBLISH_ENABLED',
				'COM_MODULES_EXTENSION_PUBLISHED_ENABLED',
				true,
				'publish',
				'publish',
			),
			0  => array(
				'publish',
				'COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED',
				'COM_MODULES_HTML_PUBLISH_ENABLED',
				'COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED',
				true,
				'unpublish',
				'unpublish',
			),
			-1 => array(
				'unpublish',
				'COM_MODULES_EXTENSION_PUBLISHED_DISABLED',
				'COM_MODULES_HTML_UNPUBLISH_DISABLED',
				'COM_MODULES_EXTENSION_PUBLISHED_DISABLED',
				true,
				'warning',
				'warning',
			),
			-2 => array(
				'publish',
				'COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED',
				'COM_MODULES_HTML_PUBLISH_DISABLED',
				'COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED',
				true,
				'unpublish',
				'unpublish',
			),
		);

		return JHtml::_('jgrid.state', $states, $value, $i, 'modules.', $enabled, true, $checkbox);
	}

	/**
	 * Display a batch widget for the module position selector.
	 *
	 * @param   integer  $clientId          The client ID.
	 * @param   integer  $state             The state of the module (enabled, unenabled, trashed).
	 * @param   string   $selectedPosition  The currently selected position for the module.
	 *
	 * @return  string   The necessary positions for the widget.
	 *
	 * @since   2.5
	 */
	public static function positions($clientId, $state = 1, $selectedPosition = '')
	{
		JLoader::register('TemplatesHelper', JPATH_ADMINISTRATOR . '/components/com_templates/helpers/templates.php');

		$templates      = array_keys(ModulesHelper::getTemplates($clientId, $state));
		$templateGroups = array();

		// Add an empty value to be able to deselect a module position
		$option = ModulesHelper::createOption();
		$templateGroups[''] = ModulesHelper::createOptionGroup('', array($option));

		// Add positions from templates
		$isTemplatePosition = false;

		foreach ($templates as $template)
		{
			$options = array();

			$positions = TemplatesHelper::getPositions($clientId, $template);

			if (is_array($positions))
			{
				foreach ($positions as $position)
				{
					$text = ModulesHelper::getTranslatedModulePosition($clientId, $template, $position) . ' [' . $position . ']';
					$options[] = ModulesHelper::createOption($position, $text);

					if (!$isTemplatePosition && $selectedPosition === $position)
					{
						$isTemplatePosition = true;
					}
				}

				$options = ArrayHelper::sortObjects($options, 'text');
			}

			$templateGroups[$template] = ModulesHelper::createOptionGroup(ucfirst($template), $options);
		}

		// Add custom position to options
		$customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION');

		$editPositions = true;
		$customPositions = ModulesHelper::getPositions($clientId, $editPositions);
		$templateGroups[$customGroupText] = ModulesHelper::createOptionGroup($customGroupText, $customPositions);

		return $templateGroups;
	}

	/**
	 * Get a select with the batch action options
	 *
	 * @return  void
	 */
	public static function batchOptions()
	{
		// Create the copy/move options.
		$options = array(
			JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')),
			JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE'))
		);

		echo JHtml::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm');
	}

	/**
	 * Method to get the field options.
	 *
	 * @param   integer  $clientId  The client ID
	 *
	 * @return  array  The field option objects.
	 *
	 * @since   2.5
	 */
	public static function positionList($clientId = 0)
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('DISTINCT(position) as value')
			->select('position as text')
			->from($db->quoteName('#__modules'))
			->where($db->quoteName('client_id') . ' = ' . (int) $clientId)
			->order('position');

		// Get the options.
		$db->setQuery($query);

		try
		{
			$options = $db->loadObjectList();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());
		}

		// Pop the first item off the array if it's blank
		if (count($options))
		{
			if (strlen($options[0]->text) < 1)
			{
				array_shift($options);
			}
		}

		return $options;
	}
}
PK"�!]���&#&#modules.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_modules
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

/**
 * Modules component helper.
 *
 * @since  1.6
 */
abstract class ModulesHelper
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 */
	public static function addSubmenu($vName)
	{
		// Not used in this component.
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @param   integer  $moduleId  The module ID.
	 *
	 * @return  JObject
	 *
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions($moduleId = 0)
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		if (empty($moduleId))
		{
			$result = JHelperContent::getActions('com_modules');
		}
		else
		{
			$result = JHelperContent::getActions('com_modules', 'module', $moduleId);
		}

		return $result;
	}

	/**
	 * Get a list of filter options for the state of a module.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 */
	public static function getStateOptions()
	{
		// Build the filter options.
		$options   = array();
		$options[] = JHtml::_('select.option', '1', JText::_('JPUBLISHED'));
		$options[] = JHtml::_('select.option', '0', JText::_('JUNPUBLISHED'));
		$options[] = JHtml::_('select.option', '-2', JText::_('JTRASHED'));
		$options[] = JHtml::_('select.option', '*', JText::_('JALL'));

		return $options;
	}

	/**
	 * Get a list of filter options for the application clients.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 */
	public static function getClientOptions()
	{
		// Build the filter options.
		$options   = array();
		$options[] = JHtml::_('select.option', '0', JText::_('JSITE'));
		$options[] = JHtml::_('select.option', '1', JText::_('JADMINISTRATOR'));

		return $options;
	}

	/**
	 * Get a list of modules positions
	 *
	 * @param   integer  $clientId       Client ID
	 * @param   boolean  $editPositions  Allow to edit the positions
	 *
	 * @return  array  A list of positions
	 */
	public static function getPositions($clientId, $editPositions = false)
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('DISTINCT(position)')
			->from('#__modules')
			->where($db->quoteName('client_id') . ' = ' . (int) $clientId)
			->order('position');

		$db->setQuery($query);

		try
		{
			$positions = $db->loadColumn();
			$positions = is_array($positions) ? $positions : array();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());

			return;
		}

		// Build the list
		$options = array();

		foreach ($positions as $position)
		{
			if (!$position && !$editPositions)
			{
				$options[] = JHtml::_('select.option', 'none', JText::_('COM_MODULES_NONE'));
			}
			else
			{
				$options[] = JHtml::_('select.option', $position, $position);
			}
		}

		return $options;
	}

	/**
	 * Return a list of templates
	 *
	 * @param   integer  $clientId  Client ID
	 * @param   string   $state     State
	 * @param   string   $template  Template name
	 *
	 * @return  array  List of templates
	 */
	public static function getTemplates($clientId = 0, $state = '', $template = '')
	{
		$db = JFactory::getDbo();

		// Get the database object and a new query object.
		$query = $db->getQuery(true);

		// Build the query.
		$query->select('element, name, enabled')
			->from('#__extensions')
			->where('client_id = ' . (int) $clientId)
			->where('type = ' . $db->quote('template'));

		if ($state != '')
		{
			$query->where('enabled = ' . $db->quote($state));
		}

		if ($template != '')
		{
			$query->where('element = ' . $db->quote($template));
		}

		// Set the query and load the templates.
		$db->setQuery($query);
		$templates = $db->loadObjectList('element');

		return $templates;
	}

	/**
	 * Get a list of the unique modules installed in the client application.
	 *
	 * @param   int  $clientId  The client id.
	 *
	 * @return  array  Array of unique modules
	 */
	public static function getModules($clientId)
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('element AS value, name AS text')
			->from('#__extensions as e')
			->where('e.client_id = ' . (int) $clientId)
			->where('type = ' . $db->quote('module'))
			->join('LEFT', '#__modules as m ON m.module=e.element AND m.client_id=e.client_id')
			->where('m.module IS NOT NULL')
			->group('element,name');

		$db->setQuery($query);
		$modules = $db->loadObjectList();
		$lang = JFactory::getLanguage();

		foreach ($modules as $i => $module)
		{
			$extension = $module->value;
			$path = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE;
			$source = $path . "/modules/$extension";
				$lang->load("$extension.sys", $path, null, false, true)
			||	$lang->load("$extension.sys", $source, null, false, true);
			$modules[$i]->text = JText::_($module->text);
		}

		$modules = ArrayHelper::sortObjects($modules, 'text', 1, true, true);

		return $modules;
	}

	/**
	 * Get a list of the assignment options for modules to menus.
	 *
	 * @param   int  $clientId  The client id.
	 *
	 * @return  array
	 */
	public static function getAssignmentOptions($clientId)
	{
		$options = array();
		$options[] = JHtml::_('select.option', '0', 'COM_MODULES_OPTION_MENU_ALL');
		$options[] = JHtml::_('select.option', '-', 'COM_MODULES_OPTION_MENU_NONE');

		if ($clientId == 0)
		{
			$options[] = JHtml::_('select.option', '1', 'COM_MODULES_OPTION_MENU_INCLUDE');
			$options[] = JHtml::_('select.option', '-1', 'COM_MODULES_OPTION_MENU_EXCLUDE');
		}

		return $options;
	}

	/**
	 * Return a translated module position name
	 *
	 * @param   integer  $clientId  Application client id 0: site | 1: admin
	 * @param   string   $template  Template name
	 * @param   string   $position  Position name
	 *
	 * @return  string  Return a translated position name
	 *
	 * @since   3.0
	 */
	public static function getTranslatedModulePosition($clientId, $template, $position)
	{
		// Template translation
		$lang = JFactory::getLanguage();
		$path = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE;

		$loaded = $lang->getPaths('tpl_' . $template . '.sys');

		// Only load the template's language file if it hasn't been already
		if (!$loaded)
		{
			$lang->load('tpl_' . $template . '.sys', $path, null, false, false)
			||	$lang->load('tpl_' . $template . '.sys', $path . '/templates/' . $template, null, false, false)
			||	$lang->load('tpl_' . $template . '.sys', $path, $lang->getDefault(), false, false)
			||	$lang->load('tpl_' . $template . '.sys', $path . '/templates/' . $template, $lang->getDefault(), false, false);
		}

		$langKey = strtoupper('TPL_' . $template . '_POSITION_' . $position);
		$text = JText::_($langKey);

		// Avoid untranslated strings
		if (!self::isTranslatedText($langKey, $text))
		{
			// Modules component translation
			$langKey = strtoupper('COM_MODULES_POSITION_' . $position);
			$text = JText::_($langKey);

			// Avoid untranslated strings
			if (!self::isTranslatedText($langKey, $text))
			{
				// Try to humanize the position name
				$text = ucfirst(preg_replace('/^' . $template . '\-/', '', $position));
				$text = ucwords(str_replace(array('-', '_'), ' ', $text));
			}
		}

		return $text;
	}

	/**
	 * Check if the string was translated
	 *
	 * @param   string  $langKey  Language file text key
	 * @param   string  $text     The "translated" text to be checked
	 *
	 * @return  boolean  Return true for translated text
	 *
	 * @since   3.0
	 */
	public static function isTranslatedText($langKey, $text)
	{
		return $text !== $langKey;
	}

	/**
	 * Create and return a new Option
	 *
	 * @param   string  $value  The option value [optional]
	 * @param   string  $text   The option text [optional]
	 *
	 * @return  object  The option as an object (stdClass instance)
	 *
	 * @since   3.0
	 */
	public static function createOption($value = '', $text = '')
	{
		if (empty($text))
		{
			$text = $value;
		}

		$option = new stdClass;
		$option->value = $value;
		$option->text  = $text;

		return $option;
	}

	/**
	 * Create and return a new Option Group
	 *
	 * @param   string  $label    Value and label for group [optional]
	 * @param   array   $options  Array of options to insert into group [optional]
	 *
	 * @return  array  Return the new group as an array
	 *
	 * @since   3.0
	 */
	public static function createOptionGroup($label = '', $options = array())
	{
		$group = array();
		$group['value'] = $label;
		$group['text']  = $label;
		$group['items'] = $options;

		return $group;
	}
}
PK"�!]GU����xml.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_modules
 *
 * @copyright   (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

try
{
	JLog::add('ModulesHelperXML is deprecated. Do not use.', JLog::WARNING, 'deprecated');
}
catch (RuntimeException $exception)
{
	// Informational log only
}

/**
 * Helper for parse XML module files
 *
 * @since       1.5
 * @deprecated  3.2  Do not use.
 */
class ModulesHelperXML
{
	/**
	 * Parse the module XML file
	 *
	 * @param   array  &$rows  XML rows
	 *
	 * @return  void
	 *
	 * @since       1.5
	 *
	 * @deprecated  3.2  Do not use.
	 */
	public function parseXMLModuleFile(&$rows)
	{
		foreach ($rows as $i => $row)
		{
			if ($row->module == '')
			{
				$rows[$i]->name    = 'custom';
				$rows[$i]->module  = 'custom';
				$rows[$i]->descrip = 'Custom created module, using Module Manager New function';
			}
			else
			{
				$data = JInstaller::parseXMLInstallFile($row->path . '/' . $row->file);

				if ($data['type'] == 'module')
				{
					$rows[$i]->name    = $data['name'];
					$rows[$i]->descrip = $data['description'];
				}
			}
		}
	}
}
PK�!]�‚-vvtags.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_tags
 *
 * @copyright   (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Tags helper.
 *
 * @since       3.1
 * @deprecated  4.0
 */
class TagsHelper extends JHelperContent
{
	/**
	 * Configure the Submenu links.
	 *
	 * @param   string  $extension  The extension.
	 *
	 * @return  void
	 *
	 * @since       3.1
	 * @deprecated  4.0
	 */
	public static function addSubmenu($extension)
	{
		$parts     = explode('.', $extension);
		$component = $parts[0];

		// Avoid nonsense situation.
		if ($component == 'tags')
		{
			return;
		}

		// Try to find the component helper.
		$file = JPath::clean(JPATH_ADMINISTRATOR . '/components/com_tags/helpers/tags.php');

		if (file_exists($file))
		{
			$cName = 'TagsHelper';

			JLoader::register($cName, $file);

			if (class_exists($cName))
			{
				if (is_callable(array($cName, 'addSubmenu')))
				{
					$lang = JFactory::getLanguage();

					// Loading language file from administrator/language directory then administrator/components/<extension>/language
					$lang->load($component, JPATH_BASE, null, false, true)
					||	$lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true);
				}
			}
		}
	}
}
PKB�!]��L�
�
djimageslider.phpnu&1i�<?php
/**
 * @version $Id$
 * @package DJ-ImageSlider
 * @subpackage DJ-ImageSlider Component
 * @copyright Copyright (C) 2017 DJ-Extensions.com, All rights reserved.
 * @license http://www.gnu.org/licenses GNU/GPL
 * @author url: http://dj-extensions.com
 * @author email contact@dj-extensions.com
 * @developer Szymon Woronowski - szymon.woronowski@design-joomla.eu
 *
 *
 * DJ-ImageSlider is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DJ-ImageSlider is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with DJ-ImageSlider. If not, see <http://www.gnu.org/licenses/>.
 *
 */

defined('_JEXEC') or die;

abstract class DJImageSliderHelper
{
	
	public static function addSubmenu($vName)
	{
		if($vName=='item' || $vName=='category') return;
		$version = new JVersion;
		
		if (version_compare($version->getShortVersion(), '3.0.0', '<')) {
			
			JSubMenuHelper::addEntry(
				JText::_('COM_DJIMAGESLIDER_SUBMENU_CPANEL'),
				'index.php?option=com_djimageslider',
				$vName == 'cpanel'
			);
			JSubMenuHelper::addEntry(
				JText::_('COM_DJIMAGESLIDER_SUBMENU_SLIDES'),
				'index.php?option=com_djimageslider&view=items',
				$vName == 'items'
			);
			JSubMenuHelper::addEntry(
				JText::_('COM_DJIMAGESLIDER_SUBMENU_CATEGORIES'),
				'index.php?option=com_categories&extension=com_djimageslider',
				$vName == 'categories'
			);
	
			
		} else {
			
			JHtmlSidebar::addEntry(
				JText::_('COM_DJIMAGESLIDER_SUBMENU_CPANEL'),
				'index.php?option=com_djimageslider',
				$vName == 'cpanel'
			);
			JHtmlSidebar::addEntry(
				JText::_('COM_DJIMAGESLIDER_SUBMENU_SLIDES'),
				'index.php?option=com_djimageslider&view=items',
				$vName == 'items'
			);
			JHtmlSidebar::addEntry(
				JText::_('COM_DJIMAGESLIDER_SUBMENU_CATEGORIES'),
				'index.php?option=com_categories&extension=com_djimageslider',
				$vName == 'categories'
			);
		}
		
		if ($vName=='categories') {
			JToolBarHelper::title(
			JText::sprintf('COM_DJIMAGESLIDER_CATEGORIES_TITLE',JText::_('com_djimageslider')),
			'slider-categories');
		}
	}
	
	public static function getBSClasses() {
	
		$classes = new JObject;
	
		if(version_compare(JVERSION, '4', '>=')) { // Bootstrap 4
			$classes->set('row', 'row');
			$classes->set('col', 'col-md-');
		} else { // Boostrap 2.3.2
			$classes->set('row', 'row-fluid');
			$classes->set('col', 'span');
		}
	
		return $classes;
	}
	
}
?>PKS�!]��html/contact.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_contact
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

JLoader::register('ContactHelper', JPATH_ADMINISTRATOR . '/components/com_contact/helpers/contact.php');

/**
 * Contact HTML helper class.
 *
 * @since  1.6
 */
abstract class JHtmlContact
{
	/**
	 * Get the associated language flags
	 *
	 * @param   integer  $contactid  The item id to search associations
	 *
	 * @return  string  The language HTML
	 *
	 * @throws  Exception
	 */
	public static function association($contactid)
	{
		// Defaults
		$html = '';

		// Get the associations
		if ($associations = JLanguageAssociations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $contactid))
		{
			foreach ($associations as $tag => $associated)
			{
				$associations[$tag] = (int) $associated->id;
			}

			// Get the associated contact items
			$db = JFactory::getDbo();
			$query = $db->getQuery(true)
				->select('c.id, c.name as title')
				->select('l.sef as lang_sef, lang_code')
				->from('#__contact_details as c')
				->select('cat.title as category_title')
				->join('LEFT', '#__categories as cat ON cat.id=c.catid')
				->where('c.id IN (' . implode(',', array_values($associations)) . ')')
				->where('c.id != ' . $contactid)
				->join('LEFT', '#__languages as l ON c.language=l.lang_code')
				->select('l.image')
				->select('l.title as language_title');
			$db->setQuery($query);

			try
			{
				$items = $db->loadObjectList('id');
			}
			catch (RuntimeException $e)
			{
				throw new Exception($e->getMessage(), 500, $e);
			}

			if ($items)
			{
				foreach ($items as &$item)
				{
					$text = strtoupper($item->lang_sef);
					$url = JRoute::_('index.php?option=com_contact&task=contact.edit&id=' . (int) $item->id);

					$tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '<br />' . JText::sprintf('JCATEGORY_SPRINTF', $item->category_title);
					$classes = 'hasPopover label label-association label-' . $item->lang_sef;

					$item->link = '<a href="' . $url . '" title="' . $item->language_title . '" class="' . $classes
						. '" data-content="' . $tooltip . '" data-placement="top">'
						. $text . '</a>';
				}
			}

			JHtml::_('bootstrap.popover');

			$html = JLayoutHelper::render('joomla.content.associations', $items);
		}

		return $html;
	}

	/**
	 * Show the featured/not-featured icon.
	 *
	 * @param   integer  $value      The featured value.
	 * @param   integer  $i          Id of the item.
	 * @param   boolean  $canChange  Whether the value can be changed or not.
	 *
	 * @return  string	The anchor tag to toggle featured/unfeatured contacts.
	 *
	 * @since   1.6
	 */
	public static function featured($value = 0, $i = 0, $canChange = true)
	{

		// Array of image, task, title, action
		$states = array(
			0 => array('unfeatured', 'contacts.featured', 'COM_CONTACT_UNFEATURED', 'JGLOBAL_TOGGLE_FEATURED'),
			1 => array('featured', 'contacts.unfeatured', 'JFEATURED', 'JGLOBAL_TOGGLE_FEATURED'),
		);
		$state = ArrayHelper::getValue($states, (int) $value, $states[1]);
		$icon  = $state[0];

		if ($canChange)
		{
			$html = '<a href="#" onclick="return listItemTask(\'cb' . $i . '\',\'' . $state[1] . '\')" class="btn btn-micro hasTooltip'
				. ($value == 1 ? ' active' : '') . '" title="' . JHtml::_('tooltipText', $state[3])
				. '"><span class="icon-' . $icon . '" aria-hidden="true"></span></a>';
		}
		else
		{
			$html = '<a class="btn btn-micro hasTooltip disabled' . ($value == 1 ? ' active' : '') . '" title="'
			. JHtml::_('tooltipText', $state[2]) . '"><span class="icon-' . $icon . '" aria-hidden="true"></span></a>';
		}

		return $html;
	}
}
PKS�!]�	���contact.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_contact
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Contact component helper.
 *
 * @since  1.6
 */
class ContactHelper extends JHelperContent
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_CONTACT_SUBMENU_CONTACTS'),
			'index.php?option=com_contact&view=contacts',
			$vName == 'contacts'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_CONTACT_SUBMENU_CATEGORIES'),
			'index.php?option=com_categories&extension=com_contact',
			$vName == 'categories'
		);

		if (JComponentHelper::isEnabled('com_fields') && JComponentHelper::getParams('com_contact')->get('custom_fields_enable', '1'))
		{
			JHtmlSidebar::addEntry(
				JText::_('JGLOBAL_FIELDS'),
				'index.php?option=com_fields&context=com_contact.contact',
				$vName == 'fields.fields'
			);
			JHtmlSidebar::addEntry(
				JText::_('JGLOBAL_FIELD_GROUPS'),
				'index.php?option=com_fields&view=groups&context=com_contact.contact',
				$vName == 'fields.groups'
			);
		}
	}

	/**
	 * Adds Count Items for Category Manager.
	 *
	 * @param   stdClass[]  &$items  The category objects
	 *
	 * @return  stdClass[]
	 *
	 * @since   3.5
	 */
	public static function countItems(&$items)
	{
		$config = (object) array(
			'related_tbl'   => 'contact_details',
			'state_col'     => 'published',
			'group_col'     => 'catid',
			'relation_type' => 'category_or_group',
		);

		return parent::countRelations($items, $config);
	}

	/**
	 * Adds Count Items for Tag Manager.
	 *
	 * @param   stdClass[]  &$items     The tag objects
	 * @param   string      $extension  The name of the active view.
	 *
	 * @return  stdClass[]
	 *
	 * @since   3.6
	 */
	public static function countTagItems(&$items, $extension)
	{
		$parts   = explode('.', $extension);
		$section = count($parts) > 1 ? $parts[1] : null;

		$config = (object) array(
			'related_tbl'   => ($section === 'category' ? 'categories' : 'contact_details'),
			'state_col'     => 'published',
			'group_col'     => 'tag_id',
			'extension'     => $extension,
			'relation_type' => 'tag_assigments',
		);

		return parent::countRelations($items, $config);
	}

	/**
	 * Returns a valid section for contacts. If it is not valid then null
	 * is returned.
	 *
	 * @param   string  $section  The section to get the mapping for
	 * @param   object  $item     optional item object
	 *
	 * @return  string|null  The new section
	 *
	 * @since   3.7.0
	 */
	public static function validateSection($section, $item)
	{
		if (JFactory::getApplication()->isClient('site') && $section == 'contact' && $item instanceof JForm)
		{
			// The contact form needs to be the mail section
			$section = 'mail';
		}

		if (JFactory::getApplication()->isClient('site') && $section == 'category')
		{
			// The contact form needs to be the mail section
			$section = 'contact';
		}

		if ($section != 'mail' && $section != 'contact')
		{
			// We don't know other sections
			return null;
		}

		return $section;
	}

	/**
	 * Returns valid contexts
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public static function getContexts()
	{
		JFactory::getLanguage()->load('com_contact', JPATH_ADMINISTRATOR);

		$contexts = array(
			'com_contact.contact'    => JText::_('COM_CONTACT_FIELDS_CONTEXT_CONTACT'),
			'com_contact.mail'       => JText::_('COM_CONTACT_FIELDS_CONTEXT_MAIL'),
			'com_contact.categories' => JText::_('JCATEGORY')
		);

		return $contexts;
	}
}
PKv�!]Z�|N>K>K
helper.phpnu&1i�<?php
/**
 * @name		Slideshow CK
 * @package		com_slideshowck
 * @copyright	Copyright (C) 2019. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - https://www.template-creator.com - https://www.joomlack.fr
 */

// No direct access
defined('_JEXEC') or die;

require_once JPATH_ADMINISTRATOR . '/components/com_slideshowck/helpers/defines.php';

use Slideshowck\CKInput;
use Slideshowck\CKFof;
use Slideshowck\CKText;

/**
 * Helper Class.
 */
class SlideshowckHelper {

	static $cssreplacements;

	/*
	 * Load the JS and CSS files needed to use CKBox
	 *
	 * Return void
	 */
	public static function loadCkbox() {
		$doc = \Joomla\CMS\Factory::getDocument();
		\Joomla\CMS\HTML\HTMLHelper::_('jquery.framework', true);
//		$doc->addScript(\Joomla\CMS\Uri\Uri::root(true) . '/media/jui/js/jquery.min.js');
		$doc->addStyleSheet(SLIDESHOWCK_MEDIA_URI . '/assets/ckbox.css');
		$doc->addScript(SLIDESHOWCK_MEDIA_URI . '/assets/ckbox.js');
	}

	/*
	 * Load the JS and CSS files needed to use CKBox
	 *
	 * Return void
	 */
//	public static function loadCKFramework() {
//		$doc = \Joomla\CMS\Factory::getDocument();
//		$doc->addScript(\Joomla\CMS\Uri\Uri::root(true) . '/media/jui/js/jquery.min.js');
//		$doc->addStyleSheet(SLIDESHOWCK_MEDIA_URI . '/assets/ckframework.css');
//	}

	/*
	 * Load the JS and CSS files needed to use CKBox
	 *
	 * Return void
	 */
	/*public static function loadInlineCKFramework() {
	?>
		<script src="<?php echo \Joomla\CMS\Uri\Uri::root(true) ?>/media/jui/js/jquery.min.js" type="text/javascript"></script>
		<link rel="stylesheet" href="<?php echo \Joomla\CMS\Uri\Uri::root(true) ?>/components/com_slideshowck/assets/font-awesome.min.css" type="text/css" />
		<link rel="stylesheet" href="<?php echo SLIDESHOWCK_MEDIA_URI ?>/assets/ckframework.css" type="text/css" />
	<?php
	}*/
	
	/**
	 * Convert a hexa decimal color code to its RGB equivalent
	 *
	 * @param string $hexStr (hexadecimal color value)
	 * @param boolean $returnAsString (if set true, returns the value separated by the separator character. Otherwise returns associative array)
	 * @param string $seperator (to separate RGB values. Applicable only if second parameter is true.)
	 * @return array or string (depending on second parameter. Returns False if invalid hex color value)
	 */
	static function hex2RGB($hexStr, $opacity) {
		$hexStr = preg_replace("/[^0-9A-Fa-f]/", '', $hexStr); // Gets a proper hex string
		$rgbArray = array();
		if (strlen($hexStr) == 6) { //If a proper hex code, convert using bitwise operation. No overhead... faster
			$colorVal = hexdec($hexStr);
			$rgbArray['red'] = 0xFF & ($colorVal >> 0x10);
			$rgbArray['green'] = 0xFF & ($colorVal >> 0x8);
			$rgbArray['blue'] = 0xFF & $colorVal;
		} elseif (strlen($hexStr) == 3) { //if shorthand notation, need some string manipulations
			$rgbArray['red'] = hexdec(str_repeat(substr($hexStr, 0, 1), 2));
			$rgbArray['green'] = hexdec(str_repeat(substr($hexStr, 1, 1), 2));
			$rgbArray['blue'] = hexdec(str_repeat(substr($hexStr, 2, 1), 2));
		} else {
			return false; //Invalid hex color code
		}
		$rgbacolor = "rgba(" . $rgbArray['red'] . "," . $rgbArray['green'] . "," . $rgbArray['blue'] . "," . ($opacity / 100) . ")";

		return $rgbacolor;
	}

	/**
	 * Test if there is already a unit, else add the px
	 *
	 * @param string $value
	 * @return string
	 */
	public static function testUnit($value) {
		if ((stristr($value, 'px')) OR (stristr($value, 'em')) OR (stristr($value, '%'))) {
			return $value;
		}

		if ($value == '') {
			$value = 0;
		}

		return $value . 'px';
	}

	/**
	 * Remove special character
	 */
	public static function cleanName($path) {
		return preg_replace('/[^a-z0-9]/i', '_', $path);
	}

	public static function formatPath($p) {
		return trim(str_replace("\\", "/", $p), "/");
	}

	/**
	 * Get a subtring with the max length setting.
	 *
	 * @param string $text;
	 * @param int $length limit characters showing;
	 * @param string $replacer;
	 * @return tring;
	 */
	public static function substring($text, $length = 100, $replacer = '...', $isStrips = true, $stringtags = '') {
	
		if($isStrips){
			$text = preg_replace('/\<p.*\>/Us','',$text);
			$text = str_replace('</p>','<br/>',$text);
			$text = strip_tags($text, $stringtags);
		}
		
		if(function_exists('mb_strlen')){
			if (mb_strlen($text) < $length)	return $text;
			$text = mb_substr($text, 0, $length);
		}else{
			if (strlen($text) < $length)	return $text;
			$text = substr($text, 0, $length);
		}
		
		return $text . $replacer;
	}

	/*
	* update the table
	*/
	/*public static function createTableOptions() {
		$sqlsrc = SLIDESHOWCK_PATH . '/sql/updates/2.4.0.sql';
		$query = file_get_contents($sqlsrc);
		$db = \Joomla\CMS\Factory::getDbo();
		$db->setQuery($query);
		if (!$db->execute()) {
			echo '<p class="alert alert-danger">Error during table options creation</p>';
		} else {
			echo '<p class="alert alert-success">Table options successfully created</p>';
		}
	}*/

	/**
	 * Get the name of the style
	 */
	public static function getStyleNameById($id) {
		if (! $id) return '';
		// Create a new query object.
		$db = \Joomla\CMS\Factory::getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select('a.name');
		$query->from($db->quoteName('#__slideshowck_styles') . ' AS a');
		$query->where('(a.state IN (0, 1))');
		$query->where('a.id = ' . (int)$id);

		// Reset the query using our newly populated query object.
		$db->setQuery($query);

		// Load the results as a list of stdClass objects (see later for more options on retrieving data).
		$results = $db->loadResult();

		return $results;
	}

	/**
	 * Create the list of all modules published as Object
	 *
	 * $file string the image path
	 * $x integer the new image width
	 * $y integer the new image height
	 *
	 * @return Boolean True on Success
	 */
	static function resizeImage($file, $x, $y = '', $thumbpath = 'th', $thumbsuffix = '_th') {

		if (!$file)
			return;

		$thumbext = explode(".", $file);
		$thumbext = end($thumbext);
		$thumbfile = str_replace(basename($file), $thumbpath . "/" . basename($file), $file);
		$thumbfile = str_replace("." . $thumbext, $thumbsuffix . "." . $thumbext, $thumbfile);
		
		$filetmp = JPATH_ROOT . '/' . $file;
		$filetmp = str_replace("%20", " ", $filetmp);
		if (! file_exists($filetmp))
			return $file;
		$size = getimagesize($filetmp);

		if ($size[0] > $size[1] || !$y) // paysage
		{
			$y = $x * $size[1] / $size[0];
		} else 
		{
			$x = $y * $size[0] / $size[1];
		}

		
		if ($size) {
			if (\Joomla\CMS\Filesystem\File::exists($thumbfile)) {
				return $thumbfile;
			}
			
			$thumbfolder = str_replace(basename($file), $thumbpath . "/", $filetmp);
			if (!\Joomla\CMS\Filesystem\Folder::exists($thumbfolder)) { 
				\Joomla\CMS\Filesystem\Folder::create($thumbfolder);
				\Joomla\CMS\Filesystem\File::copy(JPATH_ROOT . '/modules/mod_slideshowck/index.html', $thumbfolder . 'index.html' );
			}

			if ($size['mime'] == 'image/jpeg') {
				$img_big = imagecreatefromjpeg($filetmp); # On ouvre l'image d'origine
				$img_new = imagecreate($x, $y);
				# création de la miniature
				$img_mini = imagecreatetruecolor($x, $y) or $img_mini = imagecreate($x, $y);
				// copie de l'image, avec le redimensionnement.
				imagecopyresized($img_mini, $img_big, 0, 0, 0, 0, $x, $y, $size[0], $size[1]);

				imagejpeg($img_mini, JPATH_ROOT . '/' . $thumbfile);
			} elseif ($size['mime'] == 'image/png') {
				$img_big = imagecreatefrompng($filetmp); # On ouvre l'image d'origine
				$img_new = imagecreate($x, $y);
				# création de la miniature
				$img_mini = imagecreatetruecolor($x, $y) or $img_mini = imagecreate($x, $y);
				// copie de l'image, avec le redimensionnement.
				imagecopyresized($img_mini, $img_big, 0, 0, 0, 0, $x, $y, $size[0], $size[1]);

				imagepng($img_mini, JPATH_ROOT . '/' . $thumbfile);
			} elseif ($size['mime'] == 'image/gif') {
				$img_big = imagecreatefromgif($filetmp); # On ouvre l'image d'origine
				$img_new = imagecreate($x, $y);
				# création de la miniature
				$img_mini = imagecreatetruecolor($x, $y) or $img_mini = imagecreate($x, $y);
				// copie de l'image, avec le redimensionnement.
				imagecopyresized($img_mini, $img_big, 0, 0, 0, 0, $x, $y, $size[0], $size[1]);

				imagegif($img_mini, JPATH_ROOT . '/' . $thumbfile);
			}
			//echo 'Image redimensionnée !';
		}

		return $thumbfile;
	}

	/*
	 * Make empty slide object
	 */
	public static function initItem() {
		$item = new stdClass();
		$item->image = null;
		$item->link = null;
		$item->title = null;
		$item->text = null;
		$item->more = array();
		$item->alignment = null;
		$item->time = null;
		$item->target = 'default';
		$item->video = null;
		$item->texttype = null;
		$item->articleid = null;

		return $item;
	}

	/*
	 * Convert an old item to the new convention
	 */
	public static function legacyUpdateItem(&$item) {
		$newItem = self::initItem();
		foreach ($newItem as $key => $value) {
			if (!isset($item->$key)) $item->$key = $value;
		}
		$item->image = $item->imgname;
		$item->link = $item->imglink;
		$item->time = $item->imgtime;
		$item->thumb = $item->imgthumb;
		$item->title = $item->imgtitle;
		$item->text = strip_tags($item->imgcaption);
	}

	/*
	 * Convert an item to the old convention to render in a V1 layout
	 * To call manually in the layout file
	 */
	public static function legacyItemForV1Layout(&$item) {
		$newItem = self::initItem();
		foreach ($newItem as $key => $value) {
			if (!isset($item->$key)) $item->$key = $value;
		}
		$item->imgname = $item->image;
		$item->imglink = $item->link;
		$item->imgtime = $item->time;
		$item->imgthumb = $item->imgname;
//		$item->imgthumb = $item->thumb;
		$item->imgtitle = $item->title;
		$item->imgcaption = $item->text;

		$item->imgalignment = $item->alignment;
		$item->imgtime = $item->time;
		$item->imgtarget = $item->target;
		$item->imgvideo = $item->video;
		$item->article = null;
	}

	/**
	 * Set the correct video link
	 *
	 * $videolink string the video path
	 *
	 * @return string the new video path
	 */
	static function setVideolink($videolink) {
		// youtube
		if (stristr($videolink, 'youtu.be')) {
			$videolink = str_replace('youtu.be', 'www.youtube.com/embed', $videolink);
		} else if (stristr($videolink, 'www.youtube.com') AND !stristr($videolink, 'embed')) {
			$videolink = str_replace('youtube.com', 'youtube.com/embed', $videolink);
		}

		if (strpos($videolink, 'http') !== false) $videolink .= ( stristr($videolink, '?')) ? '&wmode=transparent' : '?wmode=transparent';

		return $videolink;
	}

	/**
	 * Set the correct video link
	 *
	 * $videolink string the video path
	 *
	 * @return string the new video path
	 */
	static function setImageUrl($url) {
		if (strpos($url, 'http') !== 0) {
			$url = \Joomla\CMS\Uri\Uri::root(true) . '/' . trim($url, '/');
		}

		return $url;
	}

	/**
	 * Truncates text blocks over the specified character limit and closes
	 * all open HTML tags. The method will optionally not truncate an individual
	 * word, it will find the first space that is within the limit and
	 * truncate at that point. This method is UTF-8 safe.
	 *
	 * @param   string   $text       The text to truncate.
	 * @param   integer  $length     The maximum length of the text.
	 * @param   boolean  $noSplit    Don't split a word if that is where the cutoff occurs (default: true).
	 * @param   boolean  $allowHtml  Allow HTML tags in the output, and close any open tags (default: true).
	 *
	 * @return  string   The truncated text.
	 *
	 * @since   11.1
	 */
	public static function truncate($text, $length = 0, $noSplit = true, $allowHtml = true) {
		if ($length == 0) return '';
		// Check if HTML tags are allowed.
		if (!$allowHtml) {
			// Deal with spacing issues in the input.
			$text = str_replace('>', '> ', $text);
			$text = str_replace(array('&nbsp;', '&#160;'), ' ', $text);
			$text = JString::trim(preg_replace('#\s+#mui', ' ', $text));

			// Strip the tags from the input and decode entities.
			$text = strip_tags($text);
			$text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');

			// Remove remaining extra spaces.
			$text = str_replace('&nbsp;', ' ', $text);
			$text = JString::trim(preg_replace('#\s+#mui', ' ', $text));
		}

		// Truncate the item text if it is too long.
		if ($length > 0 && JString::strlen($text) > $length) {
			// Find the first space within the allowed length.
			$tmp = JString::substr($text, 0, $length);

			if ($noSplit) {
				$offset = JString::strrpos($tmp, ' ');
				if (JString::strrpos($tmp, '<') > JString::strrpos($tmp, '>')) {
					$offset = JString::strrpos($tmp, '<');
				}
				$tmp = JString::substr($tmp, 0, $offset);

				// If we don't have 3 characters of room, go to the second space within the limit.
				if (JString::strlen($tmp) > $length - 3) {
					$tmp = JString::substr($tmp, 0, JString::strrpos($tmp, ' '));
				}
			}

			if ($allowHtml) {
				// Put all opened tags into an array
				preg_match_all("#<([a-z][a-z0-9]*)\b.*?(?!/)>#i", $tmp, $result);
				$openedTags = $result[1];
				$openedTags = array_diff($openedTags, array("img", "hr", "br"));
				$openedTags = array_values($openedTags);

				// Put all closed tags into an array
				preg_match_all("#</([a-z]+)>#iU", $tmp, $result);
				$closedTags = $result[1];

				$numOpened = count($openedTags);

				// All tags are closed
				if (count($closedTags) == $numOpened) {
					return $tmp . '...';
				}
				$tmp .= '...';
				$openedTags = array_reverse($openedTags);

				// Close tags
				for ($i = 0; $i < $numOpened; $i++) {
					if (!in_array($openedTags[$i], $closedTags)) {
						$tmp .= "</" . $openedTags[$i] . ">";
					} else {
						unset($closedTags[array_search($openedTags[$i], $closedTags)]);
					}
				}
			}

			$text = $tmp;
		}

		return $text;
	}

	static function getArticle($item) {
		$app = \Joomla\CMS\Factory::getApplication();
		if (version_compare(JVERSION, '4') >= 0) {
			$factory = $app->bootComponent('com_content')->getMVCFactory();

			// Get an instance of the generic articles model
			$articles = $factory->createModel('Articles', 'Site', ['ignore_request' => true]);
		} else {
			// load the content articles file
			$com_path = JPATH_SITE . '/components/com_content/';
			include_once $com_path . 'router.php';
			include_once $com_path . 'helpers/route.php';
			\Joomla\CMS\MVC\Model\BaseDatabaseModel::addIncludePath($com_path . '/models', 'ContentModel');

			// Get an instance of the generic articles model
			$articles = \Joomla\CMS\MVC\Model\BaseDatabaseModel::getInstance('Articles', 'ContentModel', array('ignore_request' => true));
		}
		// Access filter
		$access = !\Joomla\CMS\Component\ComponentHelper::getParams('com_content')->get('show_noauth');
		$authorised = \Joomla\CMS\Access\Access::getAuthorisedViewLevels(\Joomla\CMS\Factory::getUser()->get('id'));
		// Get an instance of the generic articles model
		$articles = \Joomla\CMS\MVC\Model\BaseDatabaseModel::getInstance('Articles', 'ContentModel', array('ignore_request' => true));
		// Set application parameters in model
		$app = \Joomla\CMS\Factory::getApplication();
//		$appParams = $app->getParams();
		$articles->setState('params', \Joomla\CMS\Component\ComponentHelper::getParams('com_content'));
//		$articles->setState('params', $appParams);
		$articles->setState('filter.published', 1);
//		$item->slidearticleid = isset($item->slidearticleid) ? $item->slidearticleid : $item->articleid;
		$articles->setState('filter.article_id', $item->slidearticleid);
		$items2 = $articles->getItems();
		$item->article = $items2[0];
		$item->text = $item->article->introtext;
		// $item->text = \Joomla\CMS\HTML\HTMLHelper::_('content.prepare', $item->text);
		$item->title = $item->article->title;
		// set the item link to the article depending on the user rights
		if ($access || in_array($item->article->access, $authorised)) {
			// We know that user has the privilege to view the article
			$item->slug = $item->article->id . ':' . $item->article->alias;
			$item->catslug = $item->article->catid ? $item->article->catid . ':' . $item->article->category_alias : $item->article->catid;
			if (version_compare(JVERSION, '4') >= 0) {
				$item->link = \Joomla\CMS\Router\Route::_(\Joomla\Component\Content\Site\Helper\RouteHelper::getArticleRoute($item->slug, $item->catslug));
			} else {
				$item->link = \Joomla\CMS\Router\Route::_(ContentHelperRoute::getArticleRoute($item->slug, $item->catslug));
			}
		} else {
			$app = \Joomla\CMS\Factory::getApplication();
			$menu = $app->getMenu();
			$menuitems = $menu->getItems('link', 'index.php?option=com_users&view=login');
			if (isset($menuitems[0])) {
				$Itemid = $menuitems[0]->id;
			} elseif ($app->input->get('Itemid', 0, 'int') > 0) {
				$Itemid = $app->input->get('Itemid', 0, 'int');
			}
			$item->link = \Joomla\CMS\Router\Route::_('index.php?option=com_users&view=login&Itemid=' . $Itemid);
		}
		return $item;
	}

	/**
	 * List the replacement between the tags and the real final CSS rules
	 */
	public static function getCssReplacement() {
		if (! empty(self::$cssreplacements)) return self::$cssreplacements;

		self::$cssreplacements = Array(
			'[container]' => ''
			,'[slide]' => '.cameraSlide img'
			,'[caption]' => '.camera_caption > div'
			,'[title]' => '.camera_caption_title'
			,'[text]' => '.camera_caption_desc'
			,'[button]' => 'a.camera-button'
			,'[buttonhover]' => 'a.camera-button:hover'
//			,'[thumbs]' => '.camera_pag_ul li img'
			,'[paginationdotthumbs]' => '.camera_pag_ul li img'
		);

		return self::$cssreplacements;
	}

	/**
	 * Get the CSS of the style
	 * @id - the style ID
	 */
	public static function getStyleLayoutcss($id) {
		if (! $id) return '';

		// Create a new query object.
		$db = \Joomla\CMS\Factory::getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select('a.layoutcss');
		$query->from($db->quoteName('#__slideshowck_styles') . ' AS a');
		$query->where('(a.state IN (0, 1))');
		$query->where('a.id = ' . (int)$id);

		// Reset the query using our newly populated query object.
		$db->setQuery($query);

		// Load the results as a list of stdClass objects (see later for more options on retrieving data).
		$result = $db->loadResult();

		self::makeCssReplacement($result);

		return $result;
	}

	public static function makeCssReplacement(&$css) {
		$cssreplacements = self::getCssReplacement();
		foreach ($cssreplacements as $tag => $rep) {
			$css = str_replace($tag, $rep, $css);
		}
//		return $css;
	}

	public static function getProMessage() {
		$html = '<div class="ckinfo"><i class="fas fa-info"></i><a href="https://www.joomlack.fr/en/joomla-extensions/slideshow-ck" target="_blank">' . \Joomla\CMS\Language\Text::_('SLIDESHOWCK_ONLY_PRO') . '</a></div>';
	
		return $html;
	}

	public static function getProPreview($imgName) {
		$html = '<div class="ckpropreview">'
					. '<img src="' . SLIDESHOWCK_MEDIA_URL . '/images/proonly/' . $imgName . '" />'
					. '<a href="https://www.joomlack.fr/en/joomla-extensions/slideshow-ck" target="_blank">' . \Joomla\CMS\Language\Text::_('SLIDESHOWCK_ONLY_PRO') . '</a>'
				. '</div>';
	
		return $html;
	}
}
PKv�!]N��++source/slidesmanager.phpnu&1i�<?php
/**
 * @copyright	Copyright (C) 2019. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - https://www.template-creator.com - https://www.joomlack.fr
 */

use Joomla\CMS\Factory;
use Joomla\CMS\Date\Date;

// No direct access
defined('_JEXEC') or die;

require_once JPATH_ADMINISTRATOR . '/components/com_slideshowck/helpers/helper.php';

/**
 * Helper Class.
 */
class SlideshowckHelpersourceSlidesmanager {

	private static $params;

	/*
	 * Get the items from the source
	 */
	public static function getItems($params, $folder = null) {
		if (empty(self::$params)) {
			self:$params = $params;
		}

		// load the items from the module settings
		$items = json_decode(str_replace("|qq|", "\"", $params->get('slides')));
		foreach ($items as $i => $item) {
			if (!$item->imgname) {
				unset($items[$i]);
				continue;
			}

			// check if the slide is published
			if (isset($item->state) && $item->state == '0') {
				unset($items[$i]);
				continue;
			}

			// get current date with Timezone
			$config = \Joomla\CMS\Factory::getConfig();
			$offset = $config->get('offset'); // timezone
			$now = new \Joomla\CMS\Date\Date('now', $offset);

			// check the slide start date
			if (isset($item->startdate) && $item->startdate) {
				// if (date("d M Y") < $item->startdate) {
				if (strtotime($now) < strtotime($item->startdate)) {
					unset($items[$i]);
					continue;
				}
			}

			// check the slide end date
			if (isset($item->enddate) && $item->enddate) {
				// if (date("d M Y") > $item->enddate) {
				if (strtotime($now) > strtotime($item->enddate)) {
					unset($items[$i]);
					continue;
				}
			}

			if (stristr($item->imgname, "http")) {
				$item->imgthumb = $item->imgname;
			} else {
				// renomme le fichier
				$thumbext = explode(".", $item->imgname);
				$thumbext = end($thumbext);
				// crée la miniature
				if ($params->get('thumbnails', '1') == '1' && $params->get('autocreatethumbs','1')) {
					if ($params->get('autocreatethumbs','1'))
						$item->imgthumb = \Joomla\CMS\Uri\Uri::base(true) . '/' . SlideshowckHelper::resizeImage($item->imgname, $params->get('thumbnailwidth', '182'), $params->get('thumbnailheight', '187'));
				} else {
					$thumbfile = str_replace(basename($item->imgname), "th/" . basename($item->imgname), $item->imgname);
					$thumbfile = str_replace("." . $thumbext, "_th." . $thumbext, $thumbfile);
					$item->imgthumb = \Joomla\CMS\Uri\Uri::base(true) . '/' . $thumbfile;
				}
				$item->imgname = \Joomla\CMS\Uri\Uri::base(true) . '/' . $item->imgname;
			}

			// set the videolink
			if ($item->imgvideo)
				$item->imgvideo = SlideshowckHelper::setVideolink($item->imgvideo);

			// for B/C
			if (! isset($item->texttype)) {
				$item->texttype = (isset($item->slidearticleid) && $item->slidearticleid) ? 'article' : 'custom';
			}
			if ($item->texttype == 'article') {
				if (isset($item->slidearticleid) && $item->slidearticleid) {
					$item = SlideshowckHelper::getArticle($item);
				} else {
					$item->link = '';
					$item->title = '';
					$item->text = '';
				}
			} else {
				// manage the title and description - LEGACY
				if (stristr($item->imgcaption, "||")) {
					$splitcaption = explode("||", $item->imgcaption);
					$item->imgtitle = $splitcaption[0];
					$item->imgcaption = $splitcaption[1];
				}

				// route the url
				if (strcasecmp(substr($item->imglink, 0, 4), 'http') && (strpos($item->imglink, 'index.php?') !== false)) {
					$item->imglink = \Joomla\CMS\Router\Route::_($item->imglink, true, false);
				} else {
					$item->imglink = \Joomla\CMS\Router\Route::_($item->imglink);
				}

				if (! isset($item->imgtitle)) $item->imgtitle = '';

				// convert legacy to new standard
				$item->link = $item->imglink;
				$item->title = $item->imgtitle;
				$item->text = $item->imgcaption;
			}
			// convert legacy to new standard
			$item->image = $item->imgname;
			$item->time = $item->imgtime;
			$item->target = $item->imgtarget;
			$item->alignment = $item->imgalignment;
			$item->video = $item->imgvideo;
		}

		return $items;
	}
}
PKv�!]�!	˔�
ckfile.phpnu&1i�<?php
namespace Slideshowck;

defined('_JEXEC') or die;

jimport('joomla.filesystem.file');

class CKFile extends \Joomla\CMS\Filesystem\File {
	
}
PKv�!]V��.	.	defines.phpnu&1i�<?php
/**
 * @copyright	Copyright (C) 2019. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - https://www.template-creator.com - https://www.joomlack.fr
 */

// No direct access
defined('_JEXEC') or die;

// set variables
define('SLIDESHOWCK_PLATFORM', 'joomla');
define('SLIDESHOWCK_PATH', JPATH_SITE . '/administrator/components/com_slideshowck');
define('SLIDESHOWCK_ADMIN_PATH', SLIDESHOWCK_PATH);
define('SLIDESHOWCK_FRONT_PATH', JPATH_SITE . '/components/com_slideshowck');
define('SLIDESHOWCK_PROJECTS_PATH', JPATH_SITE . '/administrator/components/com_slideshowck/projects');
define('SLIDESHOWCK_ADMIN_URL', \Joomla\CMS\Uri\Uri::root(true) . '/administrator/index.php?option=com_slideshowck');
define('SLIDESHOWCK_URL', \Joomla\CMS\Uri\Uri::base(true) . '/index.php?option=com_slideshowck');
define('SLIDESHOWCK_ADMIN_GENERAL_URL', \Joomla\CMS\Uri\Uri::root(true) . '/administrator/index.php?option=com_slideshowck&view=templates');
define('SLIDESHOWCK_MEDIA_URI', \Joomla\CMS\Uri\Uri::root(true) . '/media/com_slideshowck');
define('SLIDESHOWCK_MEDIA_URL', SLIDESHOWCK_MEDIA_URI);
define('SLIDESHOWCK_MEDIA_PATH', JPATH_ROOT . '/media/com_slideshowck');
define('SLIDESHOWCK_PLUGIN_URL', SLIDESHOWCK_MEDIA_URI);
define('SLIDESHOWCK_TEMPLATES_PATH', JPATH_SITE . '/templates');
define('SLIDESHOWCK_SITE_ROOT', JPATH_ROOT);
define('SLIDESHOWCK_URI', \Joomla\CMS\Uri\Uri::root(true) . '/administrator/components/com_slideshowck');
define('SLIDESHOWCK_URI_ROOT', \Joomla\CMS\Uri\Uri::root(true));
define('SLIDESHOWCK_URI_BASE', \Joomla\CMS\Uri\Uri::base(true));
define('SLIDESHOWCK_PLUGINS_PATH', JPATH_SITE . '/plugins/slideshowck');
define('SLIDESHOWCK_VERSION', simplexml_load_file(SLIDESHOWCK_PATH . '/slideshowck.xml')->version);

// include the classes
require_once SLIDESHOWCK_PATH . '/helpers/ckinput.php';
require_once SLIDESHOWCK_PATH . '/helpers/cktext.php';
require_once SLIDESHOWCK_PATH . '/helpers/ckfile.php';
require_once SLIDESHOWCK_PATH . '/helpers/ckfolder.php';
require_once SLIDESHOWCK_PATH . '/helpers/ckfof.php';
//require_once SLIDESHOWCK_PATH . '/helpers/helper.php';
//require_once SLIDESHOWCK_PATH . '/helpers/ckcontroller.php';
//require_once SLIDESHOWCK_PATH . '/helpers/ckmodel.php';
//require_once SLIDESHOWCK_PATH . '/helpers/ckview.php';PKv�!]S��bnn
cktext.phpnu&1i�<?php
namespace Slideshowck;

defined('_JEXEC') or die;

class CKText extends \Joomla\CMS\Language\Text {
	
}
PKv�!]�[�gg	ckuri.phpnu&1i�<?php
namespace Slideshowck;

defined('_JEXEC') or die;

class CKUri extends \Joomla\CMS\Uri\Uri {
	
}
PKv�!]�O�s��ckbrowse.phpnu&1i�<?php
/**
 * @copyright	Copyright (C) 2019. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - https://www.template-creator.com - https://www.joomlack.fr
 */

use Slideshowck\CKPath;
use Slideshowck\CKFolder;
use Slideshowck\CKFile;

defined('_JEXEC') or die;

jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.file');

class CKBrowse {

	static $isRestrictedUser = false;

	public static function getFileTypes($type) {
		$input = \Joomla\CMS\Factory::getApplication()->input;
		$type = $input->get('type', $type, 'string');

		switch ($type) {
			case 'video' :
				$filetypes = array('.mp4', '.ogv', '.webm', '.MP4', '.OGV', '.WEBM');
				break;
			case 'audio' :
				$filetypes = array('.mp3', '.ogg', '.MP3', '.OGG');
				break;
			case 'image' :
			default :
				$filetypes = array('.jpg', '.jpeg', '.png', '.gif', '.tiff', '.JPG', '.JPEG', '.PNG', '.GIF', '.TIFF', '.ico', '.webp', '.WEBP');
				break;
		}

		return $filetypes;
	}

	/*
	 * Get a list of folders and files 
	 */
	public static function getItemsList($type = 'image') {
		$input = \Joomla\CMS\Factory::getApplication()->input;

		$type = $input->get('type', $type, 'string');

		switch ($type) {
			case 'video' :
				$filetypes = array('.mp4', '.ogv', '.webm', '.MP4', '.OGV', '.WEBM');
				break;
			case 'audio' :
				$filetypes = array('.mp3', '.ogg', '.MP3', '.OGG');
				break;
			case 'image' :
			default :
				$filetypes = array('.jpg', '.jpeg', '.png', '.gif', '.tiff', '.JPG', '.JPEG', '.PNG', '.GIF', '.TIFF', '.ico', '.webp', '.WEBP');
				break;
		}

		$folder = $input->get('folder', '', 'string') ? '/' . trim($input->get('folder', '', 'string'), '/') : '/' . trim(\Joomla\CMS\Component\ComponentHelper::getParams('com_slideshowck')->get('imagespath', 'images/slideshowck'), '/');

		// makes replacement if specific user management is set
		if (stristr($folder, '$userid')) {
			self::$isRestrictedUser = true;
			$user = \Joomla\CMS\Factory::getUser();
			$folder = str_replace('$userid', 'user_' . $user->id, $folder);
			if (! file_exists(JPATH_SITE . '/' . $folder)) {
				\Joomla\CMS\Filesystem\Folder::create(JPATH_SITE . '/' . $folder);
			}
		}

		// no folder filtering 
		if (\Joomla\CMS\Component\ComponentHelper::getParams('com_slideshowck')->get('imagespathexclusive', '0') == '0') {
		$folder = $input->get('folder', 'images', 'string');
		}

		$tree = new stdClass();

		// list the files in the root folder
		$fName = self::createFolderObj(JPATH_SITE . '/' . $folder, $tree, 1);
		$tree->$fName->files = self::getImagesInFolder(JPATH_SITE . '/' . $folder, implode('|', $filetypes));

		// look for all folder and files
		self::getSubfolder(JPATH_SITE . '/' . $folder, $tree, implode('|', $filetypes), 2);
		$tree = self::prepareList($tree);

		return $tree;
	}

	/* 
	 * List the subfolders and files according to the filter
	 */
	private static function getSubfolder($folder, &$tree, $filter, $level) {
		$folders = \Joomla\CMS\Filesystem\Folder::folders($folder, '.', $recurse = false, $fullpath = true);
		natcasesort($folders);

		if (! count($folders)) return;

		foreach ($folders as $f) {
			$fName = self::createFolderObj($f, $tree, $level);

			// list all authorized files from the folder
			// self::getImagesInFolder($f, $tree, $fName, $filter, $level);

			// recursive loop
			self::getSubfolder($f, $tree, $filter, $level+1);
		}
		return;
	}

	private static function createFolderObj($f, &$tree, $level) {
		$fName = \Joomla\CMS\Filesystem\File::makeSafe(str_replace(JPATH_SITE, '', $f));
		$tree->$fName = new stdClass();
		$name = explode('/', $f);
		$name = end($name);
		$tree->$fName->name = ($level == 1 && self::$isRestrictedUser == true) ? 'images' : $name;
		$tree->$fName->path = $f;
		$tree->$fName->level = $level;
		$tree->$fName->files = false;

		return $fName;
	}

	/* 
	 * List the subfolders and files according to the filter
	 */
	public static function getImagesInFolder($f, $filter = '.') {

			// list all authorized files from the folder
			$files = \Joomla\CMS\Filesystem\Folder::files($f, $filter, $recurse = false, $fullpath = false);
			if (is_array($files)) natcasesort($files);

			return $files;
		}

	/* 
	 * Set level diff and check for depth
	 */
	private static function prepareList($items) {
		if (! $items) return $items;

		$lastitem = 0;
		foreach ($items as $i => $item)
		{
			self::prepareItem($item);

			if ($item->level != 0) {
				if (isset($items->$lastitem))
				{
					$items->$lastitem->deeper     = ($item->level > $items->$lastitem->level);
					$items->$lastitem->shallower  = ($item->level < $items->$lastitem->level);
					$items->$lastitem->level_diff = ($items->$lastitem->level - $item->level);
				}
			}
			$lastitem = $i;

			
		}

		// for the last item
		if (isset($items->$lastitem))
		{
			$items->$lastitem->deeper     = (1 > $items->$lastitem->level);
			$items->$lastitem->shallower  = (1 < $items->$lastitem->level);
			$items->$lastitem->level_diff = ($item->level - 1);
		}

		return $items;
	}

	/* 
	 * Set the default values
	 */
	private static function prepareItem(&$item) {
		$item->deeper     = false;
		$item->shallower  = false;
		$item->level_diff = 0;
		$item->basepath = str_replace(JPATH_SITE, '', $item->path);
		$item->basepath = str_replace('\\', '/', $item->basepath);
		$item->basepath = trim($item->basepath, '/');
	}

	/**
	 * Get the file and store it on the server
	 * 
	 * @return mixed, the method return
	 */
	public static function ajaxAddPicture() {
		// check the token for security
		if (! \Joomla\CMS\Session\Session::checkToken('get')) {
			$msg = \Joomla\CMS\Language\Text::_('JINVALID_TOKEN');
			echo '{"error" : "' . $msg . '"}';
			exit;
		}

		$app = \Joomla\CMS\Factory::getApplication();
		$input = $app->input;
		$file = $input->files->get('file', '', 'array');
		// $imgpath = '/' . trim($input->get('path', '', 'string'), '/') . '/';
		$imgpath = $input->get('path', '', 'string') ? '/' . trim($input->get('path', '', 'string'), '/') . '/' : '/' . trim(\Joomla\CMS\Component\ComponentHelper::getParams('com_slideshowck')->get('imagespath', 'images/slideshowck'), '/') . '/';

		// makes replacement if specific user management is set
		$user = \Joomla\CMS\Factory::getUser();
		$imgpath = str_replace('$userid', 'user_' . $user->id, $imgpath);

		if (!is_array($file)) {
			$msg = \Joomla\CMS\Language\Text::_('CK_NO_FILE_RECEIVED');
			echo '{"error" : "' . $msg . '"}';
			exit;
		}

		$filename = \Joomla\CMS\Filesystem\File::makeSafe($file['name']);

		// check the file extension // TODO recup preg_match de local dev
		// if (\Joomla\CMS\Filesystem\File::getExt($filename) != 'jpg') {
			// $msg = \Joomla\CMS\Language\Text::_('CK_NOT_JPG_FILE');
			// echo '{"error" : "'  $msg  '"}';
			// exit;
		// }

		//Set up the source and destination of the file
		$src = $file['tmp_name'];

		// check if the file exists
		if (!$src || !\Joomla\CMS\Filesystem\File::exists($src)) {
			$msg = \Joomla\CMS\Language\Text::_('CK_FILE_NOT_EXISTS');
			echo '{"error" : "' . $msg . '"}';
			exit;
		}

		// check if folder exists, if not then create it
		if (!\Joomla\CMS\Filesystem\Folder::exists(JPATH_SITE . $imgpath)) {
			if (!\Joomla\CMS\Filesystem\Folder::create(JPATH_SITE . $imgpath)) {
				$msg = \Joomla\CMS\Language\Text::_('CK_UNABLE_TO_CREATE_FOLDER') . ' : ' . $imgpath;
				echo '{"error" : "' . $msg . '"}';
				exit;
			}
		}

		// write the file
		if (! \Joomla\CMS\Filesystem\File::copy($src, JPATH_SITE . $imgpath . $filename)) {
			$msg = \Joomla\CMS\Language\Text::_('CK_UNABLE_WRITE_FILE');
			echo '{"error" : "' . $msg . '"}';
			exit;
		}
		echo '{"img" : "' . $imgpath . $filename . '", "filename" : "' . $filename . '"}';
		exit;
	}

	public static function createFolder($path, $folder) {
		$path = CKPath::clean(JPATH_SITE . '/' . $path . '/' . $folder);

		if (!is_dir($path) && !is_file($path))
			{
				if (CKFolder::create($path))
				{
					$data = "<html>\n<body bgcolor=\"#FFFFFF\">\n</body>\n</html>";
					CKFile::write($path . '/index.html', $data);
				} else {
					return false;
				}
		}
		return true;
	}
}
PKv�!]���l�l�ckstyles.phpnu&1i�<?php
/**
 * @copyright	Copyright (C) 2016. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - http://www.template-creator.com - http://www.joomlack.fr
 */
Namespace Slideshowck;

// No direct access
defined('_JEXEC') or die('Restricted access');

/**
 * CKStyles is a class to manage the styles
 *
 * @author Cedric KEIFLIN http://www.joomlack.fr
 */
class CKStyles extends \stdClass {

	public function create($fields, $customstyles, $direction = 'ltr') {

		$styles = "";
		$customprefixes = array();
		if (! empty($customstyles)) {
		// look for the custom styles to manage from plugins for example
		foreach ($customstyles as $prefix => $selector) {
			$customprefixes[] = $prefix;
		}
		// merge the existing prefix and the new one
		// $prefixes = array_merge($prefixes, $customprefixes);
		}
		$prefixes = $customprefixes;

		$cssstyles = new \stdClass();
		foreach ($prefixes as $prefix) {
			$cssstyles->$prefix = new \stdClass();
			$cssstyles->$prefix->css = self::genCss($fields, $prefix, $direction);
		}


		if (! empty($customstyles)) {
			$id = '|ID|';
			// loop through all custom styles from plugins or other elements
			foreach ($customstyles as $prefix => $selector) {
				$selectors = explode('|', str_replace('|qq|', '"', $selector));
				$fullselector = $id . ' ' . implode(',' . $id . ' ', $selectors);
				// $fullselector = implode(',', $selectors);
				
				$properties = $cssstyles->$prefix->css['background']
						. $cssstyles->$prefix->css['gradient']
						. $cssstyles->$prefix->css['borders']
						. $cssstyles->$prefix->css['borderradius']
						. $cssstyles->$prefix->css['height']
						. $cssstyles->$prefix->css['width']
						. $cssstyles->$prefix->css['color']
						. $cssstyles->$prefix->css['margins']
						. $cssstyles->$prefix->css['paddings']
						. $cssstyles->$prefix->css['alignement']
						. $cssstyles->$prefix->css['shadow']
						. $cssstyles->$prefix->css['fontbold']
						. $cssstyles->$prefix->css['fontitalic']
						. $cssstyles->$prefix->css['fontunderline']
						. $cssstyles->$prefix->css['fontuppercase']
						. $cssstyles->$prefix->css['letterspacing']
						. $cssstyles->$prefix->css['wordspacing']
						. $cssstyles->$prefix->css['textindent']
						. $cssstyles->$prefix->css['lineheight']
						. $cssstyles->$prefix->css['fontsize']
						. $cssstyles->$prefix->css['fontfamily']
						. $cssstyles->$prefix->css['custom']
						;
				if ( !(empty(trim($properties)))) {
							$styles .= "
	" . $fullselector . " {
	"
						. $properties
						. "}
	";
				}

				// add the animations to the element
				$styles .= $this->genAnimations($fields, $prefix, $fullselector);
				$styles .= $this->genEffects($fields, $prefix, $fullselector);
			}
		}

		// Arrows
		// normal state arrows
//		$arrowcolor = (isset($fields->navigationarrowcolor) AND $fields->navigationarrowcolor != '') ? str_replace('#', '', $fields->navigationarrowcolor) : "";
//		$arrowopacity = (isset($fields->navigationarrowopacity) AND $fields->navigationarrowopacity != '') ? $fields->navigationarrowopacity : "";
//		if ($arrowcolor || $arrowopacity) {
//			$styles .= "|ID| .camera_prev > span {"
//	. ($arrowcolor ? "background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23" . $arrowcolor . "'%2F%3E%3C%2Fsvg%3E\");" : "")
//	. ($arrowopacity ? "opacity: " . $arrowopacity . ";" : "")
//						. "}
//	";
//			$styles .= "|ID| .camera_next > span {"
//	. ($arrowcolor ? "background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23" . $arrowcolor . "'%2F%3E%3C%2Fsvg%3E\");" : "")
//	. ($arrowopacity ? "opacity: " . $arrowopacity . ";" : "")
//						. "}
//	";
//		}

		// navigation
		$arrowcolor = (isset($fields->navigationarrowcolor) AND $fields->navigationarrowcolor != '') ? str_replace('#', '', $fields->navigationarrowcolor) : "";
		$arrowopacity = (isset($fields->navigationarrowopacity) AND $fields->navigationarrowopacity != '') ? $fields->navigationarrowopacity : "1";
		if ($arrowcolor) {
			$styles .= "|ID| .camera_prev, |ID| .camera_next, |ID| .camera_commands {"
	. ($arrowcolor ? "background: " . $this->hex2RGB($arrowcolor, $arrowopacity) . ";" : "")
						. "}
	";
		}
		// navigation hover
		$arrowhovercolor = (isset($fields->navigationarrowhovercolor) AND $fields->navigationarrowhovercolor != '') ? str_replace('#', '', $fields->navigationarrowhovercolor) : "";
		$arrowhoveropacity = (isset($fields->navigationarrowhoveropacity) AND $fields->navigationarrowhoveropacity != '') ? $fields->navigationarrowhoveropacity : "1";
		if ($arrowcolor) {
			$styles .= "|ID| .camera_prev:hover, |ID| .camera_next:hover, |ID| .camera_commands:hover {"
	. ($arrowcolor ? "background: " . $this->hex2RGB($arrowhovercolor, $arrowhoveropacity) . ";" : "")
						. "}
	";
		}
		
		//paginationdotimage
		$paginationcolor = (isset($fields->paginationdotimagecolor) AND $fields->paginationdotimagecolor != '') ? $fields->paginationdotimagecolor : "";
		$paginationopacity = (isset($fields->paginationdotimageopacity) AND $fields->paginationdotimageopacity != '') ? $fields->paginationdotimageopacity : "1";
		$paginationdotimageborderwidth = (isset($fields->paginationdotimageborderwidth) AND $fields->paginationdotimageborderwidth != '') ? $fields->paginationdotimageborderwidth : "";

		if ($paginationcolor || $paginationopacity) {
			$styles .= "|ID| .camera_pag_ul li img {"
	. ($paginationcolor ? "border-color: " . $this->hex2RGB($paginationcolor, $paginationopacity) . ";" : "")
	. ($paginationdotimageborderwidth ? "border-width: " . $this->testUnit($paginationdotimageborderwidth) . ";" : "")
						. "}
	";
			$styles .= "|ID| .camera_pag_ul .thumb_arrow {"
	. ($paginationcolor ? "border-top-color: " . $this->hex2RGB($paginationcolor, $paginationopacity) . ";" : "")
						. "}
	";
		}

		//paginationdot
		$paginationdotcolor1 = (isset($fields->paginationdotcolor1) AND $fields->paginationdotcolor1 != '') ? $fields->paginationdotcolor1 : "";
		$paginationdotborderradius1 = (isset($fields->paginationdotborderradius1) AND $fields->paginationdotborderradius1 !== '') ? $fields->paginationdotborderradius1 : "";
		$paginationdotcolor2 = (isset($fields->paginationdotcolor2) AND $fields->paginationdotcolor2 != '') ? $fields->paginationdotcolor2 : "";
		$paginationdotborderradius2 = (isset($fields->paginationdotborderradius2) AND $fields->paginationdotborderradius2 !== '') ? $fields->paginationdotborderradius2 : "";

		if ($paginationdotcolor1 || $paginationdotborderradius1 !== '') {
			$styles .= "|ID|.camera_wrap .camera_pag .camera_pag_ul li {"
	. ($paginationdotcolor1 ? "background: " . $paginationdotcolor1 . ";" : "")
	. ($paginationdotborderradius1 !== '' ? "border-radius: " . $this->testUnit($paginationdotborderradius1) . ";" : "")
						. "}
	";
		}

		if ($paginationdotcolor2 || $paginationdotborderradius2 !== '') {
			$styles .= "|ID|.camera_wrap .camera_pag .camera_pag_ul li.cameracurrent > span, |ID| .camera_wrap .camera_pag .camera_pag_ul li:hover > span {"
	. ($paginationdotcolor2 ? "background: " . $paginationdotcolor2 . ";" : "")
	. ($paginationdotborderradius2 !== '' ? "border-radius: " . $this->testUnit($paginationdotborderradius2) . ";" : "")
						. "}
	";
		}

		// paginationdot position
		$paginationposition = (isset($fields->paginationdotposition) AND $fields->paginationdotposition != '') ? $fields->paginationdotposition : "";
		if ($paginationposition === 'inside') {
			$styles .= "|ID| .camera_pag {"
	. ($paginationposition ? "margin-top: -50px;" : "")
						. "}
	";
			$styles .= "|ID| {"
	. ($paginationposition ? "margin-bottom: 0px !important;" : "")
						. "}
	";
		}

		// paginationdot alignment
		$paginationalign = (isset($fields->paginationdotalign) AND $fields->paginationdotalign != '') ? $fields->paginationdotalign : "";
		if ($paginationalign) {
			$styles .= "|ID| .camera_pag .camera_pag_ul {"
	. ($paginationalign ? "text-align: " . $paginationalign . ";" : "")
						. "}
	";
		}

		// caption
		$layoutposition = (isset($fields->layoutposition) AND $fields->layoutposition != '') ? $fields->layoutposition : "";
		if ($layoutposition) {
			$styles .= "|ID| .camera_caption {"
	. ($layoutposition == 'bottom' ? "bottom: 0; top: auto;" : "")
	. ($layoutposition == 'top' ? "bottom: auto; top: 0;" : "")
	. ($layoutposition == 'middle' ? "bottom: auto; top: 50%; transform: translateY(-50%);" : "")
	. ($layoutposition == 'fullscreen' ? "bottom: 0; top: 0;" : "")
						. "}
	";
		}

		/* ---- fin des css ------ */
		return $styles;
	}

	function genCss($fields, $prefix, $direction) {
		$input = CKFof::getInput();
		$action = 'preview';

		// construct variable names
		$backgroundimageurl = $prefix . 'backgroundimageurl';
		$backgroundimageleft = $prefix . 'backgroundimageleft';
		$backgroundimagetop = $prefix . 'backgroundimagetop';
		$backgroundimagerepeat = $prefix . 'backgroundimagerepeat';
		$backgroundimageattachment = $prefix . 'backgroundimageattachment';
		$backgroundcolor = $prefix . 'backgroundcolorstart';
		$backgroundopacity = $prefix . 'backgroundopacity';
		$gradientcolor = $prefix . 'backgroundcolorend';
		$gradient1position = $prefix . 'backgroundpositionend';
		$gradient1opacity = $prefix . 'backgroundopacityend';
		$gradient2color = $prefix . 'backgroundcolorstop1';
		$gradient2position = $prefix . 'backgroundpositionstop1';
		$gradient2opacity = $prefix . 'backgroundopacitystop1';
		$gradient3color = $prefix . 'backgroundcolorstop2';
		$gradient3position = $prefix . 'backgroundpositionstop2';
		$gradient3opacity = $prefix . 'backgroundopacitystop2';
		$gradientdirection = $prefix . 'backgrounddirection';
		$hasopacity = false;
		$backgroundimagesize = $prefix . 'backgroundimagesize';
		$opacity = $prefix . 'opacity';

		// set the background color
		$css['background'] = (isset($fields->$backgroundcolor) AND $fields->$backgroundcolor != '') ? "\tbackground: " . $fields->$backgroundcolor . ";\r\n" : "";
		$backgroundcolorvalue = (isset($fields->$backgroundcolor) AND $fields->$backgroundcolor) ? $fields->$backgroundcolor : "";

		// manage rgba color for opacity
		if (isset($fields->$backgroundopacity) AND $fields->$backgroundopacity != '' AND isset($fields->$backgroundcolor)) {
			$hasopacity = true;
			$rgbavalue = $this->hex2RGB($fields->$backgroundcolor, $fields->$backgroundopacity);
			$css['background'] .= (isset($fields->$backgroundcolor) AND $fields->$backgroundcolor) ? "\tbackground: " . $rgbavalue . ";\r\n\t-pie-background: " . $rgbavalue . ";\r\n" : "";
		}
		if (isset($fields->$backgroundopacity) AND $fields->$backgroundopacity == '0') {
			$css['background'] .= "\tbackground: none;\r\n";
		}

		$imageurl = "";
		if (isset($fields->$backgroundimageurl) AND $fields->$backgroundimageurl) {
			if ($action == 'preview') {
				$imageurl = substr($fields->$backgroundimageurl, 0, 4)  == 'http' ? $fields->$backgroundimageurl : \Joomla\CMS\Uri\Uri::root(true) . '/' . $fields->$backgroundimageurl;
			} else {
				$imageurl = explode("/", $fields->$backgroundimageurl);
				$imageurl = end($imageurl);
				$imageurl = "../images/" . $imageurl;
			}
		}

		// set the background image
		$backgroundimageleftvalue = (isset($fields->$backgroundimageleft) AND $fields->$backgroundimageleft != null) ? $fields->$backgroundimageleft : "center";
		$backgroundimagetopvalue = (isset($fields->$backgroundimagetop) AND $fields->$backgroundimagetop != null) ? $fields->$backgroundimagetop : "center";
		$backgroundimagerepeatvalue = (isset($fields->$backgroundimagerepeat) AND $fields->$backgroundimagerepeat) ? $fields->$backgroundimagerepeat : "no-repeat";
		$backgroundimageurlvalue = (isset($fields->$backgroundimageurl) AND $fields->$backgroundimageurl) ? $fields->$backgroundimageurl : "";
		$backgroundimageattachmentvalue = (isset($fields->$backgroundimageattachment) AND $fields->$backgroundimageattachment) ? $fields->$backgroundimageattachment : "";

		if ($backgroundimageleftvalue != 'top' AND $backgroundimageleftvalue != 'right' AND $backgroundimageleftvalue != 'bottom' AND $backgroundimageleftvalue != 'left' AND $backgroundimageleftvalue != 'center' AND !stristr($backgroundimageleftvalue, "px")
		)
			$backgroundimageleftvalue = $this->testUnit($backgroundimageleftvalue);

		if ($backgroundimagetopvalue != 'top' AND $backgroundimagetopvalue != 'right' AND $backgroundimagetopvalue != 'bottom' AND $backgroundimagetopvalue != 'left' AND $backgroundimagetopvalue != 'center' AND !stristr($backgroundimagetopvalue, "px")
		)
			$backgroundimagetopvalue = $this->testUnit($backgroundimagetopvalue);

		// set the background color
		if ((isset($fields->class) AND !stristr($fields->class, 'bannerlogo')) OR !isset($fields->class)) {
			$css['background'] = (isset($fields->$backgroundimageurl) AND $fields->$backgroundimageurl) ? "\tbackground: " . $backgroundcolorvalue . " url(" . $imageurl . ") " . $backgroundimageleftvalue . " " . $backgroundimagetopvalue . " " . $backgroundimagerepeatvalue . " " . $backgroundimageattachmentvalue . ";\r\n" : $css['background'];
			if ($hasopacity) 
				$css['background'] .= (isset($fields->$backgroundimageurl) AND $fields->$backgroundimageurl) ? "\tbackground: " . $rgbavalue . " url(" . $imageurl . ") " . $backgroundimageleftvalue . " " . $backgroundimagetopvalue . " " . $backgroundimagerepeatvalue . " " . $backgroundimageattachmentvalue . ";\r\n" : "";
		}

		//set the background size
		if (isset($fields->$backgroundimageurl) AND $fields->$backgroundimageurl AND isset($fields->$backgroundimagesize) AND $fields->$backgroundimagesize != 'none') {
			$css['background'] .= "\tbackground-size: " . $fields->$backgroundimagesize . ";\r\n";
		}

		$css['background'] .= (isset($fields->$opacity) AND $fields->$opacity) ? "\topacity: " . ($fields->$opacity / 100) . ";" : "";

		$gradient0colorvalue = (isset($fields->$backgroundcolor) AND $fields->$backgroundcolor) ? $fields->$backgroundcolor : "";
		$gradient1colorvalue = (isset($fields->$gradientcolor) AND $fields->$gradientcolor) ? $fields->$gradientcolor : "";
		$gradient1positionvalue = (isset($fields->$gradient1position) AND $fields->$gradient1position) ? $fields->$gradient1position . "%" : "100%";
		$gradient2colorvalue = (isset($fields->$gradient2color) AND $fields->$gradient2color) ? $fields->$gradient2color : "";
		$gradient2positionvalue = (isset($fields->$gradient2position) AND $fields->$gradient2position) ? $fields->$gradient2position . "%" : "";
		$gradient3colorvalue = (isset($fields->$gradient3color) AND $fields->$gradient3color) ? $fields->$gradient3color : "";
		$gradient3positionvalue = (isset($fields->$gradient3position) AND $fields->$gradient3position) ? $fields->$gradient3position . "%" : "";

		if (isset($fields->$gradientdirection)) {
			switch ($fields->$gradientdirection) {
				case 'bottomtop':
					$gradientdirectionvalue = 'center bottom';
					$gradientdirectionvaluebis = 'left bottom, left top';
					$gradientdirectionvaluebis2 = 'x1="0%" y1="100%"
				x2="0%" y2="0%"';
					$gradientdirectionvalue3 = 'to top';
					break;
				case 'leftright':
					$gradientdirectionvalue = 'center left';
					$gradientdirectionvaluebis = 'left top, right top';
					$gradientdirectionvaluebis2 = 'x1="0%" y1="0%"
				x2="100%" y2="0%"';
					$gradientdirectionvalue3 = 'to right';
					break;
				case 'rightleft':
					$gradientdirectionvalue = 'center right';
					$gradientdirectionvaluebis = 'right top, left top';
					$gradientdirectionvaluebis2 = 'x1="100%" y1="0%"
				x2="0%" y2="0%"';
					$gradientdirectionvalue3 = 'to left';
					break;
				case 'topbottom':
				default :
					$gradientdirectionvalue = 'center top';
					$gradientdirectionvaluebis = 'left top, left bottom';
					$gradientdirectionvaluebis2 = 'x1="0%" y1="0%"
				x2="0%" y2="100%"';
					$gradientdirectionvalue3 = 'to bottom';
					break;
			}
		} else {
			$gradientdirectionvalue = 'center top';
			$gradientdirectionvaluebis = 'left top, left bottom';
			$gradientdirectionvaluebis2 = 'x1="0%" y1="0%"
				x2="0%" y2="100%"';
			$gradientdirectionvalue3 = 'to bottom';
		}


		$gradientstop2 = '';
		$gradientstop2webkit = '';
		$gradientstop2bis = '';
		$gradientstop3 = '';
		$gradientstop3webkit = '';
		$gradientstop3bis = '';
		if ($gradient2colorvalue AND $gradient2positionvalue) {
			$gradientstop2 = ',' . $gradient2colorvalue . ' ' . $gradient2positionvalue;
			$gradientstop2webkit = ',color-stop(' . $gradient2positionvalue . ',' . $gradient2colorvalue . ')';
			$gradientstop2bis = '<stop offset="' . $gradient2positionvalue . '"   stop-color="' . $gradient2colorvalue . '" stop-opacity="1"/>';
		}
		if ($gradient3colorvalue AND $gradient3positionvalue) {
			$gradientstop3 = ',' . $gradient3colorvalue . ' ' . $gradient3positionvalue;
			$gradientstop3webkit = ',color-stop(' . $gradient3positionvalue . ',' . $gradient3colorvalue . ')';
			$gradientstop3bis = '<stop offset="' . $gradient3positionvalue . '"   stop-color="' . $gradient3colorvalue . '" stop-opacity="1"/>';
		}



		if ($gradient0colorvalue && $gradient1colorvalue) {
			// $css['gradient'] = "\tbackground-image: url(\"" . $prefix . $id . "-gradient.svg\");\r\n"
			$css['gradient'] = ""
					. "\tbackground-image: -o-linear-gradient(" . $gradientdirectionvalue . "," . $gradient0colorvalue . $gradientstop2 . $gradientstop3 . ", " . $gradient1colorvalue . ' ' . $gradient1positionvalue . ");\r\n"
					. "\tbackground-image: -webkit-gradient(linear, " . $gradientdirectionvaluebis . ",from(" . $gradient0colorvalue . ")" . $gradientstop2webkit . $gradientstop3webkit . ", color-stop(" . $gradient1positionvalue . ', ' . $gradient1colorvalue . "));\r\n"
					. "\tbackground-image: -moz-linear-gradient(" . $gradientdirectionvalue . "," . $gradient0colorvalue . $gradientstop2 . $gradientstop3 . ", " . $gradient1colorvalue . ' ' . $gradient1positionvalue . ");\r\n"
					. "\tbackground-image: linear-gradient(" . $gradientdirectionvalue3 . "," . $gradient0colorvalue . $gradientstop2 . $gradientstop3 . ", " . $gradient1colorvalue . ' ' . $gradient1positionvalue . ");\r\n";
					// . "\t-pie-background: linear-gradient(" . $gradientdirectionvalue . "," . $gradient0colorvalue . $gradientstop2 . $gradientstop3 . ", " . $gradient1colorvalue . ' ' . $gradient1positionvalue . ");\r\n";

			/*
			// create the file svg for IE9 and Opera gradient compatibility
			$svgie9cssdest = $path . '/css/' . $prefix . $id . '-gradient.svg';
			$svgie9csstext = '<?xml version="1.0" ?>
              <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" version="1.0" width="100%"
              height="100%"
              xmlns:xlink="http://www.w3.org/1999/xlink">

              <defs>
              <linearGradient id="' . $prefix . $id . '"
              ' . $gradientdirectionvaluebis2 . '
              spreadMethod="pad">
              <stop offset="0%"   stop-color="' . $gradient0colorvalue . '" stop-opacity="1"/>
              ' . $gradientstop2bis . '
              ' . $gradientstop3bis . '
              <stop offset="' . $gradient1positionvalue . '" stop-color="' . $gradient1colorvalue . '" stop-opacity="1"/>
              </linearGradient>
              </defs>

              <rect width="100%" height="100%"
              style="fill:url(#' . $prefix . $id . ');" />
              </svg>
              ';
			if (!\Joomla\CMS\Filesystem\File::write($svgie9cssdest, $svgie9csstext)) {
				echo '<p class="error">' . \Joomla\CMS\Language\Text::_('CK_ERROR_CREATING_SVGIE9CSS') . '</p>';
			}*/
		} else {
			$css['gradient'] = "";
		}


		// construct variable names
		$borderscolor = $prefix . 'borderscolor';
		$borderssize = $prefix . 'borderssize';
		$bordersstyle = $prefix . 'bordersstyle';
		$bordertopcolor = $prefix . 'bordertopcolor';
		$bordertopsize = $prefix . 'bordertopsize';
		$bordertopstyle = $prefix . 'bordertopstyle';
		$borderbottomcolor = $prefix . 'borderbottomcolor';
		$borderbottomsize = $prefix . 'borderbottomsize';
		$borderbottomstyle = $prefix . 'borderbottomstyle';
		$borderleftcolor = $prefix . 'borderleftcolor';
		$borderleftsize = $prefix . 'borderleftsize';
		$borderleftstyle = $prefix . 'borderleftstyle';
		$borderrightcolor = $prefix . 'borderrightcolor';
		$borderrightsize = $prefix . 'borderrightsize';
		$borderrightstyle = $prefix . 'borderrightstyle';
		// for border radius
		$borderradius = $prefix . 'borderradius';
		$borderradiustopleft = $prefix . 'borderradiustopleft';
		$borderradiustopright = $prefix . 'borderradiustopright';
		$borderradiusbottomleft = $prefix . 'borderradiusbottomleft';
		$borderradiusbottomright = $prefix . 'borderradiusbottomright';

		$fields->$bordersstyle = isset($fields->$bordersstyle) ? $fields->$bordersstyle : 'solid';
		$fields->$bordertopstyle = isset($fields->$bordertopstyle) ? $fields->$bordertopstyle : 'solid';
		$fields->$borderbottomstyle = isset($fields->$borderbottomstyle) ? $fields->$borderbottomstyle : 'solid';
		$fields->$borderleftstyle = isset($fields->$borderleftstyle) ? $fields->$borderleftstyle : 'solid';
		$fields->$borderrightstyle = isset($fields->$borderrightstyle) ? $fields->$borderrightstyle : 'solid';

		$css['borders'] = (isset($fields->$borderssize) AND $fields->$borderssize == '0') ? "\tborder: none;\r\n" : "";
		$css['bordertop'] = (isset($fields->$bordertopsize) AND $fields->$bordertopsize == '0') ? "\tborder-top: none;\r\n" : "";
		$css['borderbottom'] = (isset($fields->$borderbottomsize) AND $fields->$borderbottomsize == '0') ? "\tborder-bottom: none;\r\n" : "";
		$css['borderleft'] = (isset($fields->$borderleftsize) AND $fields->$borderleftsize == '0') ? "\tborder-left: none;\r\n" : "";
		$css['borderright'] = (isset($fields->$borderrightsize) AND $fields->$borderrightsize == '0') ? "\tborder-right: none;\r\n" : "";

		$css['borders'] = (isset($fields->$borderscolor) AND $fields->$borderscolor AND isset($fields->$borderssize) AND $fields->$borderssize) ? "\tborder: " . $fields->$borderscolor . " " . $this->testUnit($fields->$borderssize) . " " . $fields->$bordersstyle . ";\r\n" : $css['borders'];
		$css['bordertop'] = (isset($fields->$bordertopcolor) AND $fields->$bordertopcolor AND isset($fields->$bordertopsize) AND $fields->$bordertopsize) ? "\tborder-top: " . $fields->$bordertopcolor . " " . $this->testUnit($fields->$bordertopsize) . " " . $fields->$bordertopstyle . ";\r\n" : $css['bordertop'];
		$css['borderbottom'] = (isset($fields->$borderbottomcolor) AND $fields->$borderbottomcolor AND isset($fields->$borderbottomsize) AND $fields->$borderbottomsize) ? "\tborder-bottom: " . $fields->$borderbottomcolor . " " . $this->testUnit($fields->$borderbottomsize) . " " . $fields->$borderbottomstyle . ";\r\n" : $css['borderbottom'];
		$css['borderleft'] = (isset($fields->$borderleftcolor) AND $fields->$borderleftcolor AND isset($fields->$borderleftsize) AND $fields->$borderleftsize) ? "\tborder-left: " . $fields->$borderleftcolor . " " . $this->testUnit($fields->$borderleftsize) . " " . $fields->$borderleftstyle . ";\r\n" : $css['borderleft'];
		$css['borderright'] = (isset($fields->$borderrightcolor) AND $fields->$borderrightcolor AND isset($fields->$borderrightsize) AND $fields->$borderrightsize) ? "\tborder-right: " . $fields->$borderrightcolor . " " . $this->testUnit($fields->$borderrightsize) . " " . $fields->$borderrightstyle . ";\r\n" : $css['borderright'];

		// compile all borders
		$css['borders'] .= $css['bordertop'] . $css['borderbottom'] . $css['borderleft'] . $css['borderright'];

		// $borderradiusvalue = (isset($fields->$borderradius) AND ($fields->$borderradius || $fields->$borderradius == "0")) ? $fields->$borderradius : "0";
		$borderradiusvalue = "0";
		$borderradiustopleftvalue = (isset($fields->$borderradiustopleft) AND ($fields->$borderradiustopleft || $fields->$borderradiustopleft == "0")) ? $fields->$borderradiustopleft : $borderradiusvalue;
		$borderradiustoprightvalue = (isset($fields->$borderradiustopright) AND ($fields->$borderradiustopright || $fields->$borderradiustopleft == "0")) ? $fields->$borderradiustopright : $borderradiusvalue;
		$borderradiusbottomleftvalue = (isset($fields->$borderradiusbottomleft) AND ($fields->$borderradiusbottomleft || $fields->$borderradiustopleft == "0")) ? $fields->$borderradiusbottomleft : $borderradiusvalue;
		$borderradiusbottomrightvalue = (isset($fields->$borderradiusbottomright) AND ($fields->$borderradiusbottomright || $fields->$borderradiustopleft == "0")) ? $fields->$borderradiusbottomright : $borderradiusvalue;

		if ( (isset($fields->$borderradiustopleft) AND $fields->$borderradiustopleft != "")
			|| (isset($fields->$borderradiustopright) AND $fields->$borderradiustopright != "")
			|| (isset($fields->$borderradiusbottomleft) AND $fields->$borderradiusbottomleft != "")
			|| (isset($fields->$borderradiusbottomright) AND $fields->$borderradiusbottomright != "")
		) {
			// $css['borderradius'] = "\t-moz-border-radius: " . $this->testUnit($borderradiusvalue) . ";\r\n"
					// . "\t-o-border-radius: " . $this->testUnit($borderradiusvalue) . ";\r\n"
					// . "\t-webkit-border-radius: " . $this->testUnit($borderradiusvalue) . ";\r\n"
					// . "\tborder-radius: " . $this->testUnit($borderradiusvalue) . ";\r\n"
			$css['borderradius'] =  "\t-moz-border-radius: " . $this->testUnit($borderradiustopleftvalue) . " " . $this->testUnit($borderradiustoprightvalue) . " " . $this->testUnit($borderradiusbottomrightvalue) . " " . $this->testUnit($borderradiusbottomleftvalue) . ";\r\n"
					. "\t-o-border-radius: " . $this->testUnit($borderradiustopleftvalue) . " " . $this->testUnit($borderradiustoprightvalue) . " " . $this->testUnit($borderradiusbottomrightvalue) . " " . $this->testUnit($borderradiusbottomleftvalue) . ";\r\n"
					. "\t-webkit-border-radius: " . $this->testUnit($borderradiustopleftvalue) . " " . $this->testUnit($borderradiustoprightvalue) . " " . $this->testUnit($borderradiusbottomrightvalue) . " " . $this->testUnit($borderradiusbottomleftvalue) . ";\r\n"
					. "\tborder-radius: " . $this->testUnit($borderradiustopleftvalue) . " " . $this->testUnit($borderradiustoprightvalue) . " " . $this->testUnit($borderradiusbottomrightvalue) . " " . $this->testUnit($borderradiusbottomleftvalue) . ";\r\n";
		} else {
			$css['borderradius'] = "";
		}

		// construct variable names
		$height = $prefix . 'height';
		$width = $prefix . 'width';
		$color = $prefix . 'color';
		$lineheight = $prefix . 'lineheight';
		$margintop = $prefix . 'margintop';
		$marginbottom = $prefix . 'marginbottom';
		$marginleft = $prefix . 'marginleft';
		$marginright = $prefix . 'marginright';
		$margins = $prefix . 'margins';
		$paddingtop = $prefix . 'paddingtop';
		$paddingbottom = $prefix . 'paddingbottom';
		$paddingleft = $prefix . 'paddingleft';
		$paddingright = $prefix . 'paddingright';
		$paddings = $prefix . 'paddings';

		$css['height'] = (isset($fields->$height) AND $fields->$height) ? "\theight: " . $this->testUnit($fields->$height) . ";\r\n" : "";
		$css['width'] = (isset($fields->$width) AND $fields->$width) ? "\twidth: " . $this->testUnit($fields->$width) . ";\r\n" : "";
		$css['color'] = (isset($fields->$color) AND $fields->$color) ? "\tcolor: " . $fields->$color . ";\r\n" : "";
		$css['lineheight'] = (isset($fields->$lineheight) AND $fields->$lineheight) ? "\tline-height: " . $this->testUnit($fields->$lineheight) . ";\r\n" : "";
		$css['margintop'] = (isset($fields->$margintop) AND ($fields->$margintop OR $fields->$margintop == '0')) ? "\tmargin-top: " . $this->testUnit($fields->$margintop) . ";\r\n" : "";
		$css['marginbottom'] = (isset($fields->$marginbottom) AND ($fields->$marginbottom OR $fields->$marginbottom == '0')) ? "\tmargin-bottom: " . $this->testUnit($fields->$marginbottom) . ";\r\n" : "";
		$css['marginleft'] = (isset($fields->$marginleft) AND ($fields->$marginleft OR $fields->$marginleft == '0')) ? "\tmargin-left: " . $this->testUnit($fields->$marginleft) . ";\r\n" : "";
		$css['margins'] = (isset($fields->$margins) AND ($fields->$margins OR $fields->$margins == '0')) ? "\tmargin: " . $this->testUnit($fields->$margins) . ";\r\n" : "";
		$css['marginright'] = (isset($fields->$marginright) AND ($fields->$marginright OR $fields->$marginright == '0')) ? "\tmargin-right: " . $this->testUnit($fields->$marginright) . ";\r\n" : "";
		$css['paddingtop'] = (isset($fields->$paddingtop) AND ($fields->$paddingtop OR $fields->$paddingtop == '0')) ? "\tpadding-top: " . $this->testUnit($fields->$paddingtop) . ";\r\n" : "";
		$css['paddingbottom'] = (isset($fields->$paddingbottom) AND ($fields->$paddingbottom OR $fields->$paddingbottom == '0')) ? "\tpadding-bottom: " . $this->testUnit($fields->$paddingbottom) . ";\r\n" : "";
		$css['paddingleft'] = (isset($fields->$paddingleft) AND ($fields->$paddingleft OR $fields->$paddingleft == '0')) ? "\tpadding-left: " . $this->testUnit($fields->$paddingleft) . ";\r\n" : "";
		$css['paddingright'] = (isset($fields->$paddingright) AND ($fields->$paddingright OR $fields->$paddingright == '0')) ? "\tpadding-right: " . $this->testUnit($fields->$paddingright) . ";\r\n" : "";
		$css['paddings'] = (isset($fields->$paddings) AND ($fields->$paddings OR $fields->$paddings == '0')) ? "\tpadding: " . $this->testUnit($fields->$paddings) . ";\r\n" : "";

		$css['margins'] .= $css['margintop'] . $css['marginright'] . $css['marginbottom'] . $css['marginleft'];
		$css['paddings'] .= $css['paddingtop'] . $css['paddingright'] . $css['paddingbottom'] . $css['paddingleft'];

		// construct variable names
		$shadowcolor = $prefix . 'shadowcolor';
		$shadowhoffset = $prefix . 'shadowoffseth';
		$shadowvoffset = $prefix . 'shadowoffsetv';
		$shadowblur = $prefix . 'shadowblur';
		$shadowspread = $prefix . 'shadowspread';
		$shadowinset = $prefix . 'shadowinset';
		$shadowopacity = $prefix . 'shadowopacity';

		// manage shadow box
		$shadowcolorvalue = (isset($fields->$shadowcolor) AND $fields->$shadowcolor) ? $fields->$shadowcolor : "";
		$shadowhoffsetvalue = (isset($fields->$shadowhoffset) AND $fields->$shadowhoffset) ? $fields->$shadowhoffset : "0";
		$shadowvoffsetvalue = (isset($fields->$shadowvoffset) AND $fields->$shadowvoffset) ? $fields->$shadowvoffset : "0";
		$shadowblurvalue = (isset($fields->$shadowblur) AND $fields->$shadowblur) ? $fields->$shadowblur : "";
		$shadowspreadvalue = (isset($fields->$shadowspread) AND $fields->$shadowspread) ? $fields->$shadowspread : "0";
		$shadowinsetvalue = (isset($fields->$shadowinset) AND $fields->$shadowinset === '1') ? ' inset' : '';

		// manage rgba color for opacity
		if (isset($fields->$shadowopacity) AND $fields->$shadowopacity !== '' AND $shadowcolorvalue !== '') {
			$shadowcolorvalue = $this->hex2RGB($shadowcolorvalue, $fields->$shadowopacity);
		}
		
		if ($shadowcolorvalue && $shadowblurvalue) {
			$css['shadow'] = "\tbox-shadow: " . $shadowcolorvalue . " " . $this->testUnit($shadowhoffsetvalue) . " " . $this->testUnit($shadowvoffsetvalue) . " " . $this->testUnit($shadowblurvalue) . " " . $this->testUnit($shadowspreadvalue) . $shadowinsetvalue . ";\r\n"
					. "\t-moz-box-shadow: " . $shadowcolorvalue . " " . $this->testUnit($shadowhoffsetvalue) . " " . $this->testUnit($shadowvoffsetvalue) . " " . $this->testUnit($shadowblurvalue) . " " . $this->testUnit($shadowspreadvalue) . $shadowinsetvalue . ";\r\n"
					. "\t-webkit-box-shadow: " . $shadowcolorvalue . " " . $this->testUnit($shadowhoffsetvalue) . " " . $this->testUnit($shadowvoffsetvalue) . " " . $this->testUnit($shadowblurvalue) . " " . $this->testUnit($shadowspreadvalue) . $shadowinsetvalue . ";\r\n";
		} else {
			$css['shadow'] = "";
		}

		// construct variable names
		$fontactivation = $prefix . 'fontactivation';
		// $fontbold = $prefix . 'fontbold';
		$fontitalic = $prefix . 'fontitalic';
		$fontunderline = $prefix . 'fontunderline';
		// $fontuppercase = $prefix . 'fontuppercase';
		$fontfamily = $prefix . 'fontfamily';
		$googlefont = $prefix . 'googlefont';
		$fontweight = $prefix . 'fontweight';
		$fontsize = $prefix . 'fontsize';
		// $alignementactivation = $prefix . 'alignementactivation';
		// $alignement = $prefix . 'alignement';
		// $alignementleft = $prefix . 'alignementleft';
		// $alignementcenter = $prefix . 'alignementcenter';
		// $alignementjustify = $prefix . 'alignementjustify';
		// $alignementright = $prefix . 'alignementright';
		$wordspacing = $prefix . 'wordspacing';
		$letterspacing = $prefix . 'letterspacing';
		$textindent = $prefix . 'textindent';
		$textalign = $prefix . 'textalign';
		$fontweight = $prefix . 'fontweight';
		$texttransform = $prefix . 'texttransform';

		// $css['alignement'] = "";
		// if (isset($fields->$alignementright) AND $fields->$alignementright == 'checked') {
			// $css['alignement'] = $direction == "rtl" ? "\ttext-align: left;\r\n" : "\ttext-align: right;\r\n";
		// } else if (isset($fields->$alignementcenter) AND $fields->$alignementcenter == 'checked') {
			// $css['alignement'] = "\ttext-align: center;\r\n";
		// } else if (isset($fields->$alignementjustify) AND $fields->$alignementjustify == 'checked') {
			// $css['alignement'] = "\ttext-align: justify;\r\n";
		// } else if (isset($fields->$alignementleft) AND $fields->$alignementleft == 'checked') {
			// $css['alignement'] = $direction == "rtl" ? "\ttext-align: right;\r\n" : "\ttext-align: left;\r\n";
			// ;
		// }

		// $css['fontbold'] = "";
		$css['fontitalic'] = "";
		$css['fontunderline'] = "";
		$css['fontuppercase'] = "";
		
		$css['alignement'] = (isset($fields->$textalign) AND $fields->$textalign) ? "\ttext-align: " . $fields->$textalign . ";\r\n" : "";
		$css['fontbold'] = (isset($fields->$fontweight) AND $fields->$fontweight) ? "\tfont-weight: " . $fields->$fontweight . ";\r\n" : "";
		$css['fontuppercase'] = (isset($fields->$texttransform) AND $fields->$texttransform) ? "\ttext-transform: " . $fields->$texttransform . ";\r\n" : "";
		
		

		// if (isset($fields->$fontbold) AND $fields->$fontbold) {
			// if ($fields->$fontbold != 'default')
				// $css['fontbold'] = $fields->$fontbold == 'bold' ? "\tfont-weight: bold;\r\n" : "\tfont-weight: normal;\r\n";
		// }

		if (isset($fields->$fontitalic) AND $fields->$fontitalic) {
			if ($fields->$fontitalic != 'default')
				$css['fontitalic'] = $fields->$fontitalic == 'italic' ? "\tfont-style: italic;\r\n" : "\tfont-style: normal;\r\n";
		}

		if (isset($fields->$fontunderline) AND $fields->$fontunderline) {
			if ($fields->$fontunderline != 'default')
				$css['fontunderline'] = $fields->$fontunderline == 'underline' ? "\ttext-decoration: underline;\r\n" : "\ttext-decoration: none;\r\n";
		}

		// if (isset($fields->$fontuppercase) AND $fields->$fontuppercase) {
			// if ($fields->$fontuppercase != 'default')
				// $css['fontuppercase'] = $fields->$fontuppercase == 'uppercase' ? "\ttext-transform: uppercase;\r\n" : "\ttext-transform: none;\r\n";
		// }

		$css['textindent'] = (isset($fields->$textindent) AND $fields->$textindent) ? "\ttext-indent: " . $this->testUnit($fields->$textindent) . ";\r\n" : "";
		$css['letterspacing'] = (isset($fields->$letterspacing) AND $fields->$letterspacing) ? "\tletter-spacing: " . $this->testUnit($fields->$letterspacing) . ";\r\n" : "";
		$css['wordspacing'] = (isset($fields->$wordspacing) AND $fields->$wordspacing) ? "\tword-spacing: " . $this->testUnit($fields->$wordspacing) . ";\r\n" : "";
		$css['fontsize'] = (isset($fields->$fontsize) AND $fields->$fontsize) ? "\tfont-size: " . $this->testUnit($fields->$fontsize) . ";\r\n" : "";
		$css['fontstylessquirrel'] = '';
		if (isset($fields->$fontfamily) AND $fields->$fontfamily == 'googlefont') {
			$css['fontfamily'] = (isset($fields->$googlefont) AND $fields->$googlefont != "default") ? "\tfont-family: '" . $fields->$googlefont . "';\r\n" : "";
			$css['fontbold'] = (isset($fields->$fontweight) AND $fields->$fontweight != "") ? "\tfont-weight: " . $fields->$fontweight . ";\r\n" : "";
		} else {
			$css['fontfamily'] = (isset($fields->$fontfamily) AND $fields->$fontfamily != "default") ? "\tfont-family: " . $fields->$fontfamily . ";\r\n" : "";
		}
		// compatibility with multiple intefaces
		$gfontfamily = $prefix . 'textgfont';
		if (isset($fields->$gfontfamily) AND $fields->$gfontfamily) {
			$fields->$gfontfamily = str_replace('+', ' ', $fields->$gfontfamily);
			$css['fontfamily'] .= (isset($fields->$gfontfamily) AND $fields->$gfontfamily) ? "\tfont-family: '" . $fields->$gfontfamily . "';\r\n" : "";
		}


		// construct variable names
		$normallinkfontbold = $prefix . 'normallinkfontbold';
		$normallinkfontitalic = $prefix . 'normallinkfontitalic';
		$normallinkfontunderline = $prefix . 'normallinkfontunderline';
		$normallinkfontuppercase = $prefix . 'normallinkfontuppercase';
		$normallinkcolor = $prefix . 'normallinkcolor';

		$css['normallinkfontbold'] = "";
		$css['normallinkfontitalic'] = "";
		$css['normallinkfontunderline'] = "";
		$css['normallinkfontuppercase'] = "";

		if (isset($fields->$normallinkfontbold) AND $fields->$normallinkfontbold) {
			if ($fields->$normallinkfontbold != 'default')
				$css['normallinkfontbold'] = $fields->$normallinkfontbold == 'bold' ? "\tfont-weight: bold;\r\n" : "\tfont-weight: normal;\r\n";
		}

		if (isset($fields->$normallinkfontitalic) AND $fields->$normallinkfontitalic) {
			if ($fields->$normallinkfontitalic != 'default')
				$css['normallinkfontitalic'] = $fields->$normallinkfontitalic == 'italic' ? "\tfont-style: italic;\r\n" : "\tfont-style: normal;\r\n";
		}

		if (isset($fields->$normallinkfontunderline) AND $fields->$normallinkfontunderline) {
			if ($fields->$normallinkfontunderline != 'default')
				$css['normallinkfontunderline'] = $fields->$normallinkfontunderline == 'underline' ? "\ttext-decoration: underline;\r\n" : "\ttext-decoration: none;\r\n";
		}

		if (isset($fields->$normallinkfontuppercase) AND $fields->$normallinkfontuppercase) {
			if ($fields->$normallinkfontuppercase != 'default')
				$css['normallinkfontuppercase'] = $fields->$normallinkfontuppercase == 'uppercase' ? "\ttext-transform: uppercase;\r\n" : "\ttext-transform: none;\r\n";
		}

		$css['normallinkcolor'] = (isset($fields->$normallinkcolor) AND $fields->$normallinkcolor) ? "\tcolor: " . $fields->$normallinkcolor . ";\r\n" : "";


		// construct variable names
		$hoverlinkactivation = $prefix . 'hoverlinkactivation';
		$hoverlinkfontbold = $prefix . 'hoverlinkfontbold';
		$hoverlinkfontitalic = $prefix . 'hoverlinkfontitalic';
		$hoverlinkfontunderline = $prefix . 'hoverlinkfontunderline';
		$hoverlinkfontuppercase = $prefix . 'hoverlinkfontuppercase';
		$hoverlinkcolor = $prefix . 'hoverlinkcolor';

		$css['hoverlinkfontbold'] = "";
		$css['hoverlinkfontitalic'] = "";
		$css['hoverlinkfontunderline'] = "";
		$css['hoverlinkfontuppercase'] = "";

		if (isset($fields->$hoverlinkfontbold) AND $fields->$hoverlinkfontbold) {
			if ($fields->$hoverlinkfontbold != 'default')
				$css['hoverlinkfontbold'] = $fields->$hoverlinkfontbold == 'bold' ? "\tfont-weight: bold;\r\n" : "\tfont-weight: normal;\r\n";
		}

		if (isset($fields->$hoverlinkfontitalic) AND $fields->$hoverlinkfontitalic) {
			if ($fields->$hoverlinkfontitalic != 'default')
				$css['hoverlinkfontitalic'] = $fields->$hoverlinkfontitalic == 'italic' ? "\tfont-style: italic;\r\n" : "\tfont-style: normal;\r\n";
		}

		if (isset($fields->$hoverlinkfontunderline) AND $fields->$hoverlinkfontunderline) {
			if ($fields->$hoverlinkfontunderline != 'default')
				$css['hoverlinkfontunderline'] = $fields->$hoverlinkfontunderline == 'underline' ? "\ttext-decoration: underline;\r\n" : "\ttext-decoration: none;\r\n";
		}

		if (isset($fields->$hoverlinkfontuppercase) AND $fields->$hoverlinkfontuppercase) {
			if ($fields->$hoverlinkfontuppercase != 'default')
				$css['hoverlinkfontuppercase'] = $fields->$hoverlinkfontuppercase == 'uppercase' ? "\ttext-transform: uppercase;\r\n" : "\ttext-transform: none;\r\n";
		}

		$css['hoverlinkcolor'] = (isset($fields->$hoverlinkcolor) AND $fields->$hoverlinkcolor) ? "\tcolor: " . $fields->$hoverlinkcolor . ";\r\n" : "";


		$custom = $prefix . 'custom';
		$css['custom'] = (isset($fields->$custom) AND $fields->$custom) ? "\t" . $fields->$custom . "\r\n" : "";

		return $css;
	}

	/**
	* Set the CSS3 animations for the blocks
	*/
	private function genAnimations($fields, $prefix, $id) { 
		if (! isset($fields->{$prefix . 'animfade'})) return; // if no animation field is found, nothing to do here

		// fade, move, rotate, scale, flip?rotateY, replay
		$css = '';
		$transition = Array(); // transition: opacity 0.4s;transition: opacity 0.2s, transform 0.35s;
		$transform0 = Array(); // transform: rotate(45deg);transform: translate3d(0,40px,0);
		$transform100 = Array(); // transform: rotate(45deg);transform: translate3d(0,40px,0);
		$style0 = Array();
		$style100 = Array();
		$duration = isset($fields->{$prefix . 'animdur'}) && $fields->{$prefix . 'animdur'} ? $fields->{$prefix . 'animdur'} . 's' : '1s';
		$delay = isset($fields->{$prefix . 'animdelay'}) && $fields->{$prefix . 'animdelay'} ? $fields->{$prefix . 'animdelay'} . 's' : '0s';
		// fade effect
		if ($fields->{$prefix . 'animfade'} == '1') {
			$transition['fade'] = 'opacity ' . $duration;
			$style0[] = 'opacity: 0';
			$style100[] = 'opacity: 1';
		}
		// move effect
		if ($fields->{$prefix . 'animmove'} == '1') {
			$transition['transform'] = 'transform ' . $duration;
			switch($fields->{$prefix . 'animmovedir'}) {
				case 'ltrck':
				default:
					$transform0[] = 'translate3d(-' . (int)$fields->{$prefix . 'animmovedist'} . 'px,0,0)';
				break;
				case 'rtlck':
					$transform0[] = 'translate3d(' . (int)$fields->{$prefix . 'animmovedist'} . 'px,0,0)';
				break;
				case 'ttbck':
					$transform0[] = 'translate3d(0,-' . (int)$fields->{$prefix . 'animmovedist'} . 'px,0)';
				break;
				case 'bttck':
					$transform0[] = 'translate3d(0,' . (int)$fields->{$prefix . 'animmovedist'} . 'px,0)';
				break;
			}

//			$transform100[] = 'translate3d(0,0,0)';
		}
		// rotate effect
		if ($fields->{$prefix . 'animrot'} == '1') {
			$transition['transform'] = (isset($transition['transform']) && $transition['transform']) ? $transition['transform'] : 'transform ' . $duration;
			$transform0[] = 'rotate(' . $fields->{$prefix . 'animrotrad'} . 'deg)';
			$transform100[] = 'rotate(0deg)';
		}
		// scale effect
		if ($fields->{$prefix . 'animscale'} == '1') {
			$transition['transform'] = (isset($transition['transform']) && $transition['transform']) ? $transition['transform'] : 'transform ' . $duration;
			$transform0[] = 'scale(0)';
			$transform100[] = 'scale(1)';
		}

		if (count($transition)) {
			// start
			$css .= $id . ' {
				-webkit-transition: ' . implode(', ', $transition) . ';
				transition: ' . implode(', ', $transition) . ';

				' . (count($transform0) ? '-webkit-transform: ' . implode(' ', $transform0) . ';
				transform: ' . implode(' ', $transform0) . ';' : '') . '
				' . implode(';', $style0) . ';
				 -webkit-transition-delay: ' . $delay . ';
				transition-delay: ' . $delay . ';
			}
			';
			// end
			$id = str_replace('|ID|', '|ID| .cameravisible', $id);
			$css .= $id . ' {
				' . (count($transform0) ? '-webkit-transform: ' . implode(' ', $transform100) . ';
				transform: ' . implode(' ', $transform100) . ';' : '') . '
				' . implode(';', $style100) . ';
			}';
		}

		return $css;
	}

	/**
	* Set the CSS3 animations for the blocks
	*/
	private function genEffects($fields, $prefix, $id) {
		if (! isset($fields->{$prefix . 'fxopacity'})) return; // if no animation field is found, nothing to do here

		$css = '';
		$style = Array();
		$transition = Array();
		$transform = Array();
		$filter = Array();
		$fxdur = isset($fields->{$prefix . 'fxdur'}) ? $fields->{$prefix . 'fxdur'} : 0;
		$duration = isset($fields->{$prefix . 'fxdur'}) && $fields->{$prefix . 'fxdur'} ? $fields->{$prefix . 'fxdur'} . 's' : '0s';
		$delay = isset($fields->{$prefix . 'fxdelay'}) && $fields->{$prefix . 'fxdelay'} ? $fields->{$prefix . 'fxdelay'} . 's' : '0s';

		// fade effect
		if (isset($fields->{$prefix . 'fxopacity'}) && $fields->{$prefix . 'fxopacity'} != '') {
			if ($fxdur) {
				$transition['fade'] = 'opacity ' . $duration;
			}
			$style[] = 'opacity: ' . $fields->{$prefix . 'fxopacity'};
		}

		// move effect
		if (isset($fields->{$prefix . 'fxmovedist'}) && $fields->{$prefix . 'fxmovedist'} != '') {
			if ($fxdur) {
				$transition['transform'] = 'transform ' . $duration;
			}
			switch($fields->{$prefix . 'fxmovedir'}) {
				case 'ltrck':
				default:
					$transform[] = 'translate3d(-' . (int)$fields->{$prefix . 'fxmovedist'} . 'px,0,0)';
				break;
				case 'rtlck':
					$transform[] = 'translate3d(' . (int)$fields->{$prefix . 'fxmovedist'} . 'px,0,0)';
				break;
				case 'ttbck':
					$transform[] = 'translate3d(0,-' . (int)$fields->{$prefix . 'fxmovedist'} . 'px,0)';
				break;
				case 'bttck':
					$transform[] = 'translate3d(0,' . (int)$fields->{$prefix . 'fxmovedist'} . 'px,0)';
				break;
			}
		}
		// rotate effect
		if (isset($fields->{$prefix . 'fxrotrad'}) && $fields->{$prefix . 'fxrotrad'} != '' && $fields->{$prefix . 'fxrot'} == '1') {
			if ($fxdur) $transition['transform'] = (isset($transition['transform']) && $transition['transform']) ? $transition['transform'] : 'transform ' . $duration;
			$transform[] = 'rotate(' . $fields->{$prefix . 'fxrotrad'} . 'deg)';
		}
		// scale effect
		if (isset($fields->{$prefix . 'fxscale'}) && $fields->{$prefix . 'fxscale'} != '') {
			if ($fxdur) $transition['transform'] = (isset($transition['transform']) && $transition['transform']) ? $transition['transform'] : 'transform ' . $duration;
			$transform[] = 'scale(' . $fields->{$prefix . 'fxscale'} . ')';
		}
		// blur effect
		if (isset($fields->{$prefix . 'fxblur'}) && $fields->{$prefix . 'fxblur'} != '') {
			if ($fxdur) $transition['filter'] = (isset($transition['filter']) && $transition['filter']) ? $transition['filter'] : 'filter ' . $duration;
			$filter[] = 'blur(' . $fields->{$prefix . 'fxblur'} . 'px)';
		}
		// brightness effect
		if (isset($fields->{$prefix . 'fxbrightness'}) && $fields->{$prefix . 'fxbrightness'} != '') {
			if ($fxdur) $transition['filter'] = (isset($transition['filter']) && $transition['filter']) ? $transition['filter'] : 'filter ' . $duration;
			$filter[] = 'brightness(' . $fields->{$prefix . 'fxbrightness'} . ')';
		}
		// grayscale effect
		if (isset($fields->{$prefix . 'fxgrayscale'}) && $fields->{$prefix . 'fxgrayscale'} != '') {
			if ($fxdur) $transition['filter'] = (isset($transition['filter']) && $transition['filter']) ? $transition['filter'] : 'filter ' . $duration;
			$filter[] = 'grayscale(' . $fields->{$prefix . 'fxgrayscale'} . ')';
		}

		if (count($transition)) {
			// start
			$css .= $id . ' {
				' . ($prefix == 'slidehover' || $prefix == 'slideactive' ? 'z-index: 1;' : '') . '
				-webkit-transition: ' . implode(', ', $transition) . ';
				transition: ' . implode(', ', $transition) . ';
				filter: ' . implode(' ', $filter) . ';

				' . (count($transform) ? '-webkit-transform: ' . implode(' ', $transform) . ';
				transform: ' . implode(' ', $transform) . ';' : '') . '
				' . implode(';', $style) . ';
				 -webkit-transition-delay: ' . $delay . ';
				transition-delay: ' . $delay . ';
			}
			';
		} else {
			$css .= $id . ' {
				' . ($prefix == 'slidehover' || $prefix == 'slideactive' ? 'z-index: 1;' : '') . '
				' . (count($transform) ? '-webkit-transform: ' . implode(' ', $transform) . ';
				transform: ' . implode(' ', $transform) . ';' : '') . '
				filter: ' . implode(' ', $filter) . ';
				' . implode(';', $style) . ';
			}
			';
		}

		return $css;
	}
		/**
	 * Test if there is already a unit, else add the px
	 *
	 * @param string $value
	 * @return string
	 */
	function testUnit($value, $defaultunit = "px") {

		if ((stristr($value, 'px')) OR (stristr($value, 'em')) OR (stristr($value, '%')) OR $value == 'auto')
			return $value;

		return $value . $defaultunit;
	}

	/**
	 * Convert a hexa decimal color code to its RGB equivalent
	 *
	 * @param string $hexStr (hexadecimal color value)
	 * @param boolean $returnAsString (if set true, returns the value separated by the separator character. Otherwise returns associative array)
	 * @param string $seperator (to separate RGB values. Applicable only if second parameter is true.)
	 * @return array or string (depending on second parameter. Returns False if invalid hex color value)
	 */
	function hex2RGB($hexStr, $opacity) {
		$opacity = $opacity <= 1 ? $opacity : $opacity / 100;
		$hexStr = preg_replace("/[^0-9A-Fa-f]/", '', $hexStr); // Gets a proper hex string
		$rgbArray = array();
		if (strlen($hexStr) == 6) { //If a proper hex code, convert using bitwise operation. No overhead... faster
			$colorVal = hexdec($hexStr);
			$rgbArray['red'] = 0xFF & ($colorVal >> 0x10);
			$rgbArray['green'] = 0xFF & ($colorVal >> 0x8);
			$rgbArray['blue'] = 0xFF & $colorVal;
		} elseif (strlen($hexStr) == 3) { //if shorthand notation, need some string manipulations
			$rgbArray['red'] = hexdec(str_repeat(substr($hexStr, 0, 1), 2));
			$rgbArray['green'] = hexdec(str_repeat(substr($hexStr, 1, 1), 2));
			$rgbArray['blue'] = hexdec(str_repeat(substr($hexStr, 2, 1), 2));
		} else {
			return false; //Invalid hex color code
		}
		$rgbacolor = "rgba(" . $rgbArray['red'] . "," . $rgbArray['green'] . "," . $rgbArray['blue'] . "," . $opacity . ")";

		return $rgbacolor;
	}
}


PKv�!]���eeckframework.phpnu&1i�<?php
/**
 * @name		CK Framework
 * @copyright	Copyright (C) 2019. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - https://www.template-creator.com - https://www.joomlack.fr
 */
namespace Slideshowck;

// No direct access to this file
defined('_JEXEC') or die('Restricted access');

require_once 'ckuri.php';

//use Joomla\CMS\Language\Text as CKText;
// use Joomla\CMS\Uri\Uri as CKUri;
use \Slideshowck\CKUri;

/**
 * Framework Helper
 */
class CKFramework {

	private static $assetsPath = '/media/com_slideshowck/assets';

	private static $version = '1.0.0';

	private static $doload;

	public static function init() {
		global $ckframeworkloaded;
		global $ckframeworkloadedversion;

		// if the framework is already loaded with a same or better version, do nothing
		if ($ckframeworkloaded && version_compare($ckframeworkloadedversion, self::$version, '>=')) {
			self::$doload = false;
		}

		self::$doload = true;
	}

	public static function getInline() {
		if (self::$doload === false) return '';

		$assets = self::getInlineCss() . self::getInlineJs();

		return $assets;
	}

	public static function getInlineCss() {
		if (self::$doload === false) return '';

		$assets = '<link rel="stylesheet" href="' . CKUri::root(true) . self::$assetsPath . '/ckframework.css" type="text/css" />';

		return $assets;
	}

	public static function getInlineJs() {
		if (self::$doload === false) return '';

		$assets = '<script src="' . CKUri::root(true) . self::$assetsPath . '/ckframework.js" type="text/javascript"></script>';

		return $assets;
	}

	public static function loadInline() {
		echo self::getInline();
	}

	public static function load() {
		if (self::$doload === false) return;

		\Joomla\CMS\HTML\HTMLHelper::_('jquery.framework');
		$doc = \Joomla\CMS\Factory::getDocument();
		$doc->addStylesheet(CKUri::root(true) . self::$assetsPath . '/ckframework.css');
		$doc->addScript(CKUri::root(true) . self::$assetsPath . '/ckframework.js');
	}

	public static function loadCss() {
		if (self::$doload === false) return;

		$doc = \Joomla\CMS\Factory::getDocument();
		$doc->addStylesheet(CKUri::root(true) . self::$assetsPath . '/ckframework.css');
	}

	public static function loadJs() {
		if (self::$doload === false) return;

		$doc = \Joomla\CMS\Factory::getDocument();
		$doc->addScript(CKUri::root(true) . self::$assetsPath . '/ckframework.js');
	}

	public static function getFaIconsInline() {
		return '<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous" />';
	}

	public static function loadFaIconsInline() {
		echo self::getFaIconsInline();
	}

	/*
	 * Load the JS and CSS files needed to use CKBox
	 *
	 * Return void
	 */
	public static function loadCkbox() {
		$doc = \Joomla\CMS\Factory::getDocument();
		\Joomla\CMS\HTML\HTMLHelper::_('jquery.framework');
		$doc->addStyleSheet(CKUri::root(true) . self::$assetsPath . '/ckbox.css');
		$doc->addScript(CKUri::root(true) . self::$assetsPath . '/ckbox.js');
	}
}

CKFramework::init();PKv�!]�/㆞���ckinterface.phpnu&1i�<?php
/**
 * @name		Slider CK
 * @package		com_slideshowck
 * @copyright	Copyright (C) 2016. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - http://www.template-creator.com - http://www.joomlack.fr
 */
namespace Slideshowck;

// No direct access to this file
defined('_JEXEC') or die('Restricted access');

use Slideshowck\CKUri;

class CKInterface extends \stdClass {

	public $imagespath;
	
	public $colorpicker_class = 'color {required:false,pickerPosition:\'top\',pickerBorder:2,pickerInset:3,hash:true}';

	public function __construct($properties = null) {
		$this->imagespath = SLIDESHOWCK_MEDIA_URI . '/images';
	}

	public function createAll($prefix) {
		?>
		<div class="ckheading"><?php echo CKText::_('CK_TEXT_LABEL'); ?></div>
		<?php
		$this->createText($prefix);
		?>
		<div class="ckheading"><?php echo CKText::_('CK_APPEARANCE_LABEL'); ?></div>
		<?php
		$this->createBackgroundColor($prefix);
		$this->createBackgroundImage($prefix);
		$this->createBorders($prefix);
		$this->createRoundedCorners($prefix);
		$this->createShadow($prefix);
		// $this->createTextShadow($prefix);
		?>
		<div class="ckheading"><?php echo CKText::_('CK_DIMENSIONS_LABEL'); ?></div>
		<?php
		$this->createMargins($prefix);
		$this->createDimensions($prefix);
		/*
		?>
		<!--<div class="ckheading"><?php echo CKText::_('CK_ANIMATIONS_LABEL'); ?></div>-->
		<?php 
		$this->createAnimations($prefix);*/
	}

	public function createBackgroundColor($prefix) {
	?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>backgroundcolorstart"><?php echo CKText::_('CK_BGCOLOR_LABEL'); ?></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<input type="text" id="<?php echo $prefix; ?>backgroundcolorstart" name="<?php echo $prefix; ?>backgroundcolorstart" class="cktip <?php echo $prefix; ?> <?php echo $this->colorpicker_class; ?>" title="<?php echo CKText::_('CK_BGCOLOR_DESC'); ?>"/>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<input type="text" id="<?php echo $prefix; ?>backgroundcolorend" name="<?php echo $prefix; ?>backgroundcolorend" class="cktip <?php echo $prefix; ?> <?php echo $this->colorpicker_class; ?>" title="<?php echo CKText::_('CK_BGCOLOR2_DESC'); ?>" onchange="ckCheckGradientImageConflict(this, '<?php echo $prefix; ?>backgroundimageurl')"/>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/layers.png" />
		<input type="text" id="<?php echo $prefix; ?>backgroundopacity" name="<?php echo $prefix; ?>backgroundopacity" class="cktip <?php echo $prefix; ?>" style="width:45px;" title="<?php echo CKText::_('CK_BGOPACITY_DESC'); ?>"/>
	</div>
	<?php
	}
	
	public function createBackgroundImage($prefix) {
	?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>backgroundimageurl"><?php echo CKText::_('CK_BACKGROUNDIMAGE_LABEL'); ?></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/image.png" />
		<div class="ckbutton-group">
			<input type="text" id="<?php echo $prefix; ?>backgroundimageurl" name="<?php echo $prefix; ?>backgroundimageurl" class="cktip <?php echo $prefix; ?>" title="<?php echo CKText::_('CK_BACKGROUNDIMAGE_DESC'); ?>" onchange="ckCheckGradientImageConflict(this, '<?php echo $prefix; ?>backgroundcolorend')" style="max-width: none; width: 150px;"/>
			<a class="ckbutton" onclick="ckCallImageManagerPopup('<?php echo $prefix; ?>backgroundimageurl')" href="javascript:void(0)" ><?php echo CKText::_('CK_SELECT'); ?></a>
			<a class="ckbutton" href="javascript:void(0)" onclick="$ck(this).parent().find('input').val('');"><?php echo CKText::_('CK_CLEAR'); ?></a>
		</div>
	</div>
	<div class="ckrow">
		<label></label>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/offsetx.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>backgroundimageleft" name="<?php echo $prefix; ?>backgroundimageleft" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_BACKGROUNDPOSITIONX_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/offsety.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>backgroundimagetop" name="<?php echo $prefix; ?>backgroundimagetop" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_BACKGROUNDPOSITIONY_DESC'); ?>" /></span>
		<div class="ckbutton-group">
			<input class="" type="radio" value="repeat" id="<?php echo $prefix; ?>backgroundimagerepeat" name="<?php echo $prefix; ?>backgroundimagerepeat" class="<?php echo $prefix; ?>" />
			<label class="ckbutton first" for="<?php echo $prefix; ?>backgroundimagerepeat"><img class="ckicon" src="<?php echo $this->imagespath ?>/bg_repeat.png" />
			</label><input class="<?php echo $prefix; ?>" type="radio" value="repeat-x" id="<?php echo $prefix; ?>backgroundimagerepeat-x" name="<?php echo $prefix; ?>backgroundimagerepeat" />
			<label class="ckbutton"  for="<?php echo $prefix; ?>backgroundimagerepeat-x"><img class="ckicon" src="<?php echo $this->imagespath ?>/bg_repeat-x.png" />
			</label><input class="<?php echo $prefix; ?>" type="radio" value="repeat-y" id="<?php echo $prefix; ?>backgroundimagerepeat-y" name="<?php echo $prefix; ?>backgroundimagerepeat" />
			<label class="ckbutton last"  for="<?php echo $prefix; ?>backgroundimagerepeat-y"><img class="ckicon" src="<?php echo $this->imagespath ?>/bg_repeat-y.png" />
			</label><input class="<?php echo $prefix; ?>" type="radio" value="no-repeat" id="<?php echo $prefix; ?>backgroundimagerepeatno-repeat" name="<?php echo $prefix; ?>backgroundimagerepeat" />
			<label class="ckbutton last"  for="<?php echo $prefix; ?>backgroundimagerepeatno-repeat"><img class="ckicon" src="<?php echo $this->imagespath ?>/bg_no-repeat.png" /></label>
		</div>
	</div>
	<?php
	}
	public function createRoundedCorners($prefix) {
	?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>borderradiustopleft"><?php echo CKText::_('CK_ROUNDEDCORNERS_LABEL'); ?></label>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/border_radius_tl.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>borderradiustopleft" name="<?php echo $prefix; ?>borderradiustopleft" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_ROUNDEDCORNERSTL_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/border_radius_tr.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>borderradiustopright" name="<?php echo $prefix; ?>borderradiustopright" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_ROUNDEDCORNERSTR_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/border_radius_br.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>borderradiusbottomright" name="<?php echo $prefix; ?>borderradiusbottomright" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_ROUNDEDCORNERSBR_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/border_radius_bl.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>borderradiusbottomleft" name="<?php echo $prefix; ?>borderradiusbottomleft" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_ROUNDEDCORNERSBL_DESC'); ?>" /></span>
	</div>
	<?php
	}
	public function createShadow($prefix) {
	?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>shadowcolor"><?php echo CKText::_('CK_SHADOW_LABEL'); ?></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<span><input type="text" id="<?php echo $prefix; ?>shadowcolor" name="<?php echo $prefix; ?>shadowcolor" class="<?php echo $prefix; ?> <?php echo $this->colorpicker_class; ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/shadow_blur.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>shadowblur" name="<?php echo $prefix; ?>shadowblur" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_SHADOWBLUR_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/shadow_spread.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>shadowspread" name="<?php echo $prefix; ?>shadowspread" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_SHADOWSPREAD_DESC'); ?>" /></span>
	</div>
	<div class="ckrow">
		<label></label>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/offsetx.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>shadowoffseth" name="<?php echo $prefix; ?>shadowoffseth" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_OFFSETX_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/offsety.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>shadowoffsetv" name="<?php echo $prefix; ?>shadowoffsetv" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_OFFSETY_DESC'); ?>" /></span>
		<div class="ckbutton-group">
			<input class="<?php echo $prefix; ?>" type="radio" value="0" id="<?php echo $prefix; ?>shadowinsetno" name="<?php echo $prefix; ?>shadowinset" />
			<label class="ckbutton last"  for="<?php echo $prefix; ?>shadowinsetno" style="width:auto;"><?php echo CKText::_('CK_OUT'); ?>
			</label><input class="<?php echo $prefix; ?>" type="radio" value="1" id="<?php echo $prefix; ?>shadowinsetyes" name="<?php echo $prefix; ?>shadowinset" />
			<label class="ckbutton last"  for="<?php echo $prefix; ?>shadowinsetyes" style="width:auto;"><?php echo CKText::_('CK_IN'); ?></label>
		</div>
	</div>
	<?php
	}
	public function createTextShadow($prefix) {
	?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>textshadowcolor"><?php echo CKText::_('CK_TEXTSHADOW_LABEL'); ?></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<span><input type="text" id="<?php echo $prefix; ?>textshadowcolor" name="<?php echo $prefix; ?>textshadowcolor" class="<?php echo $prefix; ?> <?php echo $this->colorpicker_class; ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/shadow_blur.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>textshadowblur" name="<?php echo $prefix; ?>textshadowblur" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_SHADOWBLUR_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/offsetx.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>textshadowoffsetx" name="<?php echo $prefix; ?>textshadowoffsetx" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_OFFSETX_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/offsety.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>textshadowoffsety" name="<?php echo $prefix; ?>textshadowoffsety" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_OFFSETY_DESC'); ?>" /></span>
	</div>
	<?php
	}

	public function createDimensions($prefix) {
	?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>width"><?php echo CKText::_('CK_WIDTH_LABEL'); ?></label>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/width.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>width" name="<?php echo $prefix; ?>width" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_WIDTH_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/height.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>height" name="<?php echo $prefix; ?>height" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_HEIGHT_DESC'); ?>" /></span>
	</div>
	<?php
	}

	public function createMargins($prefix, $margin = true, $padding = true) {
	?>
	<?php if ($margin) { ?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>margintop"><?php echo CKText::_('CK_MARGIN_LABEL'); ?></label>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/margin_top.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>margintop" name="<?php echo $prefix; ?>margintop" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_MARGINTOP_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/margin_right.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>marginright" name="<?php echo $prefix; ?>marginright" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_MARGINRIGHT_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/margin_bottom.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>marginbottom" name="<?php echo $prefix; ?>marginbottom" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_MARGINBOTTOM_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/margin_left.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>marginleft" name="<?php echo $prefix; ?>marginleft" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_MARGINLEFT_DESC'); ?>" /></span>
	</div>
	<?php } ?>
	<?php if ($padding) { ?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>paddingtop"><?php echo CKText::_('CK_PADDING_LABEL'); ?></label>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/padding_top.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>paddingtop" name="<?php echo $prefix; ?>paddingtop" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_PADDINGTOP_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/padding_right.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>paddingright" name="<?php echo $prefix; ?>paddingright" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_PADDINGRIGHT_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/padding_bottom.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>paddingbottom" name="<?php echo $prefix; ?>paddingbottom" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_PADDINGBOTTOM_DESC'); ?>" /></span>
		<span><img class="ckicon" src="<?php echo $this->imagespath ?>/padding_left.png" /></span><span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>paddingleft" name="<?php echo $prefix; ?>paddingleft" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_PADDINGLEFT_DESC'); ?>" /></span>
	</div>
	<?php } ?>
	<?php
	}

	public function createBorders($prefix) {
	?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>bordertopcolor"><?php echo CKText::_('CK_BORDERCOLOR_LABEL'); ?></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<span><input type="text" id="<?php echo $prefix; ?>bordertopcolor" name="<?php echo $prefix; ?>bordertopcolor" class="<?php echo $prefix; ?> <?php echo $this->colorpicker_class; ?>" title="<?php echo CKText::_('CK_BORDERCOLOR_DESC'); ?>"/></span>
		<span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>bordertopsize" name="<?php echo $prefix; ?>bordertopsize" class="<?php echo $prefix; ?> cktip" style="width:45px;border-top-color:#237CA4;" title="<?php echo CKText::_('CK_BORDERTOPWIDTH_DESC'); ?>" /></span>
		<span>
			<select id="<?php echo $prefix; ?>bordertopstyle" name="<?php echo $prefix; ?>bordertopstyle" class="<?php echo $prefix; ?> cktip" style="width: 70px; border-radius: 0px;">
				<option value="solid">solid</option>
				<option value="dotted">dotted</option>
				<option value="dashed">dashed</option>
			</select>
		</span>
	</div>
	<div class="ckrow">
		<label></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<span><input type="text" id="<?php echo $prefix; ?>borderrightcolor" name="<?php echo $prefix; ?>borderrightcolor" class="<?php echo $prefix; ?> <?php echo $this->colorpicker_class; ?>" title="<?php echo CKText::_('CK_BORDERCOLOR_DESC'); ?>"/></span>
		<span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>borderrightsize" name="<?php echo $prefix; ?>borderrightsize" class="<?php echo $prefix; ?> cktip" style="width:45px;border-right-color:#237CA4;" title="<?php echo CKText::_('CK_BORDERRIGHTWIDTH_DESC'); ?>" /></span>
		<span>
			<select id="<?php echo $prefix; ?>borderrightstyle" name="<?php echo $prefix; ?>borderrightstyle" class="<?php echo $prefix; ?> cktip" style="width: 70px; border-radius: 0px;">
				<option value="solid">solid</option>
				<option value="dotted">dotted</option>
				<option value="dashed">dashed</option>
			</select>
		</span>
	</div>
	<div class="ckrow">
		<label></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<span><input type="text" id="<?php echo $prefix; ?>borderbottomcolor" name="<?php echo $prefix; ?>borderbottomcolor" class="<?php echo $prefix; ?> <?php echo $this->colorpicker_class; ?>" title="<?php echo CKText::_('CK_BORDERCOLOR_DESC'); ?>"/></span>
		<span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>borderbottomsize" name="<?php echo $prefix; ?>borderbottomsize" class="<?php echo $prefix; ?> cktip" style="width:45px;border-bottom-color:#237CA4;" title="<?php echo CKText::_('CK_BORDERBOTTOMWIDTH_DESC'); ?>" /></span>
		<span>
			<select id="<?php echo $prefix; ?>borderbottomstyle" name="<?php echo $prefix; ?>borderbottomstyle" class="<?php echo $prefix; ?> cktip" style="width: 70px; border-radius: 0px;">
				<option value="solid">solid</option>
				<option value="dotted">dotted</option>
				<option value="dashed">dashed</option>
			</select>
		</span>
	</div>
	<div class="ckrow">
		<label></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<span><input type="text" id="<?php echo $prefix; ?>borderleftcolor" name="<?php echo $prefix; ?>borderleftcolor" class="<?php echo $prefix; ?> <?php echo $this->colorpicker_class; ?>" title="<?php echo CKText::_('CK_BORDERCOLOR_DESC'); ?>"/></span>
		<span style="width:45px;"><input type="text" id="<?php echo $prefix; ?>borderleftsize" name="<?php echo $prefix; ?>borderleftsize" class="<?php echo $prefix; ?> cktip" style="width:45px;border-left-color:#237CA4;" title="<?php echo CKText::_('CK_BORDERLEFTWIDTH_DESC'); ?>" /></span>
		<span>
			<select id="<?php echo $prefix; ?>borderleftstyle" name="<?php echo $prefix; ?>borderleftstyle" class="<?php echo $prefix; ?> cktip" style="width: 70px; border-radius: 0px;">
				<option value="solid">solid</option>
				<option value="dotted">dotted</option>
				<option value="dashed">dashed</option>
			</select>
		</span>
	</div>
	<?php
	}

	public function createText($prefix) { 
	?>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>textgfont"><?php echo CKText::_('CK_FONTSTYLE_LABEL'); ?></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/font_add.png" />
		<input type="text" id="<?php echo $prefix; ?>textgfont" name="<?php echo $prefix; ?>textgfont" class="<?php echo $prefix; ?> cktip gfonturl" title="<?php echo CKText::_('CK_GFONT_DESC'); ?>" style="max-width:none;width:250px;" />
		<input type="hidden" id="<?php echo $prefix; ?>textisgfont" name="<?php echo $prefix; ?>textisgfont" class="isgfont <?php echo $prefix; ?>" />
	</div>
	<div class="ckrow">
		<label></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/style.png" />
		<input type="text" id="<?php echo $prefix; ?>fontsize" name="<?php echo $prefix; ?>fontsize" class="<?php echo $prefix; ?> cktip" style="width:45px;" title="<?php echo CKText::_('CK_FONTSIZE_DESC'); ?>" />
		<img class="ckicon" src="<?php echo $this->imagespath ?>/color.png" />
		<span><?php echo CKText::_('CK_NORMAL'); ?></span>
		<input type="text" id="<?php echo $prefix; ?>color" name="<?php echo $prefix; ?>color" class="<?php echo $prefix; ?> cktip <?php echo $this->colorpicker_class; ?>" title="<?php echo CKText::_('CK_FONTCOLOR_DESC'); ?>" />
	</div>
	<div class="ckrow">
		<label for="">&nbsp;</label><img class="ckicon" src="<?php echo $this->imagespath ?>/font.png" />
		<div class="ckbutton-group">
			<input class="<?php echo $prefix; ?>" type="radio" value="left" id="<?php echo $prefix; ?>textalignleft" name="<?php echo $prefix; ?>textalign" />
			<label class="ckbutton first" for="<?php echo $prefix; ?>textalignleft"><img class="ckicon" src="<?php echo $this->imagespath ?>/text_align_left.png" />
			</label><input class="<?php echo $prefix; ?>" type="radio" value="center" id="<?php echo $prefix; ?>textaligncenter" name="<?php echo $prefix; ?>textalign" />
			<label class="ckbutton"  for="<?php echo $prefix; ?>textaligncenter"><img class="ckicon" src="<?php echo $this->imagespath ?>/text_align_center.png" />
			</label><input class="<?php echo $prefix; ?>" type="radio" value="right" id="<?php echo $prefix; ?>textalignright" name="<?php echo $prefix; ?>textalign" />
			<label class="ckbutton last"  for="<?php echo $prefix; ?>textalignright"><img class="ckicon" src="<?php echo $this->imagespath ?>/text_align_right.png" /></label>
		</div>
		<div class="ckbutton-group">
			<input class="<?php echo $prefix; ?>" type="radio" value="lowercase" id="<?php echo $prefix; ?>texttransformlowercase" name="<?php echo $prefix; ?>texttransform" />
			<label class="ckbutton first cktip" title="<?php echo CKText::_('CK_LOWERCASE'); ?>" for="<?php echo $prefix; ?>texttransformlowercase"><img class="ckicon" src="<?php echo $this->imagespath ?>/text_lowercase.png" />
			</label><input class="<?php echo $prefix; ?>" type="radio" value="uppercase" id="<?php echo $prefix; ?>texttransformuppercase" name="<?php echo $prefix; ?>texttransform" />
			<label class="ckbutton cktip" title="<?php echo CKText::_('CK_UPPERCASE'); ?>" for="<?php echo $prefix; ?>texttransformuppercase"><img class="ckicon" src="<?php echo $this->imagespath ?>/text_uppercase.png" />
			</label><input class="<?php echo $prefix; ?>" type="radio" value="capitalize" id="<?php echo $prefix; ?>texttransformcapitalize" name="<?php echo $prefix; ?>texttransform" />
			<label class="ckbutton cktip" title="<?php echo CKText::_('CK_CAPITALIZE'); ?>" for="<?php echo $prefix; ?>texttransformcapitalize"><img class="ckicon" src="<?php echo $this->imagespath ?>/text_capitalize.png" />
			</label><input class="<?php echo $prefix; ?>" type="radio" value="default" id="<?php echo $prefix; ?>texttransformdefault" name="<?php echo $prefix; ?>texttransform" />
			<label class="ckbutton cktip" title="<?php echo CKText::_('CK_DEFAULT'); ?>" for="<?php echo $prefix; ?>texttransformdefault"><img class="ckicon" src="<?php echo $this->imagespath ?>/text_default.png" />
			</label>
		</div>
	</div>
	<div class="ckrow">
		<label for="<?php echo $prefix; ?>fontweightbold"></label>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/text_bold.png" />
		<div class="ckbutton-group">
			<input class="<?php echo $prefix; ?>" type="radio" value="bold" id="<?php echo $prefix; ?>fontweightbold" name="<?php echo $prefix; ?>fontweight" />
			<label class="ckbutton first cktip" title="" for="<?php echo $prefix; ?>fontweightbold" style="width:auto;"><?php echo CKText::_('CK_BOLD'); ?>
			</label><input class="<?php echo $prefix; ?>" type="radio" value="normal" id="<?php echo $prefix; ?>fontweightnormal" name="<?php echo $prefix; ?>fontweight" />
			<label class="ckbutton cktip" title="" for="<?php echo $prefix; ?>fontweightnormal" style="width:auto;"><?php echo CKText::_('CK_NORMAL'); ?>
			</label>
		</div>
		<img class="ckicon" src="<?php echo $this->imagespath ?>/text_underline.png" />
		<div class="ckbutton-group">
			<input class="<?php echo $prefix; ?>" type="radio" value="underline" id="<?php echo $prefix; ?>fontunderlineunderline" name="<?php echo $prefix; ?>fontunderline" />
			<label class="ckbutton first cktip" title="" for="<?php echo $prefix; ?>fontunderlineunderline" style="width:auto;"><?php echo ucfirst(CKText::_('CK_UNDERLINE')); ?>
			</label><input class="<?php echo $prefix; ?>" type="radio" value="none" id="<?php echo $prefix; ?>fontunderlinenone" name="<?php echo $prefix; ?>fontunderline" />
			<label class="ckbutton cktip" title="" for="<?php echo $prefix; ?>fontunderlinenone" style="width:auto;"><?php echo CKText::_('CK_NORMAL'); ?>
			</label>
		</div>
	</div>
	<?php
	}

	public function createAnimations($prefix) {
	?>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>animdur"><?php echo CKText::_('CK_DURATION'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/hourglass.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>animdur" id="<?php echo $prefix; ?>animdur" value="1" /> [s]
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>animdelay"><?php echo CKText::_('CK_DELAY'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/hourglass.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>animdelay" id="<?php echo $prefix; ?>animdelay" value="0" /> [s]
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>animfade"><?php echo CKText::_('CK_FADE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shading.png" />
			<select class="<?php echo $prefix; ?>" type="list" name="<?php echo $prefix; ?>animfade" id="<?php echo $prefix; ?>animfade" value="" style="width: 100px;" >
				<option value="0"><?php echo CKText::_('JNO'); ?></option>
				<option value="1"><?php echo CKText::_('JYES'); ?></option>
			</select>
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>animmove"><?php echo CKText::_('CK_MOVE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_square_go.png" />
			<select class="<?php echo $prefix; ?>" type="list" name="<?php echo $prefix; ?>animmove" id="<?php echo $prefix; ?>animmove" value="" style="width: 100px;" >
				<option value="0"><?php echo CKText::_('JNO'); ?></option>
				<option value="1"><?php echo CKText::_('JYES'); ?></option>
			</select>
			<select class="<?php echo $prefix; ?> cktip" title="<?php echo CKText::_('CK_DIRECTION'); ?>" type="list" name="<?php echo $prefix; ?>animmovedir" id="<?php echo $prefix; ?>animmovedir" value="" style="width: 100px;" >
				<option value="ltrck"><?php echo CKText::_('CK_LEFT_TO_RIGHT'); ?></option>
				<option value="rtlck"><?php echo CKText::_('CK_RIGHT_TO_LEFT'); ?></option>
				<option value="ttbck"><?php echo CKText::_('CK_TOP_TO_BOTTOM'); ?></option>
				<option value="bttck"><?php echo CKText::_('CK_BOTTOM_TO_TOP'); ?></option>
			</select>
			<input class="<?php echo $prefix; ?> cktip" title="<?php echo CKText::_('CK_DISTANCE'); ?>" type="text" name="<?php echo $prefix; ?>animmovedist" id="<?php echo $prefix; ?>animmovedist" value="40" /> [px]
		</div>
		
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>animrot"><?php echo CKText::_('CK_ROTATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_rotate_clockwise.png" />
			<select class="<?php echo $prefix; ?>" type="list" name="<?php echo $prefix; ?>animrot" id="<?php echo $prefix; ?>animrot" value="" style="width: 100px;" >
				<option value="0"><?php echo CKText::_('JNO'); ?></option>
				<option value="1"><?php echo CKText::_('JYES'); ?></option>
			</select>
			<select class="<?php echo $prefix; ?>" type="list" name="<?php echo $prefix; ?>animrotrad" id="<?php echo $prefix; ?>animrotrad" value="" style="width: 100px;" >
				<option value="45">45°</option>
				<option value="90">90°</option>
				<option value="180">180°</option>
				<option value="270">270°</option>
				<option value="360">360°</option>
			</select>
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>animscale"><?php echo CKText::_('CK_SCALE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_handles.png" />
			<select class="<?php echo $prefix; ?>" type="list" name="<?php echo $prefix; ?>animscale" id="<?php echo $prefix; ?>animscale" value="" style="width:100px;" >
				<option value="0"><?php echo CKText::_('JNO'); ?></option>
				<option value="1"><?php echo CKText::_('JYES'); ?></option>
			</select>
		</div>
		<div class="ckrow">
			<a class="ckbutton" href="javascript:void(0)" onclick="ckPlayAnimationPreview('<?php echo $prefix; ?>')"><i class="icon icon-play"></i><?php echo CKText::_('CK_PLAY_ANIMATION'); ?></a>
		</div>
	<?php
	}

	public function createEffects($prefix) {
	?>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxdur"><?php echo CKText::_('CK_DURATION'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/hourglass.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>fxdur" id="<?php echo $prefix; ?>fxdur" value="1" /> [s]
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxdelay"><?php echo CKText::_('CK_DELAY'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/hourglass.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>fxdelay" id="<?php echo $prefix; ?>fxdelay" value="0" /> [s]
		</div>
		<div class="ckheading"><?php echo CKText::_('CK_OPACITY'); ?></div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxopacity"><?php echo CKText::_('CK_NORMAL_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shading.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>fxopacity" id="<?php echo $prefix; ?>fxopacity" value="" >
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxopacity"><?php echo CKText::_('CK_HOVER_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shading.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>hoverfxopacity" id="<?php echo $prefix; ?>hoverfxopacity" value="" >
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxopacity"><?php echo CKText::_('CK_ACTIVE_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shading.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>activefxopacity" id="<?php echo $prefix; ?>activefxopacity" value="" >
		</div>
		<div class="ckheading"><?php echo CKText::_('CK_MOVE'); ?></div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxmove"><?php echo CKText::_('CK_NORMAL_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_square_go.png" />
			<select class="<?php echo $prefix; ?> cktip" title="<?php echo CKText::_('CK_DIRECTION'); ?>" type="list" name="<?php echo $prefix; ?>fxmovedir" id="<?php echo $prefix; ?>fxmovedir" value="" style="width: 100px;" >
				<option value="ltrck"><?php echo CKText::_('CK_LEFT_TO_RIGHT'); ?></option>
				<option value="rtlck"><?php echo CKText::_('CK_RIGHT_TO_LEFT'); ?></option>
				<option value="ttbck"><?php echo CKText::_('CK_TOP_TO_BOTTOM'); ?></option>
				<option value="bttck"><?php echo CKText::_('CK_BOTTOM_TO_TOP'); ?></option>
			</select>
			<input class="<?php echo $prefix; ?> cktip" title="<?php echo CKText::_('CK_DISTANCE'); ?>" type="text" name="<?php echo $prefix; ?>fxmovedist" id="<?php echo $prefix; ?>fxmovedist" value="" /> [px]
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>hoverfxmove"><?php echo CKText::_('CK_HOVER_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_square_go.png" />
			<select class="<?php echo $prefix; ?>hover cktip" title="<?php echo CKText::_('CK_DIRECTION'); ?>" type="list" name="<?php echo $prefix; ?>hoverfxmovedir" id="<?php echo $prefix; ?>hoverfxmovedir" value="" style="width: 100px;" >
				<option value="ltrck"><?php echo CKText::_('CK_LEFT_TO_RIGHT'); ?></option>
				<option value="rtlck"><?php echo CKText::_('CK_RIGHT_TO_LEFT'); ?></option>
				<option value="ttbck"><?php echo CKText::_('CK_TOP_TO_BOTTOM'); ?></option>
				<option value="bttck"><?php echo CKText::_('CK_BOTTOM_TO_TOP'); ?></option>
			</select>
			<input class="<?php echo $prefix; ?>hover cktip" title="<?php echo CKText::_('CK_DISTANCE'); ?>" type="text" name="<?php echo $prefix; ?>hoverfxmovedist" id="<?php echo $prefix; ?>hoverfxmovedist" value="" /> [px]
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>activefxmove"><?php echo CKText::_('CK_ACTIVE_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_square_go.png" />
			<select class="<?php echo $prefix; ?>active cktip" title="<?php echo CKText::_('CK_DIRECTION'); ?>" type="list" name="<?php echo $prefix; ?>activefxmovedir" id="<?php echo $prefix; ?>activefxmovedir" value="" style="width: 100px;" >
				<option value="ltrck"><?php echo CKText::_('CK_LEFT_TO_RIGHT'); ?></option>
				<option value="rtlck"><?php echo CKText::_('CK_RIGHT_TO_LEFT'); ?></option>
				<option value="ttbck"><?php echo CKText::_('CK_TOP_TO_BOTTOM'); ?></option>
				<option value="bttck"><?php echo CKText::_('CK_BOTTOM_TO_TOP'); ?></option>
			</select>
			<input class="<?php echo $prefix; ?>active cktip" title="<?php echo CKText::_('CK_DISTANCE'); ?>" type="text" name="<?php echo $prefix; ?>activefxmovedist" id="<?php echo $prefix; ?>activefxmovedist" value="" /> [px]
		</div>
		<div class="ckheading"><?php echo CKText::_('CK_ROTATE'); ?></div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxrot"><?php echo CKText::_('CK_NORMAL_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_rotate_clockwise.png" />
			<select class="<?php echo $prefix; ?>" type="list" name="<?php echo $prefix; ?>fxrot" id="<?php echo $prefix; ?>fxrot" value="" style="width: 100px;" >
				<option value="0"><?php echo CKText::_('JNO'); ?></option>
				<option value="1"><?php echo CKText::_('JYES'); ?></option>
			</select>
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>fxrotrad" id="<?php echo $prefix; ?>fxrotrad" value="" /> °
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>hoverfxrot"><?php echo CKText::_('CK_HOVER_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_rotate_clockwise.png" />
			<select class="<?php echo $prefix; ?>hover" type="list" name="<?php echo $prefix; ?>hoverfxrot" id="<?php echo $prefix; ?>hoverfxrot" value="" style="width: 100px;" >
				<option value="0"><?php echo CKText::_('JNO'); ?></option>
				<option value="1"><?php echo CKText::_('JYES'); ?></option>
			</select>
			<input class="<?php echo $prefix; ?>hover" type="text" name="<?php echo $prefix; ?>hoverfxrotrad" id="<?php echo $prefix; ?>hoverfxrotrad" value="" /> °
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>activefxrot"><?php echo CKText::_('CK_ACTIVE_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_rotate_clockwise.png" />
			<select class="<?php echo $prefix; ?>active" type="list" name="<?php echo $prefix; ?>activefxrot" id="<?php echo $prefix; ?>activefxrot" value="" style="width: 100px;" >
				<option value="0"><?php echo CKText::_('JNO'); ?></option>
				<option value="1"><?php echo CKText::_('JYES'); ?></option>
			</select>
			<input class="<?php echo $prefix; ?>active" type="text" name="<?php echo $prefix; ?>activefxrotrad" id="<?php echo $prefix; ?>activefxrotrad" value="" /> °
		</div>
		<div class="ckheading"><?php echo CKText::_('CK_SCALE'); ?></div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxscale"><?php echo CKText::_('CK_NORMAL_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_handles.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>fxscale" id="<?php echo $prefix; ?>fxscale" value="" />
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>hoverfxscale"><?php echo CKText::_('CK_HOVER_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_handles.png" />
			<input class="<?php echo $prefix; ?>hover" type="text" name="<?php echo $prefix; ?>hoverfxscale" id="<?php echo $prefix; ?>hoverfxscale" value="" />
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>activefxscale"><?php echo CKText::_('CK_ACTIVE_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/shape_handles.png" />
			<input class="<?php echo $prefix; ?>active" type="text" name="<?php echo $prefix; ?>activefxscale" id="<?php echo $prefix; ?>activefxscale" value="" />
		</div>
		<div class="ckheading"><?php echo CKText::_('CK_BLUR'); ?></div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxblur"><?php echo CKText::_('CK_NORMAL_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/wrap-behind.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>fxblur" id="<?php echo $prefix; ?>fxblur" value="" />
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>hoverfxblur"><?php echo CKText::_('CK_HOVER_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/wrap-behind.png" />
			<input class="<?php echo $prefix; ?>hover" type="text" name="<?php echo $prefix; ?>hoverfxblur" id="<?php echo $prefix; ?>hoverfxblur" value="" />
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>activefxblur"><?php echo CKText::_('CK_ACTIVE_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/wrap-behind.png" />
			<input class="<?php echo $prefix; ?>active" type="text" name="<?php echo $prefix; ?>activefxblur" id="<?php echo $prefix; ?>activefxblur" value="" />
		</div>
		<div class="ckheading"><?php echo CKText::_('CK_BRIGHTNESS'); ?></div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxbrightness"><?php echo CKText::_('CK_NORMAL_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/lightbulb.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>fxbrightness" id="<?php echo $prefix; ?>fxbrightness" value="" />
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>hoverfxbrightness"><?php echo CKText::_('CK_HOVER_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/lightbulb.png" />
			<input class="<?php echo $prefix; ?>hover" type="text" name="<?php echo $prefix; ?>hoverfxbrightness" id="<?php echo $prefix; ?>hoverfxbrightness" value="" />
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>activefxbrightness"><?php echo CKText::_('CK_ACTIVE_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/lightbulb.png" />
			<input class="<?php echo $prefix; ?>active" type="text" name="<?php echo $prefix; ?>activefxbrightness" id="<?php echo $prefix; ?>activefxbrightness" value="" />
		</div>
		<div class="ckheading"><?php echo CKText::_('CK_GRAYSCALE'); ?></div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>fxgrayscale"><?php echo CKText::_('CK_NORMAL_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/lightbulb_off.png" />
			<input class="<?php echo $prefix; ?>" type="text" name="<?php echo $prefix; ?>fxgrayscale" id="<?php echo $prefix; ?>fxgrayscale" value="" />
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>hoverfxgrayscale"><?php echo CKText::_('CK_HOVER_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/lightbulb_off.png" />
			<input class="<?php echo $prefix; ?>hover" type="text" name="<?php echo $prefix; ?>hoverfxgrayscale" id="<?php echo $prefix; ?>hoverfxgrayscale" value="" />
		</div>
		<div class="ckrow">
			<label for="<?php echo $prefix; ?>activefxgrayscale"><?php echo CKText::_('CK_ACTIVE_STATE'); ?></label>
			<img class="ckicon" src="<?php echo $this->imagespath ?>/lightbulb_off.png" />
			<input class="<?php echo $prefix; ?>active" type="text" name="<?php echo $prefix; ?>activefxgrayscale" id="<?php echo $prefix; ?>activefxgrayscale" value="" />
		</div>
	<?php
	}
}
PKv�!]0����
ckpath.phpnu&1i�<?php
namespace Slideshowck;

defined('_JEXEC') or die;

jimport('joomla.filesystem.file');

class CKPath extends \Joomla\CMS\Filesystem\Path {
	
}
PKv�!]�nnckinput.phpnu&1i�<?php
namespace Slideshowck;

defined('_JEXEC') or die;

class CKInput extends  \Joomla\CMS\Input\Input {
	
}
PKv�!]·D���
ckview.phpnu&1i�<?php
Namespace Slideshowck;

defined('CK_LOADED') or die;

class CKView {

	protected $name;

	protected $model;

	protected $input;

	protected $items;

	protected $item;

	protected $state;

	protected $pagination;

	public function __construct() {
		// check if the user has the rights to access this page
		if (!CKFof::userCan('edit')) {
			CKFof::_die();
		}
		$this->input = CKFof::getInput();
	}

	public function display($tpl = 'default') {
		if ($this->model) {
			$this->state = $this->model->getState();
			$this->pagination = $this->model->getPagination();
		}

		require_once SLIDESHOWCK_PATH . '/views/' . strtolower($this->name) . '/tmpl/' . $tpl . '.php';
	}

	public function setName($name) {
		$this->name = $name;
	}

	public function setModel($model) {
		$this->model = $model;
	}

	public function get($func, $params = array()) {
		$model = $this->getModel();
		$funcName = 'get' . ucfirst($func);
		return $model->$funcName($params);
	}

	public function getModel() {
		if (empty($this->model)) {
			require_once(SLIDESHOWCK_PATH . '/models/' . strtolower($this->name) . '.php');
			$className = '\Slideshowck\CKModel' . ucfirst($this->name);
			$this->model = new $className;
		}
		return $this->model;
	}
}PKv�!]{�Bmmckcontroller.phpnu&1i�<?php
Namespace Slideshowck;

defined('CK_LOADED') or die;

// class CKController extends \Joomla\CMS\MVC\Controller\BaseController {
class CKController {

	protected $input;

	protected $model;

	protected $name;

	protected $prefix;

	protected $view;

	protected static $instance;

	protected static $views;

	function __construct() {
		$this->input = CKFof::getInput();
	}

	static function getInstance($prefix) {

		if (is_object(self::$instance))
		{
			return self::$instance;
		}
		$basePath = SLIDESHOWCK_PATH;
		// Check for a controller.task command.
		$input = CKFof::getInput();

		$cmd = $input->get('task', '', 'cmd');
		if (strpos($cmd, '.') !== false)
		{
			// Explode the controller.task command.
			list ($name, $task) = explode('.', $cmd);

			// Define the controller filename and path.
			$file = self::createFileName('controller', array('name' => $name));
			$path = $basePath . '/controllers/' . $file;
			$backuppath = $basePath . '/controller/' . $file;
			// Reset the task without the controller context.
			$input->set('task', $task);
		}
		else
		{
			// Base controller.
			$name = null;

			// Define the controller filename and path.
			$file       = self::createFileName('controller', array('name' => 'controller'));
			$path       = $basePath . '/' . $file;
		}

		// Get the controller class name.
		$class = ucfirst((string) $prefix) . 'Controller' . ucfirst((string) $name);

		// Include the class if not present.
		if (!class_exists($class))
		{
			// If the controller file path exists, include it.
			if (file_exists($path))
			{
				require_once $path;
			}
			else
			{
				throw new \InvalidArgumentException(\Joomla\CMS\Language\Text::sprintf('ERROR_INVALID_CONTROLLER', $type, $format));
			}
		}

		// Instantiate the class.
		if (!class_exists($class))
		{
			throw new \InvalidArgumentException(\Joomla\CMS\Language\Text::sprintf('ERROR_INVALID_CONTROLLER_CLASS', $class));
		}

		// Instantiate the class, store it to the static container, and return it
		return self::$instance = new $class();
	}

	protected static function createFileName($type, $parts = array())
	{
		$filename = '';

		switch ($type)
		{
			case 'controller':

				$filename = strtolower($parts['name'] . '.php');
				break;

			case 'view':

				$filename = strtolower($parts['name'] . '/view.html.php');
				break;
		}

		return $filename;
	}

	// public function getModel($base = '\Slideshowck\CKModel') {
		// if (empty($this->model)) {
			// $name = $this->getName();
			// require_once(SLIDESHOWCK_PATH . '/helpers/ckmodel.php');
			// require_once(SLIDESHOWCK_PATH . '/models/' . strtolower($name) . '.php');
			// $className = ucfirst($base) . ucfirst($name);
			// $this->model = new $className;
		// }
		// return $this->model;
	// }

	public function getView($name = '', $type = 'html', $prefix = '')
	{
		// @note We use self so we only access stuff in this class rather than in all classes.
		if (!isset(self::$views))
		{
			self::$views = array();
		}

		if (empty($name))
		{
			$name = $this->getName();
		}

		if (empty($prefix))
		{
			$prefix = $this->getPrefix() . 'View';
		}

		if (empty(self::$views[$name][$type][$prefix]))
		{
			if ($view = $this->createView($name, $prefix))
			{
				self::$views[$name][$type][$prefix] = & $view;
			}
			else
			{
				throw new \Exception(\Joomla\CMS\Language\Text::sprintf('ERROR_VIEW_NOT_FOUND', $name, $type, $prefix), 404);
			}
		}

		return self::$views[$name][$type][$prefix];
	}

	protected function createView($name, $prefix = '')
	{
		// Clean the view name
		$viewName = preg_replace('/[^A-Z0-9_]/i', '', $name);
		$classPrefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix);

		// Build the view class name
		$viewClass = $classPrefix . ucfirst($viewName);

		if (!class_exists($viewClass))
		{
			$path = SLIDESHOWCK_PATH . '/views/' . $this->createFileName('view', array('name' => $viewName));

			if (!$path)
			{
				return null;
			}

			require_once $path;

			if (!class_exists($viewClass))
			{
				throw new \Exception(\Joomla\CMS\Language\Text::_('ERROR_VIEW_CLASS_NOT_FOUND : ' . $viewClass . ' - ' . $path), 500);
			}
		}

		return new $viewClass();
	}

	public function display() {
		$viewName = $this->input->get('view', $this->getName());
		$viewLayout = $this->input->get('layout', 'default', 'string');

		$view = $this->getView($viewName, 'html', '');
		$view->setName($viewName);

		// Get/Create the model
		if ($model = $this->getModel($viewName))
		{
			// Push the model into the view (as default)
			$view->setModel($model);
		}


		$view->display();

		return $this;
	}

	public function getModel($name = '', $prefix = '', $config = array())
	{
		if (empty($name))
		{
			$name = ucfirst($this->getName());
		}

		if (empty($prefix))
		{
			$prefix = ucfirst($this->getPrefix());
		}

		$model = $this->createModel($name, $prefix, $config);

		return $model;
	}

	protected function createModel($name, $prefix = '', $config = array())
	{
		// Clean the model name
		$modelName = preg_replace('/[^A-Z0-9_]/i', '', $name);
		$classPrefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix);

		return CKModel::getInstance($modelName, $classPrefix, $config);
	}


	public function execute($task) {
		if (! $task) $task = 'display';
		if (is_callable(array($this, $task))) {
			return $this->$task();
		}
		else
		{
			throw new \Exception(\Joomla\CMS\Language\Text::sprintf('ERROR_TASK_NOT_FOUND', $task), 404);
		}

		return;
	}

	public function setName($name) {
		$this->name = $name;
	}

	public function getName()
	{
		if (empty($this->name))
		{
			$r = null;

			if (!preg_match('/Controller(.*)/i', get_class($this), $r))
			{
				throw new \Exception(\CKText::_('Error : Can not get controller name'), 500);
			}

			$this->name = strtolower($r[1]);
		}

		return $this->name;
	}

	public function getPrefix()
	{
		if (empty($this->prefix))
		{
			$r = null;

			if (!preg_match('/(.*)Controller/i', get_class($this), $r))
			{
				throw new \Exception(\CKText::_('Error : Can not get controller name'), 500);
			}

			$this->prefix = strtolower($r[1]);
		}

		return $this->prefix;
	}

	public function add() {
		return $this->edit(0);
	}

	public function edit($id = null, $appendUrl = '') {
		$editIds = $this->input->get('cid', $id, 'array');
		if (! empty($editIds)) {
			$editId = (int) $editIds[0];
		} else {
			$editId = (int) $this->input->get('id', $id, 'int');
		}

		// Redirect to the edit screen.
		CKFof::redirect(SLIDESHOWCK_ADMIN_URL . '&view=' . $this->getName() . '&layout=edit&id=' . $editId . $appendUrl);
	}

	public function copy() {
		$editIds = $this->input->get('cid', null, 'array');
		if (count($editIds)) {
			$id = (int) $editIds[0];
		} else {
			$id = (int) $this->input->get('id', null, 'int');
		}
		$model = $this->getModel($this->getName());

		if ($model->copy($id)) {
			CKFof::enqueueMessage('Item copied with success');
		} else {
			CKFof::enqueueMessage('Error : Item not copied', 'error');
		}

		// Redirect to the edit screen.
		CKFof::redirect(SLIDESHOWCK_ADMIN_URL);
	}

	public function delete() {
		$editIds = $this->input->get('cid', null, 'array');
		if (count($editIds)) {
			$id = (int) $editIds[0];
		} else {
			$id = (int) $this->input->get('id', null, 'int');
		}
		$model = $this->getModel($this->getName());
		if ($model->delete($id)) {
			CKFof::enqueueMessage('Item deleted with success');
		} else {
			CKFof::enqueueMessage('Error : Item not deleted', 'error');
		}

		// Redirect to the edit screen.
		CKFof::redirect(SLIDESHOWCK_ADMIN_URL);
	}
}
PKv�!];�a(4(4	ckfof.phpnu&1i�<?php
namespace Slideshowck;

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Slideshowck\CKInput;
use Slideshowck\CKText;

/**
 * CK Development Framework layer
 */
class CKFof {

	static $keepMessages = false;

	static protected $environment = 'com_slideshowck'; // for joomla only

	static protected $input;

	public static function loadHelper($name) {
		require_once(SLIDESHOWCK_PATH . '/helpers/ck' . $name . '.php');
	}

	public static function getInput() {
		if (empty(self::$input)) {
			self::$input = Factory::getApplication()->input;
		}
		return self::$input;
	}

	public static function userCan($task, $environment = false) {
		$environment = $environment ? $environment : self::$environment;
		$user = CKFof::getUser();
		switch ($task) {
			case 'edit' :
			default :
				return $user->authorise('core.edit', $environment);
			break;
			case 'create' :
				return $user->authorise('core.create', $environment);
			break;
			case 'manage' :
				return $user->authorise('core.manage', $environment);
			break;
			case 'admin' :
				return $user->authorise('core.admin', $environment);
			case 'delete' :
				return $user->authorise('core.delete', $environment);
			break;
		}
	}

	public static function getUser($id = 0) {
		if ($id) {
			return $user = Factory::getUser($id);
		}
		return $user = Factory::getUser();
	}

	public static function isAdmin() {
		return Factory::getApplication()->isClient('administrator') ;
	}

	public static function isSite() {
		return Factory::getApplication()->isClient('site') ;
	}

	public static function _die($msg = '') {
		$msg = $msg ? $msg : CKText::_('JERROR_ALERTNOAUTHOR');
		jexit($msg);
	}

	public static function getCurrentUri() {
//		$uri = \Joomla\CMS\Factory::getURI();
		$uri = \Joomla\CMS\Uri\Uri::getInstance();
		return $uri->toString();
	}

	public static function redirect($url = '', $msg = '', $type = '') {
		if (! $url) {
			$url = self::getCurrentUri();
		}
		if ($msg) {
			self::enqueueMessage($msg, $type);
		}
		Factory::getApplication()->redirect($url);
		// If the headers have been sent, then we cannot send an additional location header
		// so we will output a javascript redirect statement.
		/*if (headers_sent())
		{
			self::$keepMessages = true;
			echo "<script>document.location.href='" . str_replace("'", '&apos;', $url) . "';</script>\n";
		}
		else
		{
			self::$keepMessages = true;
			// All other browsers, use the more efficient HTTP header method
			header('HTTP/1.1 303 See other');
			header('Location: ' . $url);
			header('Content-Type: text/html; charset=UTF-8');
		}*/
	}

	/**
	 * 
	 * @param type $msg
	 * @param type $type
    'message' (ou vide) - vert
    'notice' - bleu
    'warning' - jaune
    'error' - rouge
	 */
	public static function enqueueMessage($msg, $type = 'message') {
		// add the information message
		Factory::getApplication()->enqueueMessage($msg, $type);
	}

	public static function displayMessages() {
		// manage the information messages
		// not needed in joomla
	}

	public static function getToken($name = '') {
		return \Joomla\CMS\Factory::getSession()->getFormToken() . '=1';
	}

	public static function renderToken($name = '') {
		echo \Joomla\CMS\HTML\HTMLHelper::_('form.token');
	}

	public static function checkToken($token = '') {
		if (! \Joomla\CMS\Session\Session::checkToken()) {
			$msg = CKText::_('Invalid token');
			jexit($msg);
		}
	}

	public static function checkAjaxToken($json = true) {
		// check the token for security
		if (! \Joomla\CMS\Session\Session::checkToken('get')) {
			$msg = CKText::_('JINVALID_TOKEN');
			if ($json === false) {
				jexit($msg);
			}
			echo '{"result": "0", "message": "' . $msg . '"}';
			exit;
		}
		return true;
	}

	public static function getDbo() {
		return Factory::getDbo();
	}

	public static function dbQuote($name) {
		$db = self::getDbo();
		return $db->quoteName($name);
	}

	public static function dbLoadObjectList($query, $key = '') {
		$db = self::getDbo();
		// $query = $db->getQuery(true);
		$db->setQuery($query);
		$results = $db->loadObjectList($key);

		return $results;
	}

	public static function dbLoadObject($query) {
		$db = self::getDbo();
		// $query = $db->getQuery(true);
		$db->setQuery($query);
		$results = $db->loadObject();

		return $results;
	}

	public static function dbLoadResult($query) {
		$db = self::getDbo();
		// $query = $db->getQuery(true);
		$db->setQuery($query);
		$result = $db->loadResult();

		return $result;
	}

	public static function dbExecute($query) {
		$db = self::getDbo();
		$db->setQuery($query);
		$result = $db->execute();

		return $result;
	}

	public static function dbLoadColumn($tableName, $column) {
		$db = self::getDbo();
		$query = $db->getQuery(true);
		$query->select($column);
		$query->from($tableName);

		$db->setQuery($query);
		$result = $db->loadColumn();

		return $result;
	}

	public static function dbCheckTableExists($tableName) {
		$db = self::getDbo();
		$tablesList = $db->getTableList();

		$tableName = str_replace('#__', $db->getPrefix(), $tableName);
		$tableExists = in_array($tableName, $tablesList);
		return $tableExists;
	}

	public static function dbLoadTable($tableName) {
		$db = self::getDbo();
		$tableName = self::getTableName($tableName);
		$query = "DESCRIBE  " . $tableName;
		$db->setQuery($query);
		$columns = $db->loadObjectList();

		$table = new \stdClass();
		foreach ($columns as $col) {
			$table->{$col->Field} = '';
		}

		return $table;
	}

	public static function dbLoad($tableName, $id) {
		// if no existing row, then load empty table
		if ($id == 0) return self::dbLoadTable($tableName);

		$db = self::getDbo();
		$query = "SELECT * FROM " . $tableName . " WHERE id = " . (int)$id;
		$db->setQuery($query);
		$result = $db->loadAssoc();

		if (! $result) return self::dbLoadTable($tableName);

		$result = self::convertArrayToObject($result);

		return $result;
	}

	public static function dbBindData($table, $data) {
		if (is_object($table)) $table = self::convertObjectToArray($table);
		if (is_object($data)) $data = self::convertObjectToArray($data);

		foreach ($table as $col => $val) {
			if (isset($data[$col])) $table[$col] = $data[$col];
		}

		return $table;
	}

	public static function getTableName($tableName) {
		return $tableName;
	}

	public static function getTableStructure($tableName) {
		$db = self::getDbo();
		$query = "SHOW COLUMNS FROM " . $tableName;
		$db->setQuery($query);

		return $db->loadObjectList('Field');
	}

	public static function dbStore($tableName, $data, $format = array()) {
		$db = self::getDbo();
		if (is_object($data)) $data = self::convertObjectToArray($data);

		// Create a new query object.
		$query = $db->getQuery(true);
		$columsData = self::getTableStructure($tableName);

		if ((int)$data['id'] === 0) {
			$columns = array();
			$values = array();
			$fields = self::dbLoadTable($tableName);

																			   

			foreach($fields as $key => $val) {
				$columns[] = $key;
				if (isset($data[$key]) && !empty($data[$key])) {
					$values[] = is_numeric($data[$key]) ? $data[$key] : $db->quote($data[$key]);
				} else {
					if (strpos($columsData[$key]->Type, 'int') === 0 || strpos($columsData[$key]->Type, 'tinyint') === 0) {
						$values[] = '0';
					} else if (strpos($columsData[$key]->Type, 'date') === 0) {
						$values[] = $db->quote('0000-00-00 00:00:00');
					} else {
						$values[] = $db->quote('');
					}
				}
			}

			// Prepare the insert query.
			$query
				->insert($db->quoteName($tableName))
				->columns($db->quoteName($columns))
				->values(implode(',', $values));

			// Set the query using our newly populated query object and execute it.
			$db->setQuery($query);
			if ($db->execute()) {
				$id = $db->insertid();
			} else {
				return false;
			}
		} else {
			// Fields to update.
			$fields = self::dbLoadTable($tableName);
			$fieldsToInsert = array();
			foreach($fields as $key => $val) {
				if (strpos($columsData[$key]->Type, 'date') === 0 && empty($data[$key])) {
					continue;
				}
				if (isset($data[$key])) {
					$value = is_numeric($data[$key]) ? (int)$data[$key] : $db->quote($data[$key]);
				} else {
					continue;
				}
				$fieldsToInsert[] = $db->quoteName($key) . ' = ' . $value;
			}

			// Conditions for which records should be updated.
			$conditions = array(
				$db->quoteName('id') . ' = ' . $data['id']
			);

			$query->update($db->quoteName($tableName))->set($fieldsToInsert)->where($conditions);

			// Set the query using our newly populated query object and execute it.
			$db->setQuery($query);
			if ($db->execute()) {
				$id = $data['id'];
			} else {
				return false;
			}
		}

		return $id;
	}

	public static function dbUpdate($tableName, $id, $fields) {
		// Create a new query object.
		$db = self::getDbo();
		$query = $db->getQuery(true);

		// Conditions for which records should be updated.
		$conditions = array(
			$db->quoteName('id') . ' = ' . $id
		);

		$fieldsToInsert = array();
		foreach ($fields as $key => $value) {
			$fieldsToInsert[] = $db->quoteName($key) . ' = ' . $value;
		}

		$query->update($db->quoteName($tableName))->set($fieldsToInsert)->where($conditions);

		// Set the query using our newly populated query object and execute it.
		$db->setQuery($query);
		if ($db->execute()) {
			$id = $data['id'];
		} else {
			return false;
		}
	}

	public static function dbDelete($tableName, $id) {
		$db = CKFof::getDbo();

		$query = $db->getQuery(true);

		$conditions = array(
			$db->quoteName('id') . ' = ' . (int) $id
//			, $db->quoteName('profile_key') . ' = ' . $db->quote('custom.%')
		);

		$query->delete($db->quoteName($tableName));
		$query->where($conditions);

		$db->setQuery($query);

		$result = $db->execute();

		return $result;
	}

	public static function convertObjectToArray($data) {
		return (array) $data;
	}

	public static function convertArrayToObject(array $array, $class = 'stdClass', $recursive = true)
	{
		$obj = new $class;

		foreach ($array as $k => $v)
		{
			if ($recursive && is_array($v))
			{
				$obj->$k = static::convertArrayToObject($v, $class);
			}
			else
			{
				$obj->$k = $v;
			}
		}

		return $obj;
	}

	public static function dump($anything){
			echo "<pre>";
				var_dump($anything);
			echo "</pre>";
	}

	public static function print_r($anything){
		echo "<pre>";
				print_r($anything);
			echo "</pre>";
	}

	public static function addToolbarTitle($title, $image = '') {
		\Joomla\CMS\Toolbar\ToolbarHelper::title($title, $image);
	}

	private static function getToolbar() {
		// Get the toolbar object instance
		$bar = \Joomla\CMS\Toolbar\Toolbar::getInstance('toolbar');
		return $bar;
	}

	public static function addToolbarButton($name, $html, $id) {
		$bar = self::getToolbar();
		$bar->appendButton($name, $html, $id);
	}

	public static function addToolbarPreferences() {
		$bar = self::getToolbar();
		// add the options of the component
		if (self::userCan('admin')) {
			\Joomla\CMS\Toolbar\ToolbarHelper::preferences(self::$environment);
		}
	}

	private static function getFileName($file) {
		$f = explode('/', $file);
		$fileName = end($f);
		$f = explode('.', $fileName);
		$ext = end($f);
		$fileName = str_replace('.' . $ext, '', $fileName);

		return $fileName;
	}

	public static function addScriptDeclaration($js) {
		$doc = Factory::getDocument();
		$doc->addScriptDeclaration($js);
	}

	public static function addScriptDeclarationInline($js) {
		echo '<script>' . $js . '</script>';
	}

	public static function addScript($file) {
		$doc = Factory::getDocument();
		$doc->addScript($file);
	}

	public static function addScriptInline($file) {
		echo '<script src="' . $file . '"></script>';
	}

	public static function addStyleDeclaration($css) {
		$doc = Factory::getDocument();
		$doc->addStyleDeclaration($css);
	}

	public static function addStyleDeclarationInline($css) {
		echo '<style>' . $css . '</style>';
	}

	public static function addStylesheet($file) {
		$doc = Factory::getDocument();
		$doc->addStylesheet($file);
	}

	public static function addStylesheetInline($file) {
		echo '<link href="' . $file . '"" rel="stylesheet" />';
	}

	public static function error($msg) {
		throw new \Exception($msg);
	}

	public static function triggerEvent($name, $e = array()) {
		if (version_compare(JVERSION,'4') < 1) {
			$dispatcher = \JEventDispatcher::getInstance();
			return $dispatcher->trigger($name, $e);
		} else {
			return Factory::getApplication()->triggerEvent($name, $e);
		}
	}

	public static function importPlugin($group) {
		if (version_compare(JVERSION,'4') < 1) {
			\Joomla\CMS\Plugin\PluginHelper::importPlugin($group);
		} else {
			PluginHelper::importPlugin($group);
		}
	}

	public static function cleanCache($group = '') {
		$conf = \Joomla\CMS\Factory::getConfig();

		$options = [
			'defaultgroup' => '',
			'storage'      => $conf->get('cache_handler', ''),
			'caching'      => true,
			'cachebase'    => $conf->get('cache_path', JPATH_SITE . '/cache'),
		];

		$cache = \Joomla\CMS\Cache\Cache::getInstance('callback', $options);

		foreach ($cache->getAll() as $group)
		{
			if ($group && $group->group == $group);
				$cache->clean($group->group);
		}
	}

	public static function getModel($modelName, $classPrefix = 'Slideshowck') {
			return CKModel::getInstance($modelName, $classPrefix);
	}
}
PKv�!]��h���defines.js.phpnu&1i�<?php
/**
 * @copyright	Copyright (C) 2019. All rights reserved.
 * @license		GNU General Public License version 2 or later; see LICENSE.txt
 * @author		Cedric Keiflin - https://www.template-creator.com - https://www.joomlack.fr
 */

// No direct access
defined('_JEXEC') or die;
?>
<script>
	var SLIDESHOWCK = {
		TOKEN : '<?php echo \Joomla\CMS\Factory::getSession()->getFormToken() ?>=1'
		, URIBASE : '<?php echo \Joomla\CMS\Uri\Uri::base(true) ?>'
		, URIBASEABS : '<?php echo \Joomla\CMS\Uri\Uri::base() ?>'
		, URIROOT : '<?php echo \Joomla\CMS\Uri\Uri::root(true) ?>'
		, URIROOTABS : '<?php echo \Joomla\CMS\Uri\Uri::root() ?>'
		, HASPAGEBUILDERCK : '<?php echo (int)file_exists(JPATH_ROOT . '/administrator/components/com_pagebuilderck') ?>'
		, ADMIN_URL : '<?php echo \Joomla\CMS\Uri\Uri::root(true) ?>/administrator/index.php?option=com_slideshowck'
		, FRONT_URL : '<?php echo \Joomla\CMS\Uri\Uri::root(true) ?>/index.php?option=com_slideshowck'
		, BASE_URL : '<?php echo \Joomla\CMS\Uri\Uri::base(true) ?>/index.php?option=com_slideshowck'
		, USERID : '<?php echo \Joomla\CMS\Factory::getUser()->id ?>'
		, ISJ4 : '<?php echo version_compare(JVERSION, "4") ?>'
	};
</script>PKv�!]�����ckfolder.phpnu&1i�<?php
namespace Slideshowck;

defined('_JEXEC') or die;

jimport('joomla.filesystem.folder');

class CKFolder extends \Joomla\CMS\Filesystem\Folder {
	
}
PKv�!]��a5�7�7
htmlfixer.phpnu&1i�<?php
// -------------------------------------------------
// HTML FIXER v.2.05 15/07/2010
// clean dirty html and make it better, fix open tags
// bad nesting, bad quotes, bad autoclosing tags.
//
// by Giulio Pons, http://www.barattalo.it
// -------------------------------------------------
// usage:
// -------------------------------------------------
// $a = new HtmlFixer();
// $clean_html = $a->getFixedHtml($dirty_html);
// -------------------------------------------------

Class SlideshowCKHtmlFixer {
	public $dirtyhtml;
	public $fixedhtml;
	public $allowed_styles;		// inline styles array of allowed css (if empty means ALL allowed)
	private $matrix;			// array used to store nodes
	public $debug;
	private $fixedhtmlDisplayCode;

	public function __construct() {
		$this->dirtyhtml = "";
		$this->fixedhtml = "";
		$this->debug = false;
		$this->fixedhtmlDisplayCode = "";
		$this->allowed_styles = array();
	}

	public function getFixedHtml($dirtyhtml) {
		$c = 0;
		$this->dirtyhtml = $dirtyhtml;
		$this->fixedhtml = "";
		$this->fixedhtmlDisplayCode = "";
		if (is_array($this->matrix)) unset($this->matrix);
		$errorsFound=0;
		while ($c<10) {
			/*
				iterations, every time it's getting better...
			*/
			if ($c>0) $this->dirtyhtml = $this->fixedxhtml;
			$errorsFound = $this->charByCharJob();
			if (!$errorsFound) $c=10;	// if no corrections made, stops iteration
			$this->fixedxhtml=str_replace('<root>','',$this->fixedxhtml);
			$this->fixedxhtml=str_replace('</root>','',$this->fixedxhtml);
			$this->fixedxhtml = $this->removeSpacesAndBadTags($this->fixedxhtml);
			$c++;
		}
		return $this->fixedxhtml;
	}

	private function fixStrToLower($m){
		/*
			$m is a part of the tag: make the first part of attr=value lowercase
		*/
		$right = strstr($m, '=');
		$left = str_replace($right,'',$m);
		return strtolower($left).$right;
	}

	private function fixQuotes($s){
		$q = "\"";// thanks to emmanuel@evobilis.com
		if (!stristr($s,"=")) return $s;
		$out = $s;
		preg_match_all("|=(.*)|",$s,$o,PREG_PATTERN_ORDER);
		for ($i = 0; $i< count ($o[1]); $i++) {
			$t = trim ( $o[1][$i] ) ;
			$lc="";
			if ($t!="") {
				if ($t[strlen($t)-1]==">") {
					$lc= ($t[strlen($t)-2].$t[strlen($t)-1])=="/>"  ?  "/>"  :  ">" ;
					$t=substr($t,0,-1);
				}
				//missing " or ' at the beginning
				if (($t[0]!="\"")&&($t[0]!="'")) $out = str_replace( $t, "\"".$t,$out); else $q=$t[0];
				//missing " or ' at the end
				if (($t[strlen($t)-1]!="\"")&&($t[strlen($t)-1]!="'")) $out = str_replace( $t.$lc, $t.$q.$lc,$out);
			}
		}
		return $out;
	}

	private function fixTag($t){
		/* remove non standard attributes and call the fix for quoted attributes */
		$t = preg_replace (
			array(
				'/borderColor=([^ >])*/i',
				'/border=([^ >])*/i'
			), 
			array(
				'',
				''
			)
			, $t);
		$ar = explode(" ",$t);
		$nt = "";
		for ($i=0;$i<count($ar);$i++) {
			$ar[$i]=$this->fixStrToLower($ar[$i]);
			if (stristr($ar[$i],"=")) $ar[$i] = $this->fixQuotes($ar[$i]);	// thanks to emmanuel@evobilis.com
			//if (stristr($ar[$i],"=") && !stristr($ar[$i],"=\"")) $ar[$i] = $this->fixQuotes($ar[$i]);
			$nt.=$ar[$i]." ";
		}
		$nt=preg_replace("/<( )*/i","<",$nt);
		$nt=preg_replace("/( )*>/i",">",$nt);
		return trim($nt);
	}

	private function extractChars($tag1,$tag2,$tutto) { /*extract a block between $tag1 and $tag2*/
		if (!stristr($tutto, $tag1)) return '';
		$s=stristr($tutto,$tag1);
		$s=substr( $s,strlen($tag1));
		if (!stristr($s,$tag2)) return '';
		$s1=stristr($s,$tag2);
		return substr($s,0,strlen($s)-strlen($s1));
	}

	private function mergeStyleAttributes($s) {
		//
		// merge many style definitions in the same tag in just one attribute style
		//

		$x = "";
		$temp = "";
		$c = 0;
		while(stristr($s,"style=\"")) {
			$temp = $this->extractChars("style=\"","\"",$s);
			if ($temp=="") {
				// missing closing quote! add missing quote.
				return preg_replace("/(\/)?>/i","\"\\1>",$s);
			}
			if ($c==0) $s = str_replace("style=\"".$temp."\"","##PUTITHERE##",$s);
				$s = str_replace("style=\"".$temp."\"","",$s);
			if (!preg_match("/;$/i",$temp)) $temp.=";";
			$x.=$temp;
			$c++;
		}

		if (count($this->allowed_styles)>0) {
			// keep only allowed styles by Martin Vool 2010-04-19
			$check=explode(';', $x);
			$x="";
			foreach($check as $chk){
				foreach($this->allowed_styles as $as)
					if(stripos($chk, $as) !== False) { $x.=$chk.';'; break; } 
			}
		}

		if ($c>0) $s = str_replace("##PUTITHERE##","style=\"".$x."\"",$s);
		return $s;


	}

	private function fixAutoclosingTags($tag,$tipo=""){
		/*
			metodo richiamato da fix() per aggiustare i tag auto chiudenti (<br/> <img ... />)
		*/
		if (in_array( $tipo, array ("img","input","br","hr")) ) {
			if (!stristr($tag,'/>')) $tag = str_replace('>','/>',$tag );
		}
		return $tag;
	}

	private function getTypeOfTag($tag) {
		$tag = trim(preg_replace("/[\>\<\/]/i","",$tag));
		$a = explode(" ",$tag);
		return $a[0];
	}


	private function checkTree() {
		// return the number of errors found
		$errorsCounter = 0;
		for ($i=1;$i<count($this->matrix);$i++) {
			$flag=false;
			if ($this->matrix[$i]["tagType"]=="div") { //div cannot stay inside a p, b, etc.
				$parentType = $this->matrix[$this->matrix[$i]["parentTag"]]["tagType"];
				if (in_array($parentType, array("p","b","i","font","u","small","strong","em"))) $flag=true;
			}

			if (in_array( $this->matrix[$i]["tagType"], array( "b", "strong" )) ) { //b cannot stay inside b o strong.
				$parentType = $this->matrix[$this->matrix[$i]["parentTag"]]["tagType"];
				if (in_array($parentType, array("b","strong"))) $flag=true;
			}

			if (in_array( $this->matrix[$i]["tagType"], array ( "i", "em") )) { //i cannot stay inside i or em
				$parentType = $this->matrix[$this->matrix[$i]["parentTag"]]["tagType"];
				if (in_array($parentType, array("i","em"))) $flag=true;
			}

			if ($this->matrix[$i]["tagType"]=="p") {
				$parentType = $this->matrix[$this->matrix[$i]["parentTag"]]["tagType"];
				if (in_array($parentType, array("p","b","i","font","u","small","strong","em"))) $flag=true;
			}

			if ($this->matrix[$i]["tagType"]=="table") {
				$parentType = $this->matrix[$this->matrix[$i]["parentTag"]]["tagType"];
				if (in_array($parentType, array("p","b","i","font","u","small","strong","em","tr","table"))) $flag=true;
			}
			if ($flag) {
				$errorsCounter++;
				if ($this->debug) echo "<div style='color:#ff0000'>Found a <b>".$this->matrix[$i]["tagType"]."</b> tag inside a <b>".htmlspecialchars($parentType)."</b> tag at node $i: MOVED</div>";
				
				$swap = $this->matrix[$this->matrix[$i]["parentTag"]]["parentTag"];
				if ($this->debug) echo "<div style='color:#ff0000'>Every node that has parent ".$this->matrix[$i]["parentTag"]." will have parent ".$swap."</div>";
				$this->matrix[$this->matrix[$i]["parentTag"]]["tag"]="<!-- T A G \"".$this->matrix[$this->matrix[$i]["parentTag"]]["tagType"]."\" R E M O V E D -->";
				$this->matrix[$this->matrix[$i]["parentTag"]]["tagType"]="";
				$hoSpostato=0;
				for ($j=count($this->matrix)-1;$j>=$i;$j--) {
					if ($this->matrix[$j]["parentTag"]==$this->matrix[$i]["parentTag"]) {
						$this->matrix[$j]["parentTag"] = $swap;
						$hoSpostato=1;
					}
				}
			}

		}
		return $errorsCounter;

	}

	private function findSonsOf($parentTag) {
		// build correct html recursively
		$out= "";
		for ($i=1;$i<count($this->matrix);$i++) {
			if ($this->matrix[$i]["parentTag"]==$parentTag) {
				if ($this->matrix[$i]["tag"]!="") {
					$out.=$this->matrix[$i]["pre"];
					$out.=$this->matrix[$i]["tag"];
					$out.=$this->matrix[$i]["post"];
				} else {
					$out.=$this->matrix[$i]["pre"];
					$out.=$this->matrix[$i]["post"];
				}
				if ($this->matrix[$i]["tag"]!="") {
					$out.=$this->findSonsOf($i);
					if ($this->matrix[$i]["tagType"]!="") {
						//write the closing tag
						if (!in_array($this->matrix[$i]["tagType"], array ( "br","img","hr","input"))) 
							$out.="</". $this->matrix[$i]["tagType"].">";
					}
				}
			}
		}
		return $out;
	}

	private function findSonsOfDisplayCode($parentTag) {
		//used for debug
		$out= "";
		for ($i=1;$i<count($this->matrix);$i++) {
			if ($this->matrix[$i]["parentTag"]==$parentTag) {
				$out.= "<div style=\"padding-left:15\"><span style='float:left;background-color:#FFFF99;color:#000;'>{$i}:</span>";
				if ($this->matrix[$i]["tag"]!="") {
					if ($this->matrix[$i]["pre"]!="") $out.=htmlspecialchars($this->matrix[$i]["pre"])."<br>";
					$out.="".htmlspecialchars($this->matrix[$i]["tag"])."<span style='background-color:red; color:white'>{$i} <em>".$this->matrix[$i]["tagType"]."</em></span>";
					$out.=htmlspecialchars($this->matrix[$i]["post"]);
				} else {
					if ($this->matrix[$i]["pre"]!="") $out.=htmlspecialchars($this->matrix[$i]["pre"])."<br>";
					$out.=htmlspecialchars($this->matrix[$i]["post"]);
				}
				if ($this->matrix[$i]["tag"]!="") {
					$out.="<div>".$this->findSonsOfDisplayCode($i)."</div>\n";
					if ($this->matrix[$i]["tagType"]!="") {
						if (($this->matrix[$i]["tagType"]!="br") && ($this->matrix[$i]["tagType"]!="img") && ($this->matrix[$i]["tagType"]!="hr")&& ($this->matrix[$i]["tagType"]!="input"))
							$out.="<div style='color:red'>".htmlspecialchars("</". $this->matrix[$i]["tagType"].">")."{$i} <em>".$this->matrix[$i]["tagType"]."</em></div>";
					}
				}
				$out.="</div>\n";
			}
		}
		return $out;
	}

	private function removeSpacesAndBadTags($s) {
		$i=0;
		while ($i<10) {
			$i++;
			$s = preg_replace (
				array(
					'/[\r\n]/i',
					'/  /i',
					'/<p([^>])*>(&nbsp;)*\s*<\/p>/i',
					'/<span([^>])*>(&nbsp;)*\s*<\/span>/i',
					'/<strong([^>])*>(&nbsp;)*\s*<\/strong>/i',
					'/<em([^>])*>(&nbsp;)*\s*<\/em>/i',
					'/<font([^>])*>(&nbsp;)*\s*<\/font>/i',
					'/<small([^>])*>(&nbsp;)*\s*<\/small>/i',
					'/<\?xml:namespace([^>])*><\/\?xml:namespace>/i',
					'/<\?xml:namespace([^>])*\/>/i',
					'/class=\"MsoNormal\"/i',
					'/<o:p><\/o:p>/i',
					'/<!DOCTYPE([^>])*>/i',
					'/<!--(.|\s)*?-->/',
					'/<\?(.|\s)*?\?>/'
				), 
				array(
					' ',
					' ',
					'',
					'',
					'',
					'',
					'',
					'',
					'',
					'',
					'',
					' ',
					'',
					''
				)
				, trim($s));
		}
		return $s;
	}

	private function charByCharJob() {
		$s = $this->removeSpacesAndBadTags($this->dirtyhtml);
 		if ($s=="") {
			$this->fixedxhtml="";
			return;
		}
		$s = "<root>".$s."</root>";
		$contenuto = "";
		$ns = "";
		$i=0;
		$j=0;
		$indexparentTag=0;
		$padri=array();
		array_push($padri,"0");
		$this->matrix[$j]["tagType"]="";
		$this->matrix[$j]["tag"]="";
		$this->matrix[$j]["parentTag"]="0";
		$this->matrix[$j]["pre"]="";
		$this->matrix[$j]["post"]="";
		$tags=array();
		
		while($i<strlen($s)) {
			if ( $s[$i] =="<") {
				/*
					found a tag
				*/
				$contenuto = $ns;
				$ns = "";
				
				$tag="";
				while( $i<strlen($s) && $s[$i]!=">" ){
					// get chars till the end of a tag
					$tag.=$s[$i];
					$i++;
				}
				$tag.=$s[$i];
				
				if($s[$i]==">") {
					/*
						$tag contains a tag <...chars...>
						let's clean it!
					*/
					$tag = $this->fixTag($tag);
					$tagType = $this->getTypeOfTag($tag);
					$tag = $this->fixAutoclosingTags($tag,$tagType);
					$tag = $this->mergeStyleAttributes($tag);

					if (!isset($tags[$tagType])) $tags[$tagType]=0;
					$tagok=true;
					if (($tags[$tagType]==0)&&(stristr($tag,'/'.$tagType.'>'))) {
						$tagok=false;
						/* there is a close tag without any open tag, I delete it */
						if ($this->debug) echo "<div style='color:#ff0000'>Found a closing tag <b>".htmlspecialchars($tag)."</b> at char $i without open tag: REMOVED</div>";
					}
				}
				if ($tagok) {
					$j++;
					$this->matrix[$j]["pre"]="";
					$this->matrix[$j]["post"]="";
					$this->matrix[$j]["parentTag"]="";
					$this->matrix[$j]["tag"]="";
					$this->matrix[$j]["tagType"]="";
					if (stristr($tag,'/'.$tagType.'>')) {
						/*
							it's the closing tag
						*/
						$ind = array_pop($padri);
						$this->matrix[$j]["post"]=$contenuto;
						$this->matrix[$j]["parentTag"]=$ind;
						$tags[$tagType]--;
					} else {
						if (@preg_match("/".$tagType."\/>$/i",$tag)||preg_match("/\/>/i",$tag)) {
							/*
								it's a autoclosing tag
							*/
							$this->matrix[$j]["tagType"]=$tagType;
							$this->matrix[$j]["tag"]=$tag;
							$indexparentTag = array_pop($padri);
							array_push($padri,$indexparentTag);
							$this->matrix[$j]["parentTag"]=$indexparentTag;
							$this->matrix[$j]["pre"]=$contenuto;
							$this->matrix[$j]["post"]="";
						} else {
							/*
								it's a open tag
							*/
							$tags[$tagType]++;
							$this->matrix[$j]["tagType"]=$tagType;
							$this->matrix[$j]["tag"]=$tag;
							$indexparentTag = array_pop($padri);
							array_push($padri,$indexparentTag);
							array_push($padri,$j);
							$this->matrix[$j]["parentTag"]=$indexparentTag;
							$this->matrix[$j]["pre"]=$contenuto;
							$this->matrix[$j]["post"]="";
						}
					}
				}
			} else {
				/*
					content of the tag
				*/
				$ns.=$s[$i];
			}
			$i++;
		}
		/*
			remove not valid tags
		*/
		for ($eli=$j+1;$eli<count($this->matrix);$eli++) {
			$this->matrix[$eli]["pre"]="";
			$this->matrix[$eli]["post"]="";
			$this->matrix[$eli]["parentTag"]="";
			$this->matrix[$eli]["tag"]="";
			$this->matrix[$eli]["tagType"]="";
		}
		$errorsCounter = $this->checkTree();		// errorsCounter contains the number of removed tags
		$this->fixedxhtml=$this->findSonsOf(0);	// build html fixed
		if ($this->debug) {
			$this->fixedxhtmlDisplayCode=$this->findSonsOfDisplayCode(0);
			echo "<table border=1 cellspacing=0 cellpadding=0>";
			echo "<tr><th>node id</th>";
			echo "<th>pre</th>";
			echo "<th>tag</th>";
			echo "<th>post</th>";
			echo "<th>parentTag</th>";
			echo "<th>tipo</th></tr>";
			for ($k=0;$k<=$j;$k++) {
				echo "<tr><td>$k</td>";
				echo "<td>&nbsp;".htmlspecialchars($this->matrix[$k]["pre"])."</td>";
				echo "<td>&nbsp;".htmlspecialchars($this->matrix[$k]["tag"])."</td>";
				echo "<td>&nbsp;".htmlspecialchars($this->matrix[$k]["post"])."</td>";
				echo "<td>&nbsp;".$this->matrix[$k]["parentTag"]."</td>";
				echo "<td>&nbsp;<i>".$this->matrix[$k]["tagType"]."</i></td></tr>";
			}
			echo "</table>";
			echo "<hr/>{$j}<hr/>\n\n\n\n".$this->fixedxhtmlDisplayCode;
		}
		return $errorsCounter;
	}
}PKv�!]�|�o
o
ckmodel.phpnu&1i�<?php
Namespace Slideshowck;

defined('CK_LOADED') or die;

use \Slideshowck\CKFof;

class CKModel {

	var $_item = null;

	private static $instance;

	protected $input;

	protected $table;

	protected $__state_set = null;

	protected $state;

	protected $pagination;

	function __construct() {
		$this->input = CKFof::getInput();
		$this->state = new \Joomla\CMS\Object\CMSObject;
	}

	static function getInstance($name, $prefix, $config) {

		if (is_object(self::$instance))
		{
			return self::$instance;
		}

		$basePath = SLIDESHOWCK_PATH;
		// Check for a controller.task command.
		$input = CKFof::getInput();

		// Define the controller filename and path.
		$file       = strtolower($name . '.php');
		$path       = $basePath . '/models/' . $file;

		// Get the controller class name.
		$class = ucfirst($prefix) . 'Model' . ucfirst($name);

		// Include the class if not present.
		if (!class_exists($class))
		{
			// If the controller file path exists, include it.
			if (file_exists($path))
			{
				require_once $path;
			}
			else
			{
//				throw new \InvalidArgumentException(\Joomla\CMS\Language\Text::sprintf('ERROR_INVALID_MODEL', $type, $format));
			
				return false;
			}
		}

		// Instantiate the class.
		if (!class_exists($class))
		{
			throw new \InvalidArgumentException(\Joomla\CMS\Language\Text::sprintf('ERROR_INVALID_MODEL_CLASS', $class));
		}

		// Instantiate the class, store it to the static container, and return it
		return self::$instance = new $class();
	}

	public function save($data) {

	}

	public function delete($id) {
		return CKFof::dbDelete( $this->table, (int)$id );
	}

	public function setState($property, $value = null)
	{
		return $this->state->set($property, $value);
	}

	public function getState($property = null, $default = null)
	{
		if (!$this->__state_set)
		{
			// Protected method to auto-populate the model state.
			$this->populateState();

			// Set the model state set flag to true.
			$this->__state_set = true;
		}

		return $property === null ? $this->state : $this->state->get($property, $default);
	}

	protected function populateState()
	{
		$this->state->set('filter_order', $this->input->get('filter_order', 'a.id'));
		$this->state->set('filter_order_Dir', $this->input->get('filter_order_Dir', 'asc'));
		$this->state->set('filter_search', $this->input->get('filter_search', ''));
		$this->state->set('limitstart', $this->input->get('limitstart', 0));
		$this->state->set('limit_total', $this->input->get('limittotal', 0));
		$this->state->set('limit', $this->input->get('limit', 20));
	}

	public function getPagination($total = null, $start = null, $limit = null)
	{
		if (!$this->pagination)
		{
			$total = $this->state->get('limit_total', $total);
//			$total = $this->getTotal();
			$start = $this->state->get('limitstart', $start);
			$limit = $this->state->get('limit', $limit);

			$this->pagination = new \Joomla\CMS\Pagination\Pagination($total, $start, $limit);
		}

		return $this->pagination;
	}

	public function getTotal($query) {
		$db = CKFof::getDbo();
		$query = clone $query;
		$query->clear('select')->clear('order')->clear('limit')->clear('offset')->select('COUNT(*)');
		$db->setQuery($query);

		return (int) $db->loadResult();
	}

	public function copy($id) {
		$row = CKFof::dbLoad($this->table, (int)$id);
		$row->id = 0;
		$row->name = $row->name . ' - copy';

		$newid = CKFof::dbStore($this->table, $row);

		return $newid;
	}
}PK�!]�����6�6	menus.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_menus
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

use Joomla\CMS\Menu\MenuHelper;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;

defined('_JEXEC') or die;

/**
 * Menus component helper.
 *
 * @since  1.6
 */
class MenusHelper
{
	/**
	 * Defines the valid request variables for the reverse lookup.
	 *
	 * @since   1.6
	 */
	protected static $_filter = array('option', 'view', 'layout');

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_MENUS_SUBMENU_MENUS'),
			'index.php?option=com_menus&view=menus',
			$vName == 'menus'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_MENUS_SUBMENU_ITEMS'),
			'index.php?option=com_menus&view=items',
			$vName == 'items'
		);
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @param   integer  $parentId  The menu ID.
	 *
	 * @return  JObject
	 *
	 * @since   1.6
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions($parentId = 0)
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		return JHelperContent::getActions('com_menus');
	}

	/**
	 * Gets a standard form of a link for lookups.
	 *
	 * @param   mixed  $request  A link string or array of request variables.
	 *
	 * @return  mixed  A link in standard option-view-layout form, or false if the supplied response is invalid.
	 *
	 * @since   1.6
	 */
	public static function getLinkKey($request)
	{
		if (empty($request))
		{
			return false;
		}

		// Check if the link is in the form of index.php?...
		if (is_string($request))
		{
			$args = array();

			if (strpos($request, 'index.php') === 0)
			{
				parse_str(parse_url(htmlspecialchars_decode($request), PHP_URL_QUERY), $args);
			}
			else
			{
				parse_str($request, $args);
			}

			$request = $args;
		}

		// Only take the option, view and layout parts.
		foreach ($request as $name => $value)
		{
			if ((!in_array($name, self::$_filter)) && (!($name == 'task' && !array_key_exists('view', $request))))
			{
				// Remove the variables we want to ignore.
				unset($request[$name]);
			}
		}

		ksort($request);

		return 'index.php?' . http_build_query($request, '', '&');
	}

	/**
	 * Get the menu list for create a menu module
	 *
	 * @param   int  $clientId  Optional client id - viz 0 = site, 1 = administrator, can be NULL for all
	 *
	 * @return  array  The menu array list
	 *
	 * @since    1.6
	 */
	public static function getMenuTypes($clientId = 0)
	{
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('a.menutype')
			->from('#__menu_types AS a');

		if (isset($clientId))
		{
			$query->where('a.client_id = ' . (int) $clientId);
		}

		$db->setQuery($query);

		return $db->loadColumn();
	}

	/**
	 * Get a list of menu links for one or all menus.
	 *
	 * @param   string   $menuType   An option menu to filter the list on, otherwise all menu with given client id links
	 *                               are returned as a grouped array.
	 * @param   integer  $parentId   An optional parent ID to pivot results around.
	 * @param   integer  $mode       An optional mode. If parent ID is set and mode=2, the parent and children are excluded from the list.
	 * @param   array    $published  An optional array of states
	 * @param   array    $languages  Optional array of specify which languages we want to filter
	 * @param   int      $clientId   Optional client id - viz 0 = site, 1 = administrator, can be NULL for all (used only if menutype not givein)
	 *
	 * @return  array
	 *
	 * @since   1.6
	 */
	public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, $published = array(), $languages = array(), $clientId = 0)
	{
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('DISTINCT(a.id) AS value,
					  a.title AS text,
					  a.alias,
					  a.level,
					  a.menutype,
					  a.client_id,
					  a.type,
					  a.published,
					  a.template_style_id,
					  a.checked_out,
					  a.language,
					  a.lft'
			)
			->from('#__menu AS a');

		$query->select('e.name as componentname, e.element')
			->join('left', '#__extensions e ON e.extension_id = a.component_id');

		if (JLanguageMultilang::isEnabled())
		{
			$query->select('l.title AS language_title, l.image AS language_image, l.sef AS language_sef')
				->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language');
		}

		// Filter by the type if given, this is more specific than client id
		if ($menuType)
		{
			$query->where('(a.menutype = ' . $db->quote($menuType) . ' OR a.parent_id = 0)');
		}
		elseif (isset($clientId))
		{
			$query->where('a.client_id = ' . (int) $clientId);
		}

		// Prevent the parent and children from showing if requested.
		if ($parentId && $mode == 2)
		{
			$query->join('LEFT', '#__menu AS p ON p.id = ' . (int) $parentId)
				->where('(a.lft <= p.lft OR a.rgt >= p.rgt)');
		}

		if (!empty($languages))
		{
			if (is_array($languages))
			{
				$languages = '(' . implode(',', array_map(array($db, 'quote'), $languages)) . ')';
			}

			$query->where('a.language IN ' . $languages);
		}

		if (!empty($published))
		{
			if (is_array($published))
			{
				$published = '(' . implode(',', $published) . ')';
			}

			$query->where('a.published IN ' . $published);
		}

		$query->where('a.published != -2');
		$query->order('a.lft ASC');

		// Get the options.
		$db->setQuery($query);

		try
		{
			$links = $db->loadObjectList();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());

			return false;
		}

		if (empty($menuType))
		{
			// If the menutype is empty, group the items by menutype.
			$query->clear()
				->select('*')
				->from('#__menu_types')
				->where('menutype <> ' . $db->quote(''))
				->order('title, menutype');

			if (isset($clientId))
			{
				$query->where('client_id = ' . (int) $clientId);
			}

			$db->setQuery($query);

			try
			{
				$menuTypes = $db->loadObjectList();
			}
			catch (RuntimeException $e)
			{
				JError::raiseWarning(500, $e->getMessage());

				return false;
			}

			// Create a reverse lookup and aggregate the links.
			$rlu = array();

			foreach ($menuTypes as &$type)
			{
				$rlu[$type->menutype] = & $type;
				$type->links = array();
			}

			// Loop through the list of menu links.
			foreach ($links as &$link)
			{
				if (isset($rlu[$link->menutype]))
				{
					$rlu[$link->menutype]->links[] = & $link;

					// Cleanup garbage.
					unset($link->menutype);
				}
			}

			return $menuTypes;
		}
		else
		{
			return $links;
		}
	}

	/**
	 * Get the associations
	 *
	 * @param   integer  $pk  Menu item id
	 *
	 * @return  array
	 *
	 * @since   3.0
	 */
	public static function getAssociations($pk)
	{
		$langAssociations = JLanguageAssociations::getAssociations('com_menus', '#__menu', 'com_menus.item', $pk, 'id', '', '');
		$associations     = array();

		foreach ($langAssociations as $langAssociation)
		{
			$associations[$langAssociation->language] = $langAssociation->id;
		}

		return $associations;
	}

	/**
	 * Load the menu items from database for the given menutype
	 *
	 * @param   string   $menutype     The selected menu type
	 * @param   boolean  $enabledOnly  Whether to load only enabled/published menu items.
	 * @param   int[]    $exclude      The menu items to exclude from the list
	 *
	 * @return  array
	 *
	 * @since   3.8.0
	 *
	 * @deprecated  4.0  This method will return a node object to iterate over in 4.0. 
	 */
	public static function getMenuItems($menutype, $enabledOnly = false, $exclude = array())
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true);

		// Prepare the query.
		$query->select('m.*')
			->from('#__menu AS m')
			->where('m.menutype = ' . $db->q($menutype))
			->where('m.client_id = 1')
			->where('m.id > 1');

		if ($enabledOnly)
		{
			$query->where('m.published = 1');
		}

		// Filter on the enabled states.
		$query->select('e.element')
			->join('LEFT', '#__extensions AS e ON m.component_id = e.extension_id')
			->where('(e.enabled = 1 OR e.enabled IS NULL)');

		if (count($exclude))
		{
			$exId = array_filter($exclude, 'is_numeric');
			$exEl = array_filter($exclude, 'is_string');

			if ($exId)
			{
				$query->where('m.id NOT IN (' . implode(', ', array_map('intval', $exId)) . ')');
				$query->where('m.parent_id NOT IN (' . implode(', ', array_map('intval', $exId)) . ')');
			}

			if ($exEl)
			{
				$query->where('e.element NOT IN (' . implode(', ', $db->quote($exEl)) . ')');
			}
		}

		// Order by lft.
		$query->order('m.lft');

		$db->setQuery($query);

		try
		{
			$menuItems = $db->loadObjectList();

			foreach ($menuItems as &$menuitem)
			{
				$menuitem->params = new Registry($menuitem->params);
			}
		}
		catch (RuntimeException $e)
		{
			$menuItems = array();

			JFactory::getApplication()->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');
		}

		return $menuItems;
	}

	/**
	 * Method to install a preset menu into database and link them to the given menutype
	 *
	 * @param   string  $preset    The preset name
	 * @param   string  $menutype  The target menutype
	 *
	 * @return  void
	 *
	 * @throws  Exception
	 *
	 * @since   3.8.0
	 */
	public static function installPreset($preset, $menutype)
	{
		$items = MenuHelper::loadPreset($preset, false);

		if (count($items) == 0)
		{
			throw new Exception(JText::_('COM_MENUS_PRESET_LOAD_FAILED'));
		}

		static::installPresetItems($items, $menutype, 1);
	}

	/**
	 * Method to install a preset menu item into database and link it to the given menutype
	 *
	 * @param   stdClass[]  $items     The single menuitem instance with a list of its descendants
	 * @param   string      $menutype  The target menutype
	 * @param   int         $parent    The parent id or object
	 *
	 * @return  void
	 *
	 * @throws  Exception
	 *
	 * @since   3.8.0
	 */
	protected static function installPresetItems(&$items, $menutype, $parent = 1)
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true);

		static $components = array();

		if (!$components)
		{
			$query->select('extension_id, element')->from('#__extensions')->where('type = ' . $db->q('component'));
			$components = $db->setQuery($query)->loadObjectList();
			$components = ArrayHelper::getColumn((array) $components, 'element', 'extension_id');
		}

		$dispatcher = JEventDispatcher::getInstance();
		$dispatcher->trigger('onPreprocessMenuItems', array('com_menus.administrator.import', &$items, null, true));

		foreach ($items as &$item)
		{
			/** @var  JTableMenu  $table */
			$table = JTable::getInstance('Menu');

			$item->alias = $menutype . '-' . $item->title;

			if ($item->type == 'separator')
			{
				// Do not reuse a separator
				$item->title = $item->title ?: '-';
				$item->alias = microtime(true);
			}
			elseif ($item->type == 'heading' || $item->type == 'container')
			{
				// Try to match an existing record to have minimum collision for a heading
				$keys  = array(
					'menutype'  => $menutype,
					'type'      => $item->type,
					'title'     => $item->title,
					'parent_id' => $parent,
					'client_id' => 1,
				);
				$table->load($keys);
			}
			elseif ($item->type == 'url' || $item->type == 'component')
			{
				if (substr($item->link, 0, 8) === 'special:')
				{
					$special = substr($item->link, 8);

					if ($special === 'language-forum')
					{
						$item->link = 'index.php?option=com_admin&amp;view=help&amp;layout=langforum';
					}
					elseif ($special === 'custom-forum')
					{
						$item->link = '';
					}
				}

				// Try to match an existing record to have minimum collision for a link
				$keys  = array(
					'menutype'  => $menutype,
					'type'      => $item->type,
					'link'      => $item->link,
					'parent_id' => $parent,
					'client_id' => 1,
				);
				$table->load($keys);
			}

			// Translate "hideitems" param value from "element" into "menu-item-id"
			if ($item->type == 'container' && count($hideitems = (array) $item->params->get('hideitems')))
			{
				foreach ($hideitems as &$hel)
				{
					if (!is_numeric($hel))
					{
						$hel = array_search($hel, $components);
					}
				}

				$query->clear()->select('id')->from('#__menu')->where('component_id IN (' . implode(', ', $hideitems) . ')');
				$hideitems = $db->setQuery($query)->loadColumn();

				$item->params->set('hideitems', $hideitems);
			}

			$record = array(
				'menutype'     => $menutype,
				'title'        => $item->title,
				'alias'        => $item->alias,
				'type'         => $item->type,
				'link'         => $item->link,
				'browserNav'   => $item->browserNav ? 1 : 0,
				'img'          => $item->class,
				'access'       => $item->access,
				'component_id' => array_search($item->element, $components),
				'parent_id'    => $parent,
				'client_id'    => 1,
				'published'    => 1,
				'language'     => '*',
				'home'         => 0,
				'params'       => (string) $item->params,
			);

			if (!$table->bind($record))
			{
				throw new Exception('Bind failed: ' . $table->getError());
			}

			$table->setLocation($parent, 'last-child');

			if (!$table->check())
			{
				throw new Exception('Check failed: ' . $table->getError());
			}

			if (!$table->store())
			{
				throw new Exception('Saved failed: ' . $table->getError());
			}

			$item->id = $table->get('id');

			if (!empty($item->submenu))
			{
				static::installPresetItems($item->submenu, $menutype, $item->id);
			}
		}
	}
}
PK�!]l22��html/menus.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_menus
 *
 * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Registry\Registry;

JLoader::register('MenusHelper', JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php');

/**
 * Menus HTML helper class.
 *
 * @package     Joomla.Administrator
 * @subpackage  com_menus
 * @since       1.7
 */
abstract class MenusHtmlMenus
{
	/**
	 * Generate the markup to display the item associations
	 *
	 * @param   int  $itemid  The menu item id
	 *
	 * @return  string
	 *
	 * @since   3.0
	 *
	 * @throws Exception If there is an error on the query
	 */
	public static function association($itemid)
	{
		// Defaults
		$html = '';

		// Get the associations
		if ($associations = MenusHelper::getAssociations($itemid))
		{
			// Get the associated menu items
			$db = JFactory::getDbo();
			$query = $db->getQuery(true)
				->select('m.id, m.title')
				->select('l.sef as lang_sef, l.lang_code')
				->select('mt.title as menu_title')
				->from('#__menu as m')
				->join('LEFT', '#__menu_types as mt ON mt.menutype=m.menutype')
				->where('m.id IN (' . implode(',', array_values($associations)) . ')')
				->where('m.id != ' . $itemid)
				->join('LEFT', '#__languages as l ON m.language=l.lang_code')
				->select('l.image')
				->select('l.title as language_title');
			$db->setQuery($query);

			try
			{
				$items = $db->loadObjectList('id');
			}
			catch (runtimeException $e)
			{
				throw new Exception($e->getMessage(), 500);
			}

			// Construct html
			if ($items)
			{
				foreach ($items as &$item)
				{
					$text = strtoupper($item->lang_sef);
					$url = JRoute::_('index.php?option=com_menus&task=item.edit&id=' . (int) $item->id);

					$tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '<br />' . JText::sprintf('COM_MENUS_MENU_SPRINTF', $item->menu_title);
					$classes = 'hasPopover label label-association label-' . $item->lang_sef;

					$item->link = '<a href="' . $url . '" title="' . $item->language_title . '" class="' . $classes
						. '" data-content="' . $tooltip . '" data-placement="top">'
						. $text . '</a>';
				}
			}

			JHtml::_('bootstrap.popover');

			$html = JLayoutHelper::render('joomla.content.associations', $items);
		}

		return $html;
	}

	/**
	 * Returns a published state on a grid
	 *
	 * @param   integer  $value     The state value.
	 * @param   integer  $i         The row index
	 * @param   boolean  $enabled   An optional setting for access control on the action.
	 * @param   string   $checkbox  An optional prefix for checkboxes.
	 *
	 * @return  string        The Html code
	 *
	 * @see JHtmlJGrid::state
	 *
	 * @since   1.7.1
	 */
	public static function state($value, $i, $enabled = true, $checkbox = 'cb')
	{
		$states = array(
			9  => array(
				'unpublish',
				'',
				'COM_MENUS_HTML_UNPUBLISH_HEADING',
				'',
				true,
				'publish',
				'publish',
			),
			8  => array(
				'publish',
				'',
				'COM_MENUS_HTML_PUBLISH_HEADING',
				'',
				true,
				'unpublish',
				'unpublish',
			),
			7  => array(
				'unpublish',
				'',
				'COM_MENUS_HTML_UNPUBLISH_SEPARATOR',
				'',
				true,
				'publish',
				'publish',
			),
			6  => array(
				'publish',
				'',
				'COM_MENUS_HTML_PUBLISH_SEPARATOR',
				'',
				true,
				'unpublish',
				'unpublish',
			),
			5  => array(
				'unpublish',
				'',
				'COM_MENUS_HTML_UNPUBLISH_ALIAS',
				'',
				true,
				'publish',
				'publish',
			),
			4  => array(
				'publish',
				'',
				'COM_MENUS_HTML_PUBLISH_ALIAS',
				'',
				true,
				'unpublish',
				'unpublish',
			),
			3  => array(
				'unpublish',
				'',
				'COM_MENUS_HTML_UNPUBLISH_URL',
				'',
				true,
				'publish',
				'publish',
			),
			2  => array(
				'publish',
				'',
				'COM_MENUS_HTML_PUBLISH_URL',
				'',
				true,
				'unpublish',
				'unpublish',
			),
			1  => array(
				'unpublish',
				'COM_MENUS_EXTENSION_PUBLISHED_ENABLED',
				'COM_MENUS_HTML_UNPUBLISH_ENABLED',
				'COM_MENUS_EXTENSION_PUBLISHED_ENABLED',
				true,
				'publish',
				'publish',
			),
			0  => array(
				'publish',
				'COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED',
				'COM_MENUS_HTML_PUBLISH_ENABLED',
				'COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED',
				true,
				'unpublish',
				'unpublish',
			),
			-1 => array(
				'unpublish',
				'COM_MENUS_EXTENSION_PUBLISHED_DISABLED',
				'COM_MENUS_HTML_UNPUBLISH_DISABLED',
				'COM_MENUS_EXTENSION_PUBLISHED_DISABLED',
				true,
				'warning',
				'warning',
			),
			-2 => array(
				'publish',
				'COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED',
				'COM_MENUS_HTML_PUBLISH_DISABLED',
				'COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED',
				true,
				'trash',
				'trash',
			),
			-3 => array(
				'publish',
				'',
				'COM_MENUS_HTML_PUBLISH',
				'',
				true,
				'trash',
				'trash',
			),
		);

		return JHtml::_('jgrid.state', $states, $value, $i, 'items.', $enabled, true, $checkbox);
	}

	/**
	 * Returns a visibility state on a grid
	 *
	 * @param   integer  $params  Params of item.
	 *
	 * @return  string  The Html code
	 *
	 * @since   3.7.0
	 */
	public static function visibility($params)
	{
		$registry = new Registry;

		try
		{
			$registry->loadString($params);
		}
		catch (Exception $e)
		{
			// Invalid JSON
		}

		$show_menu = $registry->get('menu_show');

		return ($show_menu === 0) ? '<span class="label">' . JText::_('COM_MENUS_LABEL_HIDDEN') . '</span>' : '';
	}
}
PKϠ!]=���
�
html/templates.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_templates
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * JHtml helper class.
 *
 * @since  1.6
 */
class JHtmlTemplates
{
	/**
	 * Display the thumb for the template.
	 *
	 * @param   string   $template  The name of the template.
	 * @param   integer  $clientId  The application client ID the template applies to
	 *
	 * @return  string  The html string
	 *
	 * @since   1.6
	 */
	public static function thumb($template, $clientId = 0)
	{
		$client = JApplicationHelper::getClientInfo($clientId);
		$basePath = $client->path . '/templates/' . $template;
		$thumb = $basePath . '/template_thumbnail.png';
		$preview = $basePath . '/template_preview.png';
		$html = '';

		if (file_exists($thumb))
		{
			JHtml::_('bootstrap.tooltip');

			$clientPath = ($clientId == 0) ? '' : 'administrator/';
			$thumb = $clientPath . 'templates/' . $template . '/template_thumbnail.png';
			$html = JHtml::_('image', $thumb, JText::_('COM_TEMPLATES_PREVIEW'));

			if (file_exists($preview))
			{
				$html = '<button type="button" data-target="#' . $template . '-Modal" class="thumbnail pull-left hasTooltip" data-toggle="modal"'
					. ' title="' . JHtml::_('tooltipText', 'COM_TEMPLATES_CLICK_TO_ENLARGE') . '">' . $html . '</button>';
			}
		}

		return $html;
	}

	/**
	 * Renders the html for the modal linked to thumb.
	 *
	 * @param   string   $template  The name of the template.
	 * @param   integer  $clientId  The application client ID the template applies to
	 *
	 * @return  string  The html string
	 *
	 * @since   3.4
	 */
	public static function thumbModal($template, $clientId = 0)
	{
		$client = JApplicationHelper::getClientInfo($clientId);
		$basePath = $client->path . '/templates/' . $template;
		$baseUrl = ($clientId == 0) ? JUri::root(true) : JUri::root(true) . '/administrator';
		$thumb = $basePath . '/template_thumbnail.png';
		$preview = $basePath . '/template_preview.png';
		$html = '';

		if (file_exists($thumb))
		{
			if (file_exists($preview))
			{
				$preview = $baseUrl . '/templates/' . $template . '/template_preview.png';
				$footer = '<button type="button" class="btn" data-dismiss="modal">'
					. JText::_('JTOOLBAR_CLOSE') . '</button>';

				$html .= JHtml::_(
					'bootstrap.renderModal',
					$template . '-Modal',
					array(
						'title'  => JText::_('COM_TEMPLATES_BUTTON_PREVIEW'),
						'height' => '500px',
						'width'  => '800px',
						'footer' => $footer,
					),
					$body = '<div><img src="' . $preview . '" style="max-width:100%" alt="' . $template . '"></div>'
				);
			}
		}

		return $html;
	}
}
PKϠ!].��utemplate.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_templates
 *
 * @copyright   (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Template Helper class.
 *
 * @since  3.2
 */
abstract class TemplateHelper
{
	/**
	 * Checks if the file is an image
	 *
	 * @param   string  $fileName  The filename
	 *
	 * @return  boolean
	 *
	 * @since   3.2
	 */
	public static function getTypeIcon($fileName)
	{
		// Get file extension
		return strtolower(substr($fileName, strrpos($fileName, '.') + 1));
	}

	/**
	 * Checks if the file can be uploaded
	 *
	 * @param   array   $file  File information
	 * @param   string  $err   An error message to be returned
	 *
	 * @return  boolean
	 *
	 * @since   3.2
	 */
	public static function canUpload($file, $err = '')
	{
		$params = JComponentHelper::getParams('com_templates');

		if (empty($file['name']))
		{
			$app = JFactory::getApplication();
			$app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_UPLOAD_INPUT'), 'error');

			return false;
		}

		// Media file names should never have executable extensions buried in them.
		$executable = array(
			'exe', 'phtml','java', 'perl', 'py', 'asp','dll', 'go', 'jar',
			'ade', 'adp', 'bat', 'chm', 'cmd', 'com', 'cpl', 'hta', 'ins', 'isp',
			'jse', 'lib', 'mde', 'msc', 'msp', 'mst', 'pif', 'scr', 'sct', 'shb',
			'sys', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh'
		);
		$explodedFileName = explode('.', $file['name']);

		if (count($explodedFileName) > 2)
		{
			foreach ($executable as $extensionName)
			{
				if (in_array($extensionName, $explodedFileName))
				{
					$app = JFactory::getApplication();
					$app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EXECUTABLE'), 'error');

					return false;
				}
			}
		}

		jimport('joomla.filesystem.file');

		if ($file['name'] !== JFile::makeSafe($file['name']) || preg_match('/\s/', JFile::makeSafe($file['name'])))
		{
			$app = JFactory::getApplication();
			$app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILENAME'), 'error');

			return false;
		}

		$format = strtolower(JFile::getExt($file['name']));

		$imageTypes   = explode(',', $params->get('image_formats'));
		$sourceTypes  = explode(',', $params->get('source_formats'));
		$fontTypes    = explode(',', $params->get('font_formats'));
		$archiveTypes = explode(',', $params->get('compressed_formats'));

		$allowable = array_merge($imageTypes, $sourceTypes, $fontTypes, $archiveTypes);

		if ($format == '' || $format == false || (!in_array($format, $allowable)))
		{
			$app = JFactory::getApplication();
			$app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILETYPE'), 'error');

			return false;
		}

		if (in_array($format, $archiveTypes))
		{
			$zip = new ZipArchive;

			if ($zip->open($file['tmp_name']) === true)
			{
				for ($i = 0; $i < $zip->numFiles; $i++)
				{
					$entry     = $zip->getNameIndex($i);
					$endString = substr($entry, -1);

					if ($endString != DIRECTORY_SEPARATOR)
					{
						$explodeArray = explode('.', $entry);
						$ext          = end($explodeArray);

						if (!in_array($ext, $allowable))
						{
							$app = JFactory::getApplication();
							$app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_UNSUPPORTED_ARCHIVE'), 'error');

							return false;
						}
					}
				}
			}
			else
			{
				$app = JFactory::getApplication();
				$app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error');

				return false;
			}
		}

		// Max upload size set to 2 MB for Template Manager
		$maxSize = (int) ($params->get('upload_limit') * 1024 * 1024);

		if ($maxSize > 0 && (int) $file['size'] > $maxSize)
		{
			$app = JFactory::getApplication();
			$app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILETOOLARGE'), 'error');

			return false;
		}

		$xss_check = file_get_contents($file['tmp_name'], false, null, -1, 256);
		$html_tags = array(
			'abbr', 'acronym', 'address', 'applet', 'area', 'audioscope', 'base', 'basefont', 'bdo', 'bgsound', 'big', 'blackface', 'blink', 'blockquote',
			'body', 'bq', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'custom', 'dd', 'del', 'dfn', 'dir', 'div',
			'dl', 'dt', 'em', 'embed', 'fieldset', 'fn', 'font', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
			'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'layer', 'legend', 'li', 'limittext', 'link', 'listing',
			'map', 'marquee', 'menu', 'meta', 'multicol', 'nobr', 'noembed', 'noframes', 'noscript', 'nosmartquotes', 'object', 'ol', 'optgroup', 'option',
			'param', 'plaintext', 'pre', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'server', 'shadow', 'sidebar', 'small', 'spacer', 'span', 'strike',
			'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var', 'wbr', 'xml',
			'xmp', '!DOCTYPE', '!--'
		);

		foreach ($html_tags as $tag)
		{
			// A tag is '<tagname ', so we need to add < and a space or '<tagname>'
			if (stristr($xss_check, '<' . $tag . ' ') || stristr($xss_check, '<' . $tag . '>'))
			{
				$app = JFactory::getApplication();
				$app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNIEXSS'), 'error');

				return false;
			}
		}

		return true;
	}
}
PKϠ!]�cYeii
templates.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_templates
 *
 * @copyright   (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Templates component helper.
 *
 * @since  1.6
 */
class TemplatesHelper
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_TEMPLATES_SUBMENU_STYLES'),
			'index.php?option=com_templates&view=styles',
			$vName == 'styles'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_TEMPLATES_SUBMENU_TEMPLATES'),
			'index.php?option=com_templates&view=templates',
			$vName == 'templates'
		);
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject
	 *
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions()
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		return JHelperContent::getActions('com_templates');
	}

	/**
	 * Get a list of filter options for the application clients.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 */
	public static function getClientOptions()
	{
		// Build the filter options.
		$options = array();
		$options[] = JHtml::_('select.option', '0', JText::_('JSITE'));
		$options[] = JHtml::_('select.option', '1', JText::_('JADMINISTRATOR'));

		return $options;
	}

	/**
	 * Get a list of filter options for the templates with styles.
	 *
	 * @param   mixed  $clientId  The CMS client id (0:site | 1:administrator) or '*' for all.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 */
	public static function getTemplateOptions($clientId = '*')
	{
		// Build the filter options.
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);

		$query->select($db->quoteName('element', 'value'))
			->select($db->quoteName('name', 'text'))
			->select($db->quoteName('extension_id', 'e_id'))
			->from($db->quoteName('#__extensions'))
			->where($db->quoteName('type') . ' = ' . $db->quote('template'))
			->where($db->quoteName('enabled') . ' = 1')
			->order($db->quoteName('client_id') . ' ASC')
			->order($db->quoteName('name') . ' ASC');

		if ($clientId != '*')
		{
			$query->where($db->quoteName('client_id') . ' = ' . (int) $clientId);
		}

		$db->setQuery($query);
		$options = $db->loadObjectList();

		return $options;
	}

	/**
	 * TODO
	 *
	 * @param   string  $templateBaseDir  TODO
	 * @param   string  $templateDir      TODO
	 *
	 * @return  boolean|JObject
	 */
	public static function parseXMLTemplateFile($templateBaseDir, $templateDir)
	{
		$data = new JObject;

		// Check of the xml file exists
		$filePath = JPath::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml');

		if (is_file($filePath))
		{
			$xml = JInstaller::parseXMLInstallFile($filePath);

			if ($xml['type'] != 'template')
			{
				return false;
			}

			foreach ($xml as $key => $value)
			{
				$data->set($key, $value);
			}
		}

		return $data;
	}

	/**
	 * TODO
	 *
	 * @param   integer  $clientId     TODO
	 * @param   string   $templateDir  TODO
	 *
	 * @return  boolean|array
	 *
	 * @since   3.0
	 */
	public static function getPositions($clientId, $templateDir)
	{
		$positions = array();

		$templateBaseDir = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE;
		$filePath = JPath::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml');

		if (is_file($filePath))
		{
			// Read the file to see if it's a valid component XML file
			$xml = simplexml_load_file($filePath);

			if (!$xml)
			{
				return false;
			}

			// Check for a valid XML root tag.

			// Extensions use 'extension' as the root tag.  Languages use 'metafile' instead

			if ($xml->getName() != 'extension' && $xml->getName() != 'metafile')
			{
				unset($xml);

				return false;
			}

			$positions = (array) $xml->positions;

			if (isset($positions['position']))
			{
				$positions = (array) $positions['position'];
			}
			else
			{
				$positions = array();
			}
		}

		return $positions;
	}
}
PK;�!]Nj���
plugin.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyExportDomain', __DIR__ . '/export/domain.php');
JLoader::register('PrivacyExportField', __DIR__ . '/export/field.php');
JLoader::register('PrivacyExportItem', __DIR__ . '/export/item.php');
JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php');

/**
 * Base class for privacy plugins
 *
 * @since  3.9.0
 */
abstract class PrivacyPlugin extends JPlugin
{
	/**
	 * Database object
	 *
	 * @var    JDatabaseDriver
	 * @since  3.9.0
	 */
	protected $db;

	/**
	 * Affects constructor behaviour. If true, language files will be loaded automatically.
	 *
	 * @var    boolean
	 * @since  3.9.0
	 */
	protected $autoloadLanguage = true;

	/**
	 * Create a new domain object
	 *
	 * @param   string  $name         The domain's name
	 * @param   string  $description  The domain's description
	 *
	 * @return  PrivacyExportDomain
	 *
	 * @since   3.9.0
	 */
	protected function createDomain($name, $description = '')
	{
		$domain              = new PrivacyExportDomain;
		$domain->name        = $name;
		$domain->description = $description;

		return $domain;
	}

	/**
	 * Create an item object for an array
	 *
	 * @param   array         $data    The array data to convert
	 * @param   integer|null  $itemId  The ID of this item
	 *
	 * @return  PrivacyExportItem
	 *
	 * @since   3.9.0
	 */
	protected function createItemFromArray(array $data, $itemId = null)
	{
		$item = new PrivacyExportItem;
		$item->id = $itemId;

		foreach ($data as $key => $value)
		{
			if (is_object($value))
			{
				$value = (array) $value;
			}

			if (is_array($value))
			{
				$value = print_r($value, true);
			}

			$field        = new PrivacyExportField;
			$field->name  = $key;
			$field->value = $value;

			$item->addField($field);
		}

		return $item;
	}

	/**
	 * Create an item object for a JTable object
	 *
	 * @param   JTable  $table  The JTable object to convert
	 *
	 * @return  PrivacyExportItem
	 *
	 * @since   3.9.0
	 */
	protected function createItemForTable($table)
	{
		$data = array();

		foreach (array_keys($table->getFields()) as $fieldName)
		{
			$data[$fieldName] = $table->$fieldName;
		}

		return $this->createItemFromArray($data, $table->{$table->getKeyName(false)});
	}

	/**
	 * Helper function to create the domain for the items custom fields.
	 *
	 * @param   string  $context  The context
	 * @param   array   $items    The items
	 *
	 * @return  PrivacyExportDomain
	 *
	 * @since   3.9.0
	 */
	protected function createCustomFieldsDomain($context, $items = array())
	{
		if (!is_array($items))
		{
			$items = array($items);
		}

		$parts = FieldsHelper::extract($context);

		if (!$parts)
		{
			return array();
		}

		$type = str_replace('com_', '', $parts[0]);

		$domain = $this->createDomain($type . '_' . $parts[1] . '_custom_fields', 'joomla_' . $type . '_' . $parts[1] . '_custom_fields_data');

		foreach ($items as $item)
		{
			// Get item's fields, also preparing their value property for manual display
			$fields = FieldsHelper::getFields($parts[0] . '.' . $parts[1], $item);

			foreach ($fields as $field)
			{
				$fieldValue = is_array($field->value) ? implode(', ', $field->value) : $field->value;

				$data = array(
					$type . '_id' => $item->id,
					'field_name'  => $field->name,
					'field_title' => $field->title,
					'field_value' => $fieldValue,
				);

				$domain->addItem($this->createItemFromArray($data));
			}
		}

		return $domain;
	}
}
PK;�!]�P�export/domain.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyExportItem', __DIR__ . '/item.php');

/**
 * Data object representing all data contained in a domain.
 *
 * A domain is typically a single database table and the items within the domain are separate rows from the table.
 *
 * @since  3.9.0
 */
class PrivacyExportDomain
{
	/**
	 * The name of this domain
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $name;

	/**
	 * A short description of the data in this domain
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $description;

	/**
	 * The items belonging to this domain
	 *
	 * @var    PrivacyExportItem[]
	 * @since  3.9.0
	 */
	protected $items = array();

	/**
	 * Add an item to the domain
	 *
	 * @param   PrivacyExportItem  $item  The item to add
	 *
	 * @return  void
	 *
	 * @since  3.9.0
	 */
	public function addItem(PrivacyExportItem $item)
	{
		$this->items[] = $item;
	}

	/**
	 * Get the domain's items
	 *
	 * @return  PrivacyExportItem[]
	 *
	 * @since  3.9.0
	 */
	public function getItems()
	{
		return $this->items;
	}
}
PK;�!]�H8���export/item.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JLoader::register('PrivacyExportField', __DIR__ . '/field.php');

/**
 * Data object representing a single item within a domain.
 *
 * An item is typically a single row from a database table.
 *
 * @since  3.9.0
 */
class PrivacyExportItem
{
	/**
	 * The primary identifier of this item, typically the primary key for a database row.
	 *
	 * @var    integer
	 * @since  3.9.0
	 */
	public $id;

	/**
	 * The fields belonging to this item
	 *
	 * @var    PrivacyExportField[]
	 * @since  3.9.0
	 */
	protected $fields = array();

	/**
	 * Add a field to the item
	 *
	 * @param   PrivacyExportField  $field  The field to add
	 *
	 * @return  void
	 *
	 * @since  3.9.0
	 */
	public function addField(PrivacyExportField $field)
	{
		$this->fields[] = $field;
	}

	/**
	 * Get the item's fields
	 *
	 * @return  PrivacyExportField[]
	 *
	 * @since  3.9.0
	 */
	public function getFields()
	{
		return $this->fields;
	}
}
PK;�!]y��,,export/field.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Data object representing a field within an item.
 *
 * @since  3.9.0
 */
class PrivacyExportField
{
	/**
	 * The name of this field
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $name;

	/**
	 * The field's value
	 *
	 * @var    mixed
	 * @since  3.9.0
	 */
	public $value;
}
PK;�!]=*Nhtml/helper.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Privacy component HTML helper.
 *
 * @since  3.9.0
 */
class PrivacyHtmlHelper
{
	/**
	 * Render a status label
	 *
	 * @param   integer  $status  The item status
	 *
	 * @return  string
	 *
	 * @since   3.9.0
	 */
	public static function statusLabel($status)
	{
		switch ($status)
		{
			case 2:
				return '<span class="label label-success">' . JText::_('COM_PRIVACY_STATUS_COMPLETED') . '</span>';

			case 1:
				return '<span class="label label-info">' . JText::_('COM_PRIVACY_STATUS_CONFIRMED') . '</span>';

			case -1:
				return '<span class="label label-important">' . JText::_('COM_PRIVACY_STATUS_INVALID') . '</span>';

			default:
			case 0:
				return '<span class="label label-warning">' . JText::_('COM_PRIVACY_STATUS_PENDING') . '</span>';
		}
	}
}
PK;�!]�:�<<removal/status.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Data object communicating the status of whether the data for an information request can be removed.
 *
 * Typically, this object will only be used to communicate data will be removed.
 *
 * @since  3.9.0
 */
class PrivacyRemovalStatus
{
	/**
	 * Flag indicating the status reported by the plugin on whether the information can be removed
	 *
	 * @var    boolean
	 * @since  3.9.0
	 */
	public $canRemove = true;

	/**
	 * A status message indicating the reason data can or cannot be removed
	 *
	 * @var    string
	 * @since  3.9.0
	 */
	public $reason;
}
PK;�!]�7�privacy.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_privacy
 *
 * @copyright   (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\CMS\Factory;

/**
 * Privacy component helper.
 *
 * @since  3.9.0
 */
class PrivacyHelper extends JHelperContent
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   3.9.0
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('COM_PRIVACY_SUBMENU_DASHBOARD'),
			'index.php?option=com_privacy&view=dashboard',
			$vName === 'dashboard'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_PRIVACY_SUBMENU_REQUESTS'),
			'index.php?option=com_privacy&view=requests',
			$vName === 'requests'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_PRIVACY_SUBMENU_CAPABILITIES'),
			'index.php?option=com_privacy&view=capabilities',
			$vName === 'capabilities'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_PRIVACY_SUBMENU_CONSENTS'),
			'index.php?option=com_privacy&view=consents',
			$vName === 'consents'
		);
	}

	/**
	 * Render the data request as a XML document.
	 *
	 * @param   PrivacyExportDomain[]  $exportData  The data to be exported.
	 *
	 * @return  string
	 *
	 * @since   3.9.0
	 */
	public static function renderDataAsXml(array $exportData)
	{
		$export = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><data-export />');

		foreach ($exportData as $domain)
		{
			$xmlDomain = $export->addChild('domain');
			$xmlDomain->addAttribute('name', $domain->name);
			$xmlDomain->addAttribute('description', $domain->description);

			foreach ($domain->getItems() as $item)
			{
				$xmlItem = $xmlDomain->addChild('item');

				if ($item->id)
				{
					$xmlItem->addAttribute('id', $item->id);
				}

				foreach ($item->getFields() as $field)
				{
					$xmlItem->{$field->name} = $field->value;
				}
			}
		}

		$dom = new DOMDocument;
		$dom->loadXML($export->asXML());
		$dom->formatOutput = true;

		return $dom->saveXML();
	}

	/**
	 * Gets the privacyconsent system plugin extension id.
	 *
	 * @return  integer  The privacyconsent system plugin extension id.
	 *
	 * @since   3.9.2
	 */
	public static function getPrivacyConsentPluginId()
	{
		$db    = Factory::getDbo();
		$query = $db->getQuery(true)
			->select($db->quoteName('extension_id'))
			->from($db->quoteName('#__extensions'))
			->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
			->where($db->quoteName('element') . ' = ' . $db->quote('privacyconsent'));

		$db->setQuery($query);

		try
		{
			$result = (int) $db->loadResult();
		}
		catch (RuntimeException $e)
		{
			JError::raiseWarning(500, $e->getMessage());
		}

		return $result;
	}
}
PKP�!]F0fb11
html/xmap.phpnu&1i�<?php
/**
 * @version     $Id$
 * @copyright   Copyright (C) 2007 - 2009 Joomla! Vargas. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 * @author      Guillermo Vargas (guille@vargas.co.cr)
 */

// no direct access
defined('_JEXEC') or die;

JTable::addIncludePath( JPATH_COMPONENT . '/tables' );

/**
 * @package       Xmap
 * @subpackage    com_xmap
 */
abstract class JHtmlXmap
{

    /**
     * @param    string  $name
     * @param    string  $value
     * @param    int     $j
     */
    public static function priorities($name, $value = '0.5', $j)
    {
        // Array of options
        for ($i=0.1; $i<=1;$i+=0.1) {
            $options[] = JHTML::_('select.option',$i,$i);;
        }
        return JHtml::_('select.genericlist', $options, $name, null, 'value', 'text', $value, $name.$j);
    }

    /**
     * @param    string  $name
     * @param    string  $value
     * @param    int     $j
     */
    public static function changefrequency($name, $value = 'weekly', $j)
    {
        // Array of options
        $options[] = JHTML::_('select.option','hourly','hourly');
        $options[] = JHTML::_('select.option','daily','daily');
        $options[] = JHTML::_('select.option','weekly','weekly');
        $options[] = JHTML::_('select.option','monthly','monthly');
        $options[] = JHTML::_('select.option','yearly','yearly');
        $options[] = JHTML::_('select.option','never','never');
        return JHtml::_('select.genericlist', $options, $name, null, 'value', 'text', $value, $name.$j);
    }

}
PK��!]6�yC��
installer.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_installer
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Installer helper.
 *
 * @since  1.6
 */
class InstallerHelper
{
	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 */
	public static function addSubmenu($vName = 'install')
	{
		if (JFactory::getUser()->authorise('core.admin'))
		{
			JHtmlSidebar::addEntry(
				JText::_('COM_INSTALLER_SUBMENU_INSTALL'),
				'index.php?option=com_installer&view=install',
				$vName == 'install'
			);
		}
		JHtmlSidebar::addEntry(
			JText::_('COM_INSTALLER_SUBMENU_UPDATE'),
			'index.php?option=com_installer&view=update',
			$vName == 'update'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_INSTALLER_SUBMENU_MANAGE'),
			'index.php?option=com_installer&view=manage',
			$vName == 'manage'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_INSTALLER_SUBMENU_DISCOVER'),
			'index.php?option=com_installer&view=discover',
			$vName == 'discover'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_INSTALLER_SUBMENU_DATABASE'),
			'index.php?option=com_installer&view=database',
			$vName == 'database'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_INSTALLER_SUBMENU_WARNINGS'),
			'index.php?option=com_installer&view=warnings',
			$vName == 'warnings'
		);

		if (JFactory::getUser()->authorise('core.admin'))
		{
			JHtmlSidebar::addEntry(
				JText::_('COM_INSTALLER_SUBMENU_LANGUAGES'),
				'index.php?option=com_installer&view=languages',
				$vName == 'languages'
			);
		}

		JHtmlSidebar::addEntry(
			JText::_('COM_INSTALLER_SUBMENU_UPDATESITES'),
			'index.php?option=com_installer&view=updatesites',
			$vName == 'updatesites'
		);
	}

	/**
	 * Get a list of filter options for the extension types.
	 *
	 * @return  array  An array of stdClass objects.
	 *
	 * @since   3.0
	 */
	public static function getExtensionTypes()
	{
		$db    = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('DISTINCT type')
			->from('#__extensions');
		$db->setQuery($query);
		$types = $db->loadColumn();

		$options = array();

		foreach ($types as $type)
		{
			$options[] = JHtml::_('select.option', $type, JText::_('COM_INSTALLER_TYPE_' . strtoupper($type)));
		}

		return $options;
	}

	/**
	 * Get a list of filter options for the extension types.
	 *
	 * @return  array  An array of stdClass objects.
	 *
	 * @since   3.0
	 */
	public static function getExtensionGroupes()
	{
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('DISTINCT folder')
			->from('#__extensions')
			->where('folder != ' . $db->quote(''))
			->order('folder');
		$db->setQuery($query);
		$folders = $db->loadColumn();

		$options = array();

		foreach ($folders as $folder)
		{
			$options[] = JHtml::_('select.option', $folder, $folder);
		}

		return $options;
	}

	/**
	 * Gets a list of the actions that can be performed.
	 *
	 * @return  JObject
	 *
	 * @since   1.6
	 * @deprecated  3.2  Use JHelperContent::getActions() instead
	 */
	public static function getActions()
	{
		// Log usage of deprecated function
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		// Get list of actions
		return JHelperContent::getActions('com_installer');
	}

	/**
	 * Get a list of filter options for the application clients.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   3.5
	 */
	public static function getClientOptions()
	{
		// Build the filter options.
		$options   = array();
		$options[] = JHtml::_('select.option', '0', JText::_('JSITE'));
		$options[] = JHtml::_('select.option', '1', JText::_('JADMINISTRATOR'));

		return $options;
	}

	/**
	 * Get a list of filter options for the application statuses.
	 *
	 * @return  array  An array of JHtmlOption elements.
	 *
	 * @since   3.5
	 */
	public static function getStateOptions()
	{
		// Build the filter options.
		$options   = array();
		$options[] = JHtml::_('select.option', '0', JText::_('JDISABLED'));
		$options[] = JHtml::_('select.option', '1', JText::_('JENABLED'));
		$options[] = JHtml::_('select.option', '2', JText::_('JPROTECTED'));
		$options[] = JHtml::_('select.option', '3', JText::_('JUNPROTECTED'));

		return $options;
	}
}
PK��!]�'�a��html/manage.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_installer
 *
 * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Installer HTML class.
 *
 * @since  2.5
 */
abstract class InstallerHtmlManage
{
	/**
	 * Returns a published state on a grid.
	 *
	 * @param   integer  $value     The state value.
	 * @param   integer  $i         The row index.
	 * @param   boolean  $enabled   An optional setting for access control on the action.
	 * @param   string   $checkbox  An optional prefix for checkboxes.
	 *
	 * @return  string        The Html code
	 *
	 * @see JHtmlJGrid::state
	 *
	 * @since   2.5
	 */
	public static function state($value, $i, $enabled = true, $checkbox = 'cb')
	{
		$states = array(
			2 => array(
				'',
				'COM_INSTALLER_EXTENSION_PROTECTED',
				'',
				'COM_INSTALLER_EXTENSION_PROTECTED',
				true,
				'protected',
				'protected',
			),
			1 => array(
				'unpublish',
				'COM_INSTALLER_EXTENSION_ENABLED',
				'COM_INSTALLER_EXTENSION_DISABLE',
				'COM_INSTALLER_EXTENSION_ENABLED',
				true,
				'publish',
				'publish',
			),
			0 => array(
				'publish',
				'COM_INSTALLER_EXTENSION_DISABLED',
				'COM_INSTALLER_EXTENSION_ENABLE',
				'COM_INSTALLER_EXTENSION_DISABLED',
				true,
				'unpublish',
				'unpublish',
			),
		);

		return JHtml::_('jgrid.state', $states, $value, $i, 'manage.', $enabled, true, $checkbox);
	}
}
PK��!]�3��YYhtml/updatesites.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_installer
 *
 * @copyright   (C) 2015 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Installer HTML class.
 *
 * @since  3.5
 */
abstract class InstallerHtmlUpdatesites
{
	/**
	 * Returns a published state on a grid.
	 *
	 * @param   integer  $value     The state value.
	 * @param   integer  $i         The row index.
	 * @param   boolean  $enabled   An optional setting for access control on the action.
	 * @param   string   $checkbox  An optional prefix for checkboxes.
	 *
	 * @return  string   The HTML code
	 *
	 * @see     JHtmlJGrid::state()
	 * @since   3.5
	 */
	public static function state($value, $i, $enabled = true, $checkbox = 'cb')
	{
		$states	= array(
			1 => array(
				'unpublish',
				'COM_INSTALLER_UPDATESITE_ENABLED',
				'COM_INSTALLER_UPDATESITE_DISABLE',
				'COM_INSTALLER_UPDATESITE_ENABLED',
				true,
				'publish',
				'publish',
			),
			0 => array(
				'publish',
				'COM_INSTALLER_UPDATESITE_DISABLED',
				'COM_INSTALLER_UPDATESITE_ENABLE',
				'COM_INSTALLER_UPDATESITE_DISABLED',
				true,
				'unpublish',
				'unpublish',
			),
		);

		return JHtml::_('jgrid.state', $states, $value, $i, 'updatesites.', $enabled, true, $checkbox);
	}
}
PK5�!]J6XXencrypt/aes.phpnu&1i�<?php
/**
 * @copyright Copyright (c)2009-2013 Nicholas K. Dionysopoulos
 * @license GNU General Public License version 3, or later
 *
 * @since 2.4
 */

// Protection against direct access
\defined('_JEXEC') or die;

/**
 * AES implementation in PHP (c) Chris Veness 2005-2013.
 * Right to use and adapt is granted for under a simple creative commons attribution
 * licence. No warranty of any form is offered.
 *
 * Modified for Akeeba Backup by Nicholas K. Dionysopoulos
 * Included for JCE with the kind permission of Nicholas K. Dionysopoulos
 */
class WFUtilEncrypt
{
    // Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [�5.1.1]
    protected static $Sbox =
             array(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
                   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
                   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
                   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
                   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
                   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
                   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
                   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
                   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
                   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
                   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
                   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
                   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
                   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
                   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
                   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, );

    // Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [�5.2]
    protected static $Rcon = array(
                   array(0x00, 0x00, 0x00, 0x00),
                   array(0x01, 0x00, 0x00, 0x00),
                   array(0x02, 0x00, 0x00, 0x00),
                   array(0x04, 0x00, 0x00, 0x00),
                   array(0x08, 0x00, 0x00, 0x00),
                   array(0x10, 0x00, 0x00, 0x00),
                   array(0x20, 0x00, 0x00, 0x00),
                   array(0x40, 0x00, 0x00, 0x00),
                   array(0x80, 0x00, 0x00, 0x00),
                   array(0x1b, 0x00, 0x00, 0x00),
                   array(0x36, 0x00, 0x00, 0x00), );

    protected static $passwords = array();

    /**
     * AES Cipher function: encrypt 'input' with Rijndael algorithm.
     *
     * @param input message as byte-array (16 bytes)
     * @param w     key schedule as 2D byte-array (Nr+1 x Nb bytes) -
     *              generated from the cipher key by KeyExpansion()
     *
     * @return ciphertext as byte-array (16 bytes)
     */
    public static function Cipher($input, $w)
    {    // main Cipher function [�5.1]
      $Nb = 4;                 // block size (in words): no of columns in state (fixed at 4 for AES)
      $Nr = count($w) / $Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys

      $state = array();  // initialise 4xNb byte-array 'state' with input [�3.4]
      for ($i = 0; $i < 4 * $Nb; ++$i) {
          $state[$i % 4][floor($i / 4)] = $input[$i];
      }

        $state = self::AddRoundKey($state, $w, 0, $Nb);

        for ($round = 1; $round < $Nr; ++$round) {  // apply Nr rounds
        $state = self::SubBytes($state, $Nb);
            $state = self::ShiftRows($state, $Nb);
            $state = self::MixColumns($state, $Nb);
            $state = self::AddRoundKey($state, $w, $round, $Nb);
        }

        $state = self::SubBytes($state, $Nb);
        $state = self::ShiftRows($state, $Nb);
        $state = self::AddRoundKey($state, $w, $Nr, $Nb);

        $output = array(4 * $Nb);  // convert state to 1-d array before returning [�3.4]
      for ($i = 0; $i < 4 * $Nb; ++$i) {
          $output[$i] = $state[$i % 4][floor($i / 4)];
      }

        return $output;
    }

    protected static function AddRoundKey($state, $w, $rnd, $Nb)
    {  // xor Round Key into state S [�5.1.4]
      for ($r = 0; $r < 4; ++$r) {
          for ($c = 0; $c < $Nb; ++$c) {
              $state[$r][$c] ^= $w[$rnd * 4 + $c][$r];
          }
      }

        return $state;
    }

    protected static function SubBytes($s, $Nb)
    {    // apply SBox to state S [�5.1.1]
      for ($r = 0; $r < 4; ++$r) {
          for ($c = 0; $c < $Nb; ++$c) {
              $s[$r][$c] = self::$Sbox[$s[$r][$c]];
          }
      }

        return $s;
    }

    protected static function ShiftRows($s, $Nb)
    {    // shift row r of state S left by r bytes [�5.1.2]
      $t = array(4);
        for ($r = 1; $r < 4; ++$r) {
            for ($c = 0; $c < 4; ++$c) {
                $t[$c] = $s[$r][($c + $r) % $Nb];
            }  // shift into temp copy
        for ($c = 0; $c < 4; ++$c) {
            $s[$r][$c] = $t[$c];
        }         // and copy back
        }          // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
      return $s;  // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
    }

    protected static function MixColumns($s, $Nb)
    {   // combine bytes of each col of state S [�5.1.3]
      for ($c = 0; $c < 4; ++$c) {
          $a = array(4);  // 'a' is a copy of the current column from 's'
        $b = array(4);  // 'b' is a�{02} in GF(2^8)
        for ($i = 0; $i < 4; ++$i) {
            $a[$i] = $s[$i][$c];
            $b[$i] = $s[$i][$c] & 0x80 ? $s[$i][$c] << 1 ^ 0x011b : $s[$i][$c] << 1;
        }
        // a[n] ^ b[n] is a�{03} in GF(2^8)
        $s[0][$c] = $b[0] ^ $a[1] ^ $b[1] ^ $a[2] ^ $a[3]; // 2*a0 + 3*a1 + a2 + a3
        $s[1][$c] = $a[0] ^ $b[1] ^ $a[2] ^ $b[2] ^ $a[3]; // a0 * 2*a1 + 3*a2 + a3
        $s[2][$c] = $a[0] ^ $a[1] ^ $b[2] ^ $a[3] ^ $b[3]; // a0 + a1 + 2*a2 + 3*a3
        $s[3][$c] = $a[0] ^ $b[0] ^ $a[1] ^ $a[2] ^ $b[3]; // 3*a0 + a1 + a2 + 2*a3
      }

        return $s;
    }

    /**
     * Key expansion for Rijndael Cipher(): performs key expansion on cipher key
     * to generate a key schedule.
     *
     * @param key cipher key byte-array (16 bytes)
     *
     * @return key schedule as 2D byte-array (Nr+1 x Nb bytes)
     */
    public static function KeyExpansion($key)
    {  // generate Key Schedule from Cipher Key [�5.2]
      $Nb = 4;              // block size (in words): no of columns in state (fixed at 4 for AES)
      $Nk = count($key) / 4;  // key length (in words): 4/6/8 for 128/192/256-bit keys
      $Nr = $Nk + 6;        // no of rounds: 10/12/14 for 128/192/256-bit keys

      $w = array();
        $temp = array();

        for ($i = 0; $i < $Nk; ++$i) {
            $r = array($key[4 * $i], $key[4 * $i + 1], $key[4 * $i + 2], $key[4 * $i + 3]);
            $w[$i] = $r;
        }

        for ($i = $Nk; $i < ($Nb * ($Nr + 1)); ++$i) {
            $w[$i] = array();
            for ($t = 0; $t < 4; ++$t) {
                $temp[$t] = $w[$i - 1][$t];
            }
            if ($i % $Nk == 0) {
                $temp = self::SubWord(self::RotWord($temp));
                for ($t = 0; $t < 4; ++$t) {
                    $temp[$t] ^= self::$Rcon[$i / $Nk][$t];
                }
            } elseif ($Nk > 6 && $i % $Nk == 4) {
                $temp = self::SubWord($temp);
            }
            for ($t = 0; $t < 4; ++$t) {
                $w[$i][$t] = $w[$i - $Nk][$t] ^ $temp[$t];
            }
        }

        return $w;
    }

    protected static function SubWord($w)
    {    // apply SBox to 4-byte word w
      for ($i = 0; $i < 4; ++$i) {
          $w[$i] = self::$Sbox[$w[$i]];
      }

        return $w;
    }

    protected static function RotWord($w)
    {    // rotate 4-byte word w left by one byte
      $tmp = $w[0];
        for ($i = 0; $i < 3; ++$i) {
            $w[$i] = $w[$i + 1];
        }
        $w[3] = $tmp;

        return $w;
    }

    /*
     * Unsigned right shift function, since PHP has neither >>> operator nor unsigned ints
     *
     * @param a  number to be shifted (32-bit integer)
     * @param b  number of bits to shift a to the right (0..31)
     * @return   a right-shifted and zero-filled by b bits
     */
    protected static function urs($a, $b)
    {
        $a &= 0xffffffff;
        $b &= 0x1f;  // (bounds check)
      if ($a & 0x80000000 && $b > 0) {   // if left-most bit set
        $a = ($a >> 1) & 0x7fffffff;   //   right-shift one bit & clear left-most bit
        $a = $a >> ($b - 1);           //   remaining right-shifts
      } else {                       // otherwise
        $a = ($a >> $b);               //   use normal right-shift
      }

        return $a;
    }

    /**
     * Encrypt a text using AES encryption in Counter mode of operation
     *  - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf.
     *
     * Unicode multi-byte character safe
     *
     * @param plaintext source text to be encrypted
     * @param password  the password to use to generate a key
     * @param nBits     number of bits to be used in the key (128, 192, or 256)
     *
     * @return encrypted text
     */
    public static function AESEncryptCtr($plaintext, $password, $nBits)
    {
        $blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
      if (!($nBits == 128 || $nBits == 192 || $nBits == 256)) {
          return '';
      }  // standard allows 128/192/256 bit keys
      // note PHP (5) gives us plaintext and password in UTF8 encoding!

      // use AES itself to encrypt password to get cipher key (using plain password as source for
      // key expansion) - gives us well encrypted key
      $nBytes = $nBits / 8;  // no bytes in key
      $pwBytes = array();
        for ($i = 0; $i < $nBytes; ++$i) {
            $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff;
        }
        $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes));
        $key = array_merge($key, array_slice($key, 0, $nBytes - 16));  // expand key to 16/24/32 bytes long

      // initialise counter block (NIST SP800-38A �B.2): millisecond time-stamp for nonce in
      // 1st 8 bytes, block counter in 2nd 8 bytes
      $counterBlock = array();
        $nonce = floor(microtime(true) * 1000);   // timestamp: milliseconds since 1-Jan-1970
      $nonceSec = floor($nonce / 1000);
        $nonceMs = $nonce % 1000;
      // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes
      for ($i = 0; $i < 4; ++$i) {
          $counterBlock[$i] = self::urs($nonceSec, $i * 8) & 0xff;
      }
        for ($i = 0; $i < 4; ++$i) {
            $counterBlock[$i + 4] = $nonceMs & 0xff;
        }
      // and convert it to a string to go on the front of the ciphertext
      $ctrTxt = '';
        for ($i = 0; $i < 8; ++$i) {
            $ctrTxt .= chr($counterBlock[$i]);
        }

      // generate key schedule - an expansion of the key into distinct Key Rounds for each round
      $keySchedule = self::KeyExpansion($key);

        $blockCount = ceil(strlen($plaintext) / $blockSize);
        $ciphertxt = array();  // ciphertext as array of strings

      for ($b = 0; $b < $blockCount; ++$b) {
          // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
        // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
        for ($c = 0; $c < 4; ++$c) {
            $counterBlock[15 - $c] = self::urs($b, $c * 8) & 0xff;
        }
          for ($c = 0; $c < 4; ++$c) {
              $counterBlock[15 - $c - 4] = self::urs($b / 0x100000000, $c * 8);
          }

          $cipherCntr = self::Cipher($counterBlock, $keySchedule);  // -- encrypt counter block --

        // block size is reduced on final block
        $blockLength = $b < $blockCount - 1 ? $blockSize : (strlen($plaintext) - 1) % $blockSize + 1;
          $cipherByte = array();

          for ($i = 0; $i < $blockLength; ++$i) {  // -- xor plaintext with ciphered counter byte-by-byte --
          $cipherByte[$i] = $cipherCntr[$i] ^ ord(substr($plaintext, $b * $blockSize + $i, 1));
              $cipherByte[$i] = chr($cipherByte[$i]);
          }
          $ciphertxt[$b] = implode('', $cipherByte);  // escape troublesome characters in ciphertext
      }

      // implode is more efficient than repeated string concatenation
      $ciphertext = $ctrTxt.implode('', $ciphertxt);
        $ciphertext = base64_encode($ciphertext);

        return $ciphertext;
    }

    /**
     * Decrypt a text encrypted by AES in counter mode of operation.
     *
     * @param ciphertext source text to be decrypted
     * @param password   the password to use to generate a key
     * @param nBits      number of bits to be used in the key (128, 192, or 256)
     *
     * @return decrypted text
     */
    public static function AESDecryptCtr($ciphertext, $password, $nBits)
    {
        $blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
      if (!($nBits == 128 || $nBits == 192 || $nBits == 256)) {
          return '';
      }  // standard allows 128/192/256 bit keys
      $ciphertext = base64_decode($ciphertext);

      // use AES to encrypt password (mirroring encrypt routine)
      $nBytes = $nBits / 8;  // no bytes in key
      $pwBytes = array();
        for ($i = 0; $i < $nBytes; ++$i) {
            $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff;
        }
        $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes));
        $key = array_merge($key, array_slice($key, 0, $nBytes - 16));  // expand key to 16/24/32 bytes long

      // recover nonce from 1st element of ciphertext
      $counterBlock = array();
        $ctrTxt = substr($ciphertext, 0, 8);
        for ($i = 0; $i < 8; ++$i) {
            $counterBlock[$i] = ord(substr($ctrTxt, $i, 1));
        }

      // generate key schedule
      $keySchedule = self::KeyExpansion($key);

      // separate ciphertext into blocks (skipping past initial 8 bytes)
      $nBlocks = ceil((strlen($ciphertext) - 8) / $blockSize);
        $ct = array();
        for ($b = 0; $b < $nBlocks; ++$b) {
            $ct[$b] = substr($ciphertext, 8 + $b * $blockSize, 16);
        }
        $ciphertext = $ct;  // ciphertext is now array of block-length strings

      // plaintext will get generated block-by-block into array of block-length strings
      $plaintxt = array();

        for ($b = 0; $b < $nBlocks; ++$b) {
            // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
        for ($c = 0; $c < 4; ++$c) {
            $counterBlock[15 - $c] = self::urs($b, $c * 8) & 0xff;
        }
            for ($c = 0; $c < 4; ++$c) {
                $counterBlock[15 - $c - 4] = self::urs(($b + 1) / 0x100000000 - 1, $c * 8) & 0xff;
            }

            $cipherCntr = self::Cipher($counterBlock, $keySchedule);  // encrypt counter block

        $plaintxtByte = array();
            for ($i = 0; $i < strlen($ciphertext[$b]); ++$i) {
                // -- xor plaintext with ciphered counter byte-by-byte --
          $plaintxtByte[$i] = $cipherCntr[$i] ^ ord(substr($ciphertext[$b], $i, 1));
                $plaintxtByte[$i] = chr($plaintxtByte[$i]);
            }
            $plaintxt[$b] = implode('', $plaintxtByte);
        }

      // join array of blocks into single plaintext string
      $plaintext = implode('', $plaintxt);

        return $plaintext;
    }

    /**
     * AES encryption in CBC mode. This is the standard mode (the CTR methods
     * actually use Rijndael-128 in CTR mode, which - technically - isn't AES).
     * The data length is tucked as a 32-bit unsigned integer (little endian)
     * after the ciphertext. It supports AES-128, AES-192 and AES-256.
     *
     * @since 3.0.1
     *
     * @author Nicholas K. Dionysopoulos
     *
     * @param string $plaintext The data to encrypt
     * @param string $password  Encryption password
     * @param int    $nBits     Encryption key size. Can be 128, 192 or 256
     *
     * @return string The ciphertext
     */
    public static function AESEncryptCBC($plaintext, $password, $nBits = 128)
    {
        if (!($nBits == 128 || $nBits == 192 || $nBits == 256)) {
            return false;
        }  // standard allows 128/192/256 bit keys
        if (!function_exists('mcrypt_module_open')) {
            return false;
        }

            // Try to fetch cached key/iv or create them if they do not exist
        $lookupKey = $password.'-'.$nBits;
        if (array_key_exists($lookupKey, self::$passwords)) {
            $key = self::$passwords[$lookupKey]['key'];
            $iv = self::$passwords[$lookupKey]['iv'];
        } else {
            // use AES itself to encrypt password to get cipher key (using plain password as source for
            // key expansion) - gives us well encrypted key
            $nBytes = $nBits / 8;  // no bytes in key
            $pwBytes = array();
            for ($i = 0; $i < $nBytes; ++$i) {
                $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff;
            }
            $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes));
            $key = array_merge($key, array_slice($key, 0, $nBytes - 16));  // expand key to 16/24/32 bytes long
            $newKey = '';
            foreach ($key as $int) {
                $newKey .= chr($int);
            }
            $key = $newKey;

            // Create an Initialization Vector (IV) based on the password, using the same technique as for the key
            $nBytes = 16;  // AES uses a 128 -bit (16 byte) block size, hence the IV size is always 16 bytes
            $pwBytes = array();
            for ($i = 0; $i < $nBytes; ++$i) {
                $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff;
            }
            $iv = self::Cipher($pwBytes, self::KeyExpansion($pwBytes));
            $newIV = '';
            foreach ($iv as $int) {
                $newIV .= chr($int);
            }
            $iv = $newIV;

            self::$passwords[$lookupKey]['key'] = $key;
            self::$passwords[$lookupKey]['iv'] = $iv;
        }

        $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
        mcrypt_generic_init($td, $key, $iv);
        $ciphertext = mcrypt_generic($td, $plaintext);
        mcrypt_generic_deinit($td);

        $ciphertext .= pack('V', strlen($plaintext));

        return $ciphertext;
    }

    /**
     * AES decryption in CBC mode. This is the standard mode (the CTR methods
     * actually use Rijndael-128 in CTR mode, which - technically - isn't AES).
     *
     * Supports AES-128, AES-192 and AES-256. It supposes that the last 4 bytes
     * contained a little-endian unsigned long integer representing the unpadded
     * data length.
     *
     * @since 3.0.1
     *
     * @author Nicholas K. Dionysopoulos
     *
     * @param string $ciphertext The data to encrypt
     * @param string $password   Encryption password
     * @param int    $nBits      Encryption key size. Can be 128, 192 or 256
     *
     * @return string The plaintext
     */
    public static function AESDecryptCBC($ciphertext, $password, $nBits = 128)
    {
        if (!($nBits == 128 || $nBits == 192 || $nBits == 256)) {
            return false;
        }  // standard allows 128/192/256 bit keys
        if (!function_exists('mcrypt_module_open')) {
            return false;
        }

        // Try to fetch cached key/iv or create them if they do not exist
        $lookupKey = $password.'-'.$nBits;
        if (array_key_exists($lookupKey, self::$passwords)) {
            $key = self::$passwords[$lookupKey]['key'];
            $iv = self::$passwords[$lookupKey]['iv'];
        } else {
            // use AES itself to encrypt password to get cipher key (using plain password as source for
            // key expansion) - gives us well encrypted key
            $nBytes = $nBits / 8;  // no bytes in key
            $pwBytes = array();
            for ($i = 0; $i < $nBytes; ++$i) {
                $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff;
            }
            $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes));
            $key = array_merge($key, array_slice($key, 0, $nBytes - 16));  // expand key to 16/24/32 bytes long
            $newKey = '';
            foreach ($key as $int) {
                $newKey .= chr($int);
            }
            $key = $newKey;

            // Create an Initialization Vector (IV) based on the password, using the same technique as for the key
            $nBytes = 16;  // AES uses a 128 -bit (16 byte) block size, hence the IV size is always 16 bytes
            $pwBytes = array();
            for ($i = 0; $i < $nBytes; ++$i) {
                $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff;
            }
            $iv = self::Cipher($pwBytes, self::KeyExpansion($pwBytes));
            $newIV = '';
            foreach ($iv as $int) {
                $newIV .= chr($int);
            }
            $iv = $newIV;

            self::$passwords[$lookupKey]['key'] = $key;
            self::$passwords[$lookupKey]['iv'] = $iv;
        }

        // Read the data size
        $data_size = unpack('V', substr($ciphertext, -4));

        // Decrypt
        $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
        mcrypt_generic_init($td, $key, $iv);
        $plaintext = mdecrypt_generic($td, substr($ciphertext, 0, -4));
        mcrypt_generic_deinit($td);

        // Trim padding, if necessary
        if (strlen($plaintext) > $data_size) {
            $plaintext = substr($plaintext, 0, $data_size);
        }

        return $plaintext;
    }
}
PK5�!]t�3Ɨ%�%plugins.jsonnu&1i�{
    "article": {
        "title": "WF_ARTICLE_TITLE",
        "description": "WF_ARTICLE_DESC",
        "icon": "readmore,pagebreak",
        "editable": 1,
        "row": 4,
        "core": 1
    },
    "anchor": {
        "title": "WF_ANCHOR_TITLE",
        "description": "WF_ANCHOR_DESC",
        "core": 1,
        "icon": "anchor",
        "row": 4,
        "editable": 0
    },
    "attributes": {
        "title": "WF_ATTRIBUTES_TITLE",
        "description": "WF_ATTRIBUTES_DESC",
        "icon": "attribs",
        "editable": 0,
        "row": 4,
        "core": 1
    },
    "autosave": {
        "title": "WF_AUTOSAVE_TITLE",
        "description": "WF_AUTOSAVE_DESC",
        "icon": "autosave",
        "editable": 1,
        "row": 4,
        "core": 1
    },
    "browser": {
        "title": "WF_BROWSER_TITLE",
        "description": "WF_BROWSER_DESC",
        "icon": "",
        "editable": 1,
        "row": 0,
        "core": 1,
        "checksum": "${checksum:browser}"
    },
    "charmap": {
        "title": "WF_CHARMAP_TITLE",
        "description": "WF_CHARMAP_DESC",
        "icon": "charmap",
        "editable": 1,
        "row": 2,
        "core": 1
    },
    "cleanup": {
        "title": "WF_CLEANUP_TITLE",
        "description": "WF_CLEANUP_DESC",
        "icon": "cleanup",
        "editable": 0,
        "row": 1,
        "core": 1
    },
    "clipboard": {
        "title": "WF_CLIPBOARD_TITLE",
        "description": "WF_CLIPBOARD_DESC",
        "icon": "cut,copy,paste,pastetext",
        "editable": 1,
        "row": 2,
        "core": 1
    },
    "code": {
        "title": "WF_CODE_TITLE",
        "description": "WF_CODE_DESC",
        "icon": "",
        "editable": 0,
        "row": 0,
        "core": 1
    },
    "colorpicker": {
        "title": "WF_COLORPICKER_TITLE",
        "description": "WF_COLORPICKER_DESC",
        "icon": "",
        "editable": 0,
        "row": 0,
        "core": 1,
        "checksum": "${checksum:colorpicker}"
    },
    "contextmenu": {
        "title": "WF_CONTEXTMENU_TITLE",
        "description": "WF_CONTEXTMENU_DESC",
        "icon": "",
        "editable": 1,
        "row": 0,
        "core": 1
    },
    "directionality": {
        "title": "WF_DIRECTIONALITY_TITLE",
        "description": "WF_DIRECTIONALITY_DESC",
        "icon": "ltr,rtl",
        "editable": 0,
        "row": 3,
        "core": 1
    },
    "format": {
        "title": "WF_FORMAT_TITLE",
        "description": "WF_FORMAT_DESC",
        "icon": "",
        "editable": 0,
        "row": 0,
        "core": 1,
        "class": "list-box"
    },
    "formatselect": {
        "title": "WF_FORMATSELECT_TITLE",
        "description": "WF_FORMATSELECT_DESC",
        "core": 1,
        "icon": "formatselect",
        "row": 1,
        "editable": 1,
        "class": "list-box"
    },
    "fontcolor": {
        "title": "WF_FONTCOLOR_TITLE",
        "description": "WF_FONTCOLOR_DESC",
        "core": 1,
        "icon": "forecolor,backcolor",
        "row": 2,
        "editable": 1,
        "class": "split-button"
    },
    "fontselect": {
        "title": "WF_FONTSELECT_TITLE",
        "description": "WF_FONTSELECT_DESC",
        "core": 1,
        "icon": "fontselect",
        "row": 2,
        "editable": 1,
        "class": "list-box"
    },
    "fontsizeselect": {
        "title": "WF_FONTSIZESELECT_TITLE",
        "description": "WF_FONTSIZESELECT_DESC",
        "core": 1,
        "icon": "fontsizeselect",
        "row": 2,
        "editable": 1,
        "class": "list-box"
    },
    "fullscreen": {
        "title": "WF_FULLSCREEN_TITLE",
        "description": "WF_FULLSCREEN_DESC",
        "icon": "fullscreen",
        "editable": 0,
        "row": 3,
        "core": 1
    },
    "help": {
        "title": "WF_HELP_TITLE",
        "description": "WF_HELP_DESC",
        "icon": "help",
        "editable": 0,
        "row": 1,
        "core": 1,
        "checksum": "${checksum:help}"
    },
    "imgmanager": {
        "title": "WF_IMGMANAGER_TITLE",
        "description": "WF_IMGMANAGER_DESC",
        "icon": "imgmanager",
        "editable": 1,
        "row": 4,
        "core": 1,
        "checksum": "${checksum:imgmanager}"
    },
    "joomla": {
        "title": "WF_JOOMLABUTTONS_TITLE",
        "description": "WF_JOOMLABUTTONS_DESC",
        "icon": "joomla",
        "editable": 0,
        "row": 4,
        "core": 1,
        "class": "split-button"
    },
    "langcode": {
        "title": "WF_LANGCODE_TITLE",
        "description": "WF_LANGCODE_DESC",
        "icon": "langcode",
        "editable": 0,
        "row": 4,
        "core": 1
    },
    "layer": {
        "title": "WF_LAYER_TITLE",
        "description": "WF_LAYER_DESC",
        "icon": "insertlayer,layerforward,layerbackward,layerabsolute",
        "editable": 0,
        "row": 4,
        "core": 1
    },
    "link": {
        "title": "WF_LINK_TITLE",
        "description": "WF_LINK_DESC",
        "icon": "link",
        "editable": 1,
        "row": 4,
        "core": 1,
        "class": "split-button",
        "checksum": "${checksum:link}"
    },
    "lists": {
        "title": "WF_LISTS_TITLE",
        "description": "WF_LISTS_DESC",
        "icon": "numlist,bullist",
        "editable": 1,
        "row": 2,
        "core": 1,
        "class": "split-button"
    },
    "media": {
        "title": "WF_MEDIA_TITLE",
        "description": "WF_MEDIA_DESC",
        "icon": "",
        "editable": 1,
        "row": 0,
        "core": 1
    },
    "nonbreaking": {
        "title": "WF_NONBREAKING_TITLE",
        "description": "WF_NONBREAKING_DESC",
        "icon": "nonbreaking",
        "editable": 0,
        "row": 4,
        "core": 1
    },
    "noneditable": {
        "title": "WF_NONEDITABLE_TITLE",
        "description": "WF_NONEDITABLE_DESC",
        "icon": "",
        "editable": 0,
        "row": 0,
        "core": 1
    },
    "preview": {
        "title": "WF_PREVIEW_TITLE",
        "description": "WF_PREVIEW_DESC",
        "icon": "",
        "editable": 1,
        "row": 0,
        "core": 1,
        "checksum": "${checksum:preview}"
    },
    "print": {
        "title": "WF_PRINT_TITLE",
        "description": "WF_PRINT_DESC",
        "icon": "print",
        "editable": 0,
        "row": 3,
        "core": 1
    },
    "searchreplace": {
        "title": "WF_SEARCHREPLACE_TITLE",
        "description": "WF_SEARCHREPLACE_DESC",
        "icon": "search",
        "editable": 0,
        "row": 2,
        "core": 1
    },
    "source": {
        "title": "WF_SOURCE_TITLE",
        "description": "WF_SOURCE_DESC",
        "icon": "",
        "editable": 1,
        "row": 0,
        "core": 1
    },
    "spellchecker": {
        "title": "WF_SPELLCHECKER_TITLE",
        "description": "WF_SPELLCHECKER_DESC",
        "icon": "spellchecker",
        "editable": 1,
        "row": 4,
        "core": 1,
        "checksum": "${checksum:spellchecker}"
    },
    "style": {
        "title": "WF_STYLE_TITLE",
        "description": "WF_STYLE_DESC",
        "icon": "style",
        "editable": 0,
        "row": 4,
        "core": 1,
        "checksum": "${checksum:style}"
    },
    "styleselect": {
        "title": "WF_STYLESELECT_TITLE",
        "description": "WF_STYLESELECT_DESC",
        "core": 1,
        "icon": "styleselect",
        "row": 1,
        "editable": 1,
        "class": "list-box"
    },
    "tabfocus": {
        "title": "WF_TABFOCUS_TITLE",
        "description": "WF_TABFOCUS_DESC",
        "icon": "",
        "editable": 0,
        "row": 0,
        "core": 1
    },
    "table": {
        "title": "WF_TABLE_TITLE",
        "description": "WF_TABLE_DESC",
        "icon": "table_insert,delete_table,row_props,cell_props,row_before,row_after,delete_row,col_before,col_after,delete_col,split_cells,merge_cells",
        "editable": 1,
        "row": 3,
        "core": 1,
        "checksum": "${checksum:table}"
    },
    "textcase": {
        "title": "WF_TEXTCASE_TITLE",
        "description": "WF_TEXTCASE_DESC",
        "icon": "textcase",
        "editable": 0,
        "row": 4,
        "core": 1,
        "class": "split-button"
    },
    "visualchars": {
        "title": "WF_VISUALCHARS_TITLE",
        "description": "WF_VISUALCHARS_DESC",
        "icon": "visualchars",
        "editable": 0,
        "row": 4,
        "core": 1
    },
    "wordcount": {
        "title": "WF_WORDCOUNT_TITLE",
        "description": "WF_WORDCOUNT_DESC",
        "icon": "",
        "editable": 0,
        "row": 0,
        "core": 1
    },
    "reference": {
        "title": "WF_REFERENCE_TITLE",
        "description": "WF_REFERENCE_DESC",
        "icon": "cite,q,abbr,acronym,del,ins",
        "editable": 1,
        "row": 4,
        "core": 1
    },
    "kitchensink": {
        "title": "WF_KITCHENSINK_TITLE",
        "description": "WF_KITCHENSINK_DESC",
        "core": 1,
        "icon": "kitchensink",
        "row": 1,
        "editable": 0
    },
    "hr": {
        "title": "WF_HR_TITLE",
        "description": "WF_HR_DESC",
        "core": 1,
        "icon": "hr",
        "row": 3,
        "editable": 0
    },
    "visualblocks": {
        "title": "WF_VISUALBLOCKS_TITLE",
        "description": "WF_VISUALBLOCKS_DESC",
        "core": 1,
        "icon": "visualblocks",
        "row": 4,
        "editable": 1
    },
    "emotions": {
        "title": "WF_EMOTIONS_TITLE",
        "description": "WF_EMOTIONS_DESC",
        "core": 1,
        "icon": "emotions",
        "row": 4,
        "editable": 1,
        "class": "split-button"
    }
}PK5�!]���SS
commands.jsonnu&1i�{
    "undo": {
        "title": "WF_UNDO_TITLE",
        "description": "WF_UNDO_DESC",
        "core": 1,
        "icon": "undo",
        "row": 1,
        "editable": 0
    },
    "redo": {
        "title": "WF_REDO_TITLE",
        "description": "WF_REDO_DESC",
        "core": 1,
        "icon": "redo",
        "row": 1,
        "editable": 0
    },
    "bold": {
        "title": "WF_BOLD_TITLE",
        "description": "WF_BOLD_DESC",
        "core": 1,
        "icon": "bold",
        "row": 1,
        "editable": 0
    },
    "italic": {
        "title": "WF_ITALIC_TITLE",
        "description": "WF_ITALIC_DESC",
        "core": 1,
        "icon": "italic",
        "row": 1,
        "editable": 0
    },
    "underline": {
        "title": "WF_UNDERLINE_TITLE",
        "description": "WF_UNDERLINE_DESC",
        "core": 1,
        "icon": "underline",
        "row": 1,
        "editable": 0
    },
    "strikethrough": {
        "title": "WF_STRIKETHROUGH_TITLE",
        "description": "WF_STRIKETHROUGH_DESC",
        "core": 1,
        "icon": "strikethrough",
        "row": 1,
        "editable": 0
    },
    "justifyfull": {
        "title": "WF_JUSTIFYFULL_TITLE",
        "description": "WF_JUSTIFYFULL_DESC",
        "core": 1,
        "icon": "justifyfull",
        "row": 1,
        "editable": 0
    },
    "justifycenter": {
        "title": "WF_JUSTIFYCENTER_TITLE",
        "description": "WF_JUSTIFYCENTER_DESC",
        "core": 1,
        "icon": "justifycenter",
        "row": 1,
        "editable": 0
    },
    "justifyleft": {
        "title": "WF_JUSTIFYLEFT_TITLE",
        "description": "WF_JUSTIFYLEFT_DESC",
        "core": 1,
        "icon": "justifyleft",
        "row": 1,
        "editable": 0
    },
    "justifyright": {
        "title": "WF_JUSTIFYRIGHT_TITLE",
        "description": "WF_JUSTIFYRIGHT_DESC",
        "core": 1,
        "icon": "justifyright",
        "row": 1,
        "editable": 0
    },
    "formatselect": {
        "title": "WF_FORMATSELECT_TITLE",
        "description": "WF_FORMATSELECT_DESC",
        "core": 1,
        "icon": "formatselect",
        "row": 1,
        "editable": 0,
        "class": "list-box"
    },
    "newdocument": {
        "title": "WF_NEWDOCUMENT_TITLE",
        "description": "WF_NEWDOCUMENT_DESC",
        "core": 1,
        "icon": "newdocument",
        "row": 1,
        "editable": 0
    },
    "unlink": {
        "title": "WF_UNLINK_TITLE",
        "description": "WF_UNLINK_DESC",
                "core": 1,
        "icon": "unlink",
        "row": 4,
        "editable": 0
    },
    "indent": {
        "title": "WF_INDENT_TITLE",
        "description": "WF_INDENT_DESC",
        "core": 1,
        "icon": "indent",
        "row": 2,
        "editable": 0
    },
    "outdent": {
        "title": "WF_OUTDENT_TITLE",
        "description": "WF_OUTDENT_DESC",
        "core": 1,
        "icon": "outdent",
        "row": 2,
        "editable": 0
    },
    "blockquote": {
        "title": "WF_BLOCKQUOTE_TITLE",
        "description": "WF_BLOCKQUOTE_DESC",
        "core": 1,
        "icon": "blockquote",
        "row": 1,
        "editable": 0
    },
    "removeformat": {
        "title": "WF_REMOVEFORMAT_TITLE",
        "description": "WF_REMOVEFORMAT_DESC",
        "core": 1,
        "icon": "removeformat",
        "row": 1,
        "editable": 0
    },
    "sub": {
        "title": "WF_SUB_TITLE",
        "description": "WF_SUB_DESC",
        "core": 1,
        "icon": "sub",
        "row": 2,
        "editable": 0
    },
    "sup": {
        "title": "WF_SUP_TITLE",
        "description": "WF_SUP_DESC",
        "core": 1,
        "icon": "sup",
        "row": 2,
        "editable": 0
    },
   	"visualaid": {
        "title": "WF_VISUALAID_TITLE",
        "description": "WF_VISUALAID_DESC",
        "core": 1,
        "icon": "visualaid",
        "row": 4,
        "editable": 0
    }
}PK5�!]��8�||encrypt.phpnu&1i�<?php

/**
 * @copyright Copyright (c)2018 Ryan Demmer
 * @license GNU General Public License version 3, or later
 *
 * @since 2.7
 */
// Protection against direct access
\defined('_JEXEC') or die;

use Defuse\Crypto\Key;
use Defuse\Crypto\Encoding;
use Defuse\Crypto\Crypto;

/**
 * Implements encrypted settings handling features.
 */
class JceEncryptHelper
{
    protected static function generateKey()
    {        
        $keyObject = Key::createNewRandomKey();
        $keyAscii = $keyObject->saveToAsciiSafeString();

        $keyData = Encoding::binToHex($keyAscii);

        $filecontents = "<?php defined('WF_EDITOR') or die(); define('WF_SERVERKEY', '$keyData'); ?>";
        $filename     = JPATH_ADMINISTRATOR . '/components/com_jce/serverkey.php';

        file_put_contents($filename, $filecontents);

        return Key::loadFromAsciiSafeString($keyAscii);
    }

    /**
     * Gets the configured server key, automatically loading the server key storage file
     * if required.
     *
     * @return string
     */
    public static function getKey($legacy = false)
    {
        if (!defined('WF_SERVERKEY')) {
            $filename = JPATH_ADMINISTRATOR . '/components/com_jce/serverkey.php';

            if (is_file($filename)) {
                include_once($filename);
            }
        }

        if (defined('WF_SERVERKEY')) {
            // return key as string
            if ($legacy) {
                $key = base64_decode(WF_SERVERKEY);
                return $key;
            }

            try {
                $keyAscii = Encoding::hexToBin(WF_SERVERKEY);
                $key = Key::loadFromAsciiSafeString($keyAscii);
            } catch(Defuse\Crypto\Exception\BadFormatException $ex) {
                return "";
            }

            return $key;
        }

        return self::generateKey();
    }

    /**
     * Encrypts the settings using the automatically detected preferred algorithm.
     *
     * @param $settingsINI string The raw settings INI string
     *
     * @return string The encrypted data to store in the database
     */
    public static function encrypt($data, $key = null)
    {
        // Do we have a non-empty key to begin with?
        if (empty($key)) {
            $key = self::getKey();
        }

        if (empty($key)) {
            return $data;
        }

        $encrypted = Crypto::encrypt($data, $key);

        // base64encode
        $encoded = base64_encode($encrypted);

        // add marker
        $data = '###DEFUSE###' . $encoded;

        return $data;
    }

    /**
     * Decrypts the encrypted settings and returns the plaintext INI string.
     *
     * @param $encrypted string The encrypted data
     *
     * @return string The decrypted data
     */
    public static function decrypt($encrypted, $key = null)
    {
        $mode = substr($encrypted, 0, 12);

        if ($mode == '###AES128###' || $mode == '###CTR128###') {
            require_once(__DIR__ . '/encrypt/aes.php');
            
            $encrypted = substr($encrypted, 12);

            $key = self::getKey(true);

            switch ($mode) {
                case '###AES128###':
                    $encrypted = base64_decode($encrypted);
                    $decrypted = @WFUtilEncrypt::AESDecryptCBC($encrypted, $key, 128);
                    break;
    
                case '###CTR128###':
                    $decrypted = @WFUtilEncrypt::AESDecryptCtr($encrypted, $key, 128);
                    break;
            }

            return rtrim($decrypted, "\0");
        }

        if ($mode == '###DEFUSE###') {
            $key = self::getKey();

            if (empty($key)) {
                return $encrypted;
            }

            //get encrypted string without marker
            $encrypted = substr($encrypted, 12);
            
            // base64decode
            $decoded = base64_decode($encrypted);

            try {
                $decrypted = Crypto::decrypt($decoded, $key);
            } catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) {
                return $encrypted;
            }

            return rtrim($decrypted, "\0");
        }

        return $encrypted;
    }
}
PK5�!]-�)3jj	admin.phpnu&1i�<?php
/**
 * @package     JCE
 * @subpackage  Admin
 *
 * @copyright   Copyright (C) 2005 - 2023 Open Source Matters, Inc. All rights reserved.
 * @copyright   Copyright (c) 2009-2024 Ryan Demmer. All rights reserved
 * @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;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\HTML\Helpers\Sidebar;

/**
 * Admin helper.
 *
 * @since       3.0
 */
class JceHelperAdmin
{
    /**
     * Configure the Submenu links.
     *
     * @param string $vName The view name
     *
     * @since   3.0
     */
    public static function addSubmenu($vName)
    {
        $uri = (string) Uri::getInstance();
        $return = urlencode(base64_encode($uri));

        $user = Factory::getUser();

        Sidebar::addEntry(
            Text::_('WF_CPANEL'),
            'index.php?option=com_jce&view=cpanel',
            $vName == 'cpanel'
        );

        $views = array(
            'config' => 'WF_CONFIGURATION',
            'profiles' => 'WF_PROFILES',
            'browser' => 'WF_CPANEL_BROWSER',
            'mediabox' => 'WF_MEDIABOX',
        );

        foreach ($views as $key => $label) {

            if ($key === "mediabox" && !PluginHelper::isEnabled('system', 'jcemediabox')) {
                continue;
            }

            if ($user->authorise('jce.' . $key, 'com_jce')) {
                Sidebar::addEntry(
                    Text::_($label),
                    'index.php?option=com_jce&view=' . $key,
                    $vName == $key
                );
            }
        }
    }

    public static function getTemplateStylesheets()
    {
        require_once JPATH_SITE . '/components/com_jce/editor/libraries/classes/editor.php';

        return WFEditor::getTemplateStyleSheets();
    }
}
PK5�!]`$z�/�/profiles.phpnu&1i�<?php

/**
 * @package     JCE
 * @subpackage  Admin
 *
 * @copyright   Copyright (C) 2005 - 2023 Open Source Matters, Inc. All rights reserved.
 * @copyright   Copyright (c) 2009-2024 Ryan Demmer. All rights reserved
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
\defined('_JEXEC') or die;

use Joomla\CMS\Access\Access;
use Joomla\CMS\Factory;
use Joomla\Filesystem\File;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Table\Table;
use Joomla\String\StringHelper;

abstract class JceProfilesHelper
{
    /**
     * Create the Profiles table.
     *
     * @return bool
     */
    public static function createProfilesTable()
    {
        $app = Factory::getApplication();

        $db = Factory::getDBO();
        $driver = strtolower($db->name);

        switch ($driver) {
            default:
            case 'mysql':
            case 'mysqli':
                $driver = 'mysql';
                break;
            case 'sqlsrv':
            case 'sqlazure':
            case 'sqlzure':
                $driver = 'sqlsrv';
                break;
            case 'postgresql':
            case 'pgsql':
                $driver = 'postgresql';
                break;
        }

        $file = JPATH_ADMINISTRATOR . '/components/com_jce/sql/' . $driver . '.sql';
        $error = null;

        if (is_file($file)) {
            $query = file_get_contents($file);

            if ($query) {
                // replace prefix
                $query = $db->replacePrefix((string) $query);

                // set query
                $db->setQuery(trim($query));

                if (!$db->execute()) {
                    $app->enqueueMessage(Text::_('WF_INSTALL_TABLE_PROFILES_ERROR') . $db->stdErr(), 'error');

                    return false;
                } else {
                    return true;
                }
            } else {
                $error = 'NO SQL QUERY';
            }
        } else {
            $error = 'SQL FILE MISSING';
        }

        $app->enqueueMessage(Text::_('WF_INSTALL_TABLE_PROFILES_ERROR') . !is_null($error) ? ' - ' . $error : '', 'error');

        return false;
    }

    /**
     * Install Profiles.
     *
     * @return bool
     *
     * @param object $install[optional]
     */
    public static function installProfiles()
    {
        $app = Factory::getApplication();
        $db = Factory::getDBO();

        if (self::createProfilesTable()) {
            self::buildCountQuery();

            $profiles = array('Default' => false, 'Front End' => false);

            // No Profiles table data
            if (!$db->loadResult()) {
                $xml = JPATH_ADMINISTRATOR . '/components/com_jce/models/profiles.xml';

                if (is_file($xml)) {
                    if (!self::processImport($xml)) {
                        $app->enqueueMessage(Text::_('WF_INSTALL_PROFILES_ERROR'), 'error');

                        return false;
                    }
                } else {
                    $app->enqueueMessage(Text::_('WF_INSTALL_PROFILES_NOFILE_ERROR'), 'error');

                    return false;
                }
            }

            return true;
        }

        return false;
    }

    private static function buildCountQuery($name = '')
    {
        $db = Factory::getDBO();

        $query = $db->getQuery(true);

        // check for name
        $query->select('COUNT(id)')->from('#__wf_profiles');

        if ($name) {
            $query->where('name = ' . $db->Quote($name));
        }

        $db->setQuery($query);
    }

    public static function getDefaultProfile()
    {
        $mainframe = Factory::getApplication();
        $file = JPATH_ADMINISTRATOR . '/components/com_jce/models/profiles.xml';

        $xml = simplexml_load_file($file);

        Table::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_jce/tables');

        if ($xml) {
            foreach ($xml->profiles->children() as $profile) {
                if ($profile->attributes()->default) {
                    $table = Table::getInstance('Profiles', 'JceTable');

                    foreach ($profile->children() as $item) {
                        switch ($item->getName()) {
                            case 'rows':
                                $table->rows = (string) $item;
                                break;
                            case 'plugins':
                                $table->plugins = (string) $item;
                                break;
                            default:
                                $key = $item->getName();
                                $table->$key = (string) $item;

                                break;
                        }
                    }

                    // reset name and description
                    $table->name = '';
                    $table->description = '';

                    return $table;
                }
            }
        }

        return null;
    }

    /**
     * Check whether a table exists.
     *
     * @return bool
     *
     * @param string $table Table name
     */
    public static function checkTable()
    {
        $db = Factory::getDBO();

        $tables = $db->getTableList();

        if (!empty($tables)) {
            // swap array values with keys, convert to lowercase and return array keys as values
            $tables = array_keys(array_change_key_case(array_flip($tables)));
            $app = Factory::getApplication();
            $match = str_replace('#__', strtolower($app->getCfg('dbprefix', '')), '#__wf_profiles');

            return in_array($match, $tables);
        }

        // try with query
        self::buildCountQuery();

        return $db->execute();
    }

    /**
     * Check table contents.
     *
     * @return int
     *
     * @param string $table Table name
     */
    public static function checkTableContents()
    {
        $db = Factory::getDBO();

        self::buildCountQuery();

        return $db->loadResult();
    }

    public static function getUserGroups($area)
    {
        $db = Factory::getDBO();

        $query = $db->getQuery(true);

        $query->select('id')->from('#__usergroups');

        $db->setQuery($query);
        $groups = $db->loadColumn();

        $front = array();
        $back = array();

        foreach ($groups as $group) {
            $create = Access::checkGroup($group, 'core.create');
            $admin = Access::checkGroup($group, 'core.login.admin');
            $super = Access::checkGroup($group, 'core.admin');

            if ($super) {
                $back[] = $group;
            } else {
                // group can create
                if ($create) {
                    // group has admin access
                    if ($admin) {
                        $back[] = $group;
                    } else {
                        $front[] = $group;
                    }
                }
            }
        }

        switch ($area) {
            case 0:
                return array_merge($front, $back);
                break;
            case 1:
                return $front;
                break;
            case 2:
                return $back;
                break;
        }

        return array();
    }

    /**
     * Process import data from XML file.
     *
     * @param object $file    XML file
     * @param bool   $install Can be used by the package installer
     */
    public static function processImport($file)
    {
        $n = 0;

        $app = Factory::getApplication();

        // load data from file
        $data = file_get_contents($file);
        // format params data as CDATA
        $data = preg_replace('#<params>{(.+?)}<\/params>#', '<params><![CDATA[{$1}]]></params>', $data);
        // load processed string
        $xml = simplexml_load_string($data);

        $user = Factory::getUser();
        $date = Factory::getDate();

        Table::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_jce/tables');

        $language = Factory::getLanguage();
        $language->load('com_jce', JPATH_ADMINISTRATOR, null, true);

        if ($xml) {
            foreach ($xml->profiles->children() as $profile) {
                $table = Table::getInstance('Profiles', 'JceTable');

                foreach ($profile->children() as $item) {
                    $key = $item->getName();
                    $value = (string) $item;

                    switch ($key) {
                        case 'name':
                            // only if name set and table name not set
                            if ($value) {
                                // create name copy if exists
                                while ($table->load(array('name' => $value))) {
                                    if ($value === $table->name) {
                                        $value = StringHelper::increment($value);
                                    }
                                }
                            }
                            break;

                        case 'description':
                            $value = Text::_($value);
                            break;
                        case 'types':

                            if ($value === "") {
                                $area = (string) $profile->area[0] || 0;
                                $groups = self::getUserGroups($area);
                                $value = implode(',', array_unique($groups));
                            }
                            break;
                        case 'users':
                            break;
                        case 'area':
                            if ($value === "") {
                                $value = '0';
                            }

                            break;
                        case 'components':
                            break;
                        case 'params':
                            if (!empty($value)) {
                                $data = json_decode($value, true);

                                if (is_array($data)) {
                                    array_walk($data, function (&$param, $key) {
                                        if (is_string($param) && WFUtility::isJson($param)) {
                                            $param = json_decode($param, true);
                                        }
                                    });
                                }

                                $value = json_encode($data);
                            }

                            if (empty($value)) {
                                $value = "{}";
                            }

                            break;
                        case 'rows':
                            break;
                        case 'plugins':
                            break;
                        case 'area':
                        case 'published':
                        case 'ordering':
                            $value = (int) $value;
                            break;
                    }

                    $table->$key = $value;
                }

                // set new id
                $table->id = 0;

                // set checked_out
                $table->checked_out = $user->get('id');

                // set checked_out_time
                $table->checked_out_time = $date->toSQL();

                if (!$table->store()) {
                    $app->enqueueMessage($table->getError(), 'error');
                    return false;
                }

                // check-in
                $table->checkin();

                ++$n;
            }
        }

        return $n;
    }

    /**
     * CDATA encode a parameter if it contains & < > characters, eg: <![CDATA[index.php?option=com_content&view=article&id=1]]>.
     *
     * @param object $param
     *
     * @return CDATA encoded parameter or parameter
     */
    public static function encodeData($data)
    {
        if (preg_match('/[<>&]/', $data)) {
            $data = '<![CDATA[' . $data . ']]>';
        }

        $data = preg_replace('/"/', '\"', $data);

        return $data;
    }
}
PK5�!]�=T�8�8plugins.phpnu&1i�<?php

/**
 * @copyright     Copyright (c) 2009-2024 Ryan Demmer. All rights reserved
 * @license       GNU/GPL 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * JCE is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses
 */
\defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\Filesystem\File;
use Joomla\Filesystem\Folder;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Uri\Uri;

require_once JPATH_ADMINISTRATOR . '/components/com_jce/includes/base.php';

abstract class JcePluginsHelper
{
    public static function getCommands()
    {
        $data = file_get_contents(__DIR__ . '/commands.json');
        $json = json_decode($data);

        $commands = array();

        if ($json) {
            foreach ($json as $name => $attribs) {
                $attribs->type = 'command';
                $commands[$name] = $attribs;
            }
        }

        return $commands;
    }

    public static function isValidPlugin($name)
    {
        $plugins = self::getPlugins();
        return isset($plugins[$name]);
    }

    /**
     * Get a list of all code, pro and installed plugins.
     *
     * @return array $plugins
     */
    public static function getPlugins()
    {
        $app = Factory::getApplication();
        $language = Factory::getLanguage();

        static $plugins;

        if (!isset($plugins)) {
            $plugins = array();

            // get core json
            $core = file_get_contents(__DIR__ . '/plugins.json');
            // decode to object
            $data = json_decode($core);

            if ($data) {
                foreach ($data as $name => $attribs) {
                    // skip if the plugin file is missing
                    if (!is_file(WF_EDITOR_MEDIA . '/tinymce/plugins/' . $name . '/plugin.js')) {
                        continue;
                    }

                    // update attributes
                    $attribs->type = 'plugin';

                    $attribs->path = WF_EDITOR_PLUGINS . '/' . $name;
                    $attribs->manifest = WF_EDITOR_PLUGINS . '/' . $name . '/' . $name . '.xml';

                    $attribs->image = '';

                    if (!isset($attribs->class)) {
                        $attribs->class = '';
                    }

                    // compatability
                    $attribs->name = $name;
                    // pass to array
                    $plugins[$name] = $attribs;
                }
            }

            // get plugins external sources via event, eg: JCE Pro System Plugin
            $app->triggerEvent('onWfPluginsHelperGetPlugins', array(&$plugins));

            // get all installed plugins
            $installed = PluginHelper::getPlugin('jce');

            foreach ($installed as $item) {
                // check for delimiter, only load editor plugins
                if (!preg_match('/^editor[-_]/', $item->name)) {
                    continue;
                }

                // create path
                $path = JPATH_PLUGINS . '/jce/' . $item->name;

                // load language
                $language->load('plg_jce_' . $item->name, JPATH_ADMINISTRATOR);
                $language->load('plg_jce_' . $item->name, $path);

                // get xml file
                $file = $path . '/' . $item->name . '.xml';

                if (is_file($file)) {
                    // load xml data
                    $xml = simplexml_load_file($file);

                    if ($xml) {
                        // check xml file is valid
                        if ((string) $xml->getName() != 'extension') {
                            continue;
                        }

                        // remove "editor-" or "editor_"
                        $name = substr($item->name, 7);

                        $attribs = new StdClass();
                        $attribs->name = $name;
                        $attribs->manifest = $file;

                        $params = $xml->fields;

                        $attribs->title = (string) $xml->name;
                        $attribs->icon = (string) $xml->icon;
                        $attribs->editable = 0;

                        // set default values
                        $attribs->image = '';
                        $attribs->class = '';

                        if ($xml->icon->attributes()) {
                            foreach ($xml->icon->attributes() as $key => $value) {
                                $attribs->$key = $value;
                            }
                        }

                        if ($attribs->image) {
                            $attribs->image = Uri::root(true) . '/' . $attribs->image;
                        }

                        // can't be editable without parameters
                        if ($params && count($params->children())) {
                            $attribs->editable = 1;
                        }

                        $row = (int) $xml->attributes()->row;

                        // set row from passed in value or 0
                        $attribs->row = $row;

                        // if an icon is set and no row, default to 4
                        if (!empty($attribs->icon) && !$row) {
                            $attribs->row = 4;
                        }

                        $attribs->description = (string) $xml->description;
                        $attribs->core = 0;

                        // relative path
                        $attribs->path = $path;
                        $attribs->url = 'plugins/jce/' . $item->name;

                        // get snake-case name to check for media folder
                        $snake_case_name = str_replace('-', '_', $item->name);

                        // url in Joomla media folder
                        if (is_dir(JPATH_SITE . '/media/plg_jce_' . $snake_case_name)) {
                            $attribs->url = 'media/plg_jce_' . $snake_case_name;
                        }

                        $attribs->type = 'plugin';

                        $plugins[$name] = $attribs;
                    }
                }
            }
        }

        return $plugins;
    }

    /**
     * Get installed extensions.
     *
     * @return array $extensions
     */
    public static function getExtensions($type = '')
    {
        $language = Factory::getLanguage();

        static $extensions;

        if (empty($extensions)) {
            $extensions = array();

            // recursively get all extension files
            $files = Folder::files(WF_EDITOR_EXTENSIONS, '\.xml$', true, true);

            foreach ($files as $file) {
                $name = basename($file, '.xml');

                $object = new StdClass();
                $object->folder = basename(dirname($file));
                $object->manifest = $file;
                $object->plugins = array();
                $object->name = $name;
                $object->title = 'WF_' . strtoupper($object->folder) . '_' . strtoupper($name) . '_TITLE';
                $object->description = '';
                $object->id = $object->folder . '.' . $object->name;
                $object->extension = $object->name;
                // set as non-core by default
                $object->core = 0;
                // set as not editable by default
                $object->editable = 0;
                // set type
                $object->type = $object->folder;

                $extensions[$object->type][] = $object;
            }

            // get all installed plugins
            $installed = PluginHelper::getPlugin('jce');

            if (!empty($installed)) {
                foreach ($installed as $p) {
                    // check for delimiter to remove legacy extensions
                    if (!preg_match('/[-_]/', $p->name)) {
                        continue;
                    }

                    // only load "extensions", not editor plugins
                    if (preg_match('/^editor[-_]/', $p->name)) {
                        continue;
                    }

                    // set path
                    $p->path = JPATH_PLUGINS . '/jce/' . $p->name;

                    $parts = preg_split('/[-_]/', $p->name, 2);

                    // get type and name
                    $p->folder = $parts[0];
                    $p->extension = $parts[1];

                    // plugin manifest, eg: filesystem-joomla.xml
                    $p->manifest = $p->path . '/' . $p->name . '.xml';

                    $p->plugins = array();
                    $p->description = '';

                    // load language
                    $language->load('plg_jce_' . $p->name, JPATH_ADMINISTRATOR);
                    $language->load('plg_jce_' . $p->name, $p->path);

                    list($p->type, $p->name) = preg_split('/[-_]/', $p->name, 2);

                    // create title from name parts, eg: plg_jce_filesystem_joomla
                    $p->title = 'plg_jce_' . $p->type . '_' . $p->name;

                    // create plugin id, eg: filesystem.joomla
                    $p->id = $p->type . '.' . $p->name;

                    // not core
                    $p->core = 0;

                    // set as not editable by default
                    $p->editable = 0;

                    $extensions[$p->type][] = $p;
                }
            }
        }

        if ($type && isset($extensions[$type])) {
            return $extensions[$type];
        }

        return $extensions;
    }

    public static function addToProfile($id, $plugin)
    {
        Table::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_jce/tables');

        // Add to Default Group
        $profile = Table::getInstance('Profiles', 'JceTable');

        if ($profile->load($id)) {
            // Add to plugins list
            $plugins = explode(',', $profile->plugins);

            if (!in_array($plugin->name, $plugins)) {
                $plugins[] = $plugin->name;
            }

            $profile->plugins = implode(',', $plugins);

            if ($plugin->icon) {
                if (in_array($plugin->name, preg_split('/[;,]+/', $profile->rows)) === false) {
                    // get rows as array
                    $rows = explode(';', $profile->rows);

                    if (count($rows)) {
                        // get key (row number)
                        $key = count($rows) - 1;
                        // get row contents as array
                        $row = explode(',', $rows[$key]);
                        // add plugin name to end of row
                        $row[] = $plugin->name;
                        // add row data back to rows array
                        $rows[$key] = implode(',', $row);

                        $profile->rows = implode(';', $rows);
                    }
                }
            }

            if (!$profile->store()) {
                throw new Exception(Text::_('WF_INSTALLER_PLUGIN_PROFILE_ERROR'));
            }
        }

        return true;
    }

    public static function removeFromProfile($id, $plugin)
    {
        Table::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_jce/tables');

        // Add to Default Group
        $profile = Table::getInstance('Profiles', 'JceTable');

        if ($profile->load($id)) {
            // remove from plugins list
            $plugins = explode(',', $profile->plugins);
            $key = array_search($plugin->name, $plugins);

            if ($key) {
                unset($plugins[$key]);
                $profile->plugins = implode(',', array_values($plugins));
            }

            if ($plugin->icon) {
                // check if its in the profile
                if (in_array($plugin->name, preg_split('/[;,]+/', $profile->rows))) {
                    $lists = array();
                    foreach (explode(';', $profile->rows) as $list) {
                        $icons = explode(',', $list);
                        foreach ($icons as $k => $v) {
                            if ($plugin->name == $v) {
                                unset($icons[$k]);
                            }
                        }
                        $lists[] = implode(',', $icons);
                    }
                    $profile->rows = implode(';', $lists);
                }

                if (!$profile->store()) {
                    throw new Exception(Text::sprintf('WF_INSTALLER_REMOVE_FROM_GROUP_ERROR', $plugin->name));
                }
            }
        }

        return true;
    }

    /**
     * Add index.html files to each folder.
     */
    private static function addIndexfiles($path)
    {
        // get the base file
        $file = JPATH_ADMINISTRATOR . '/components/com_jce/index.html';

        if (is_file($file) && is_dir($path)) {
            File::copy($file, $path . '/' . basename($file));

            // admin component
            $folders = Folder::folders($path, '.', true, true);

            foreach ($folders as $folder) {
                File::copy($file, $folder . '/' . basename($file));
            }
        }
    }

    public static function postInstall($route, $plugin, $installer)
    {
        $db = Factory::getDBO();

        // load the plugin and enable
        if (isset($plugin->row) && $plugin->row > 0) {
            $query = $db->getQuery(true);

            $query->select('id')->from('#__wf_profiles')->where('name = ' . $db->Quote('Default') . ' OR id = 1');

            $db->setQuery($query);
            $id = $db->loadResult();

            if ($id) {
                if ($route == 'install') {
                    // add to profile
                    self::addToProfile($id, $plugin);
                } else {
                    // remove from profile
                    self::removeFromProfile($id, $plugin);
                }
            }
        }

        if ($route == 'install') {
            if ($plugin->type == 'extension') {
                $plugin->path = $plugin->path . '/' . $plugin->name;
            }

            // add index.html files
            self::addIndexfiles($plugin->path);
        }

        return true;
    }
}
PK5�!]Uէ���
parameter.phpnu&1i�<?php

/**
 * @package   	JCE
 * @copyright 	Copyright (c) 2009-2016 Ryan Demmer. All rights reserved.
 * @license   	GNU/GPL 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * JCE is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 */

abstract class WFParameterHelper
{
	/**
	 * Convert JSON data to JParameter Object
	 * @param $data JSON data
	 */
	public static function toObject($data) 
	{
		$param = new WFParameter('');
		$param->bind($data);

		return $param->getData();
	}
	
	public static function getComponentParams($key = '', $path = '')
	{
		require_once(JPATH_COMPONENT_ADMINISTRATOR . '/classes/parameter.php');		
		$component = JComponentHelper::getComponent('com_jce');
		
		return new WFParameter($component->params, $path, $key);
	}
}PK5�!]�7ċ��browser.phpnu&1i�<?php

/**
 * @package     JCE
 * @subpackage  Admin
 *
 * @copyright   Copyright (C) 2005 - 2023 Open Source Matters, Inc. All rights reserved.
 * @copyright   Copyright (c) 2009-2024 Ryan Demmer. All rights reserved
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
\defined('_JEXEC') or die;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;

JLoader::register('WFApplication', JPATH_ADMINISTRATOR . '/components/com_jce/helpers/browser.php');

abstract class WfBrowserHelper
{
    public static function getBrowserLink($element = null, $mediatype = '', $callback = '', $options = array())
    {
        $options = array_merge($options, array(
            'element' => $element,
            'mediatype' => $mediatype,
            'callback' => $callback,
        ));

        $url = self::getMediaFieldUrl($options);

        return $url;
    }

    public static function getMediaFieldLink($element = null, $mediatype = 'images', $callback = '')
    {
        $url = self::getMediaFieldUrl(array(
            'element' => $element,
            'mediatype' => $mediatype,
            'callback' => $callback,
        ));

        return $url;
    }

    public static function isMediaFieldEnabled()
    {
        static $enabled = null;

        if ($enabled !== null) {
            return $enabled;
        }

        require_once JPATH_SITE . '/components/com_jce/editor/libraries/classes/application.php';

        $wf = WFApplication::getInstance();
        $profile = $wf->getActiveProfile(['plugin' => 'browser']);

        $enabled = $profile ? (bool) $wf->getParam('browser.mediafield_enable', 1) : false;

        return $enabled;
    }

    public static function getMediaFieldUrl($options = array())
    {
        $app = Factory::getApplication();
        $token = Factory::getSession()->getFormToken();

        // get component params to check for media field conversion
        $componentParams = ComponentHelper::getParams('com_jce');

        if (!isset($options['element'])) {
            $options['element'] = null;
        }

        if (!isset($options['mediatype'])) {
            $options['mediatype'] = 'images';
        }

        if (!isset($options['callback'])) {
            $options['callback'] = '';
        }

        if (!isset($options['converted'])) {
            $options['converted'] = false;
        }

        if (!isset($options['mediafolder'])) {
            $options['mediafolder'] = '';
        }

        if (self::isMediaFieldEnabled() === false) {
            return '';
        }

        // get editor instance
        $wf = WFApplication::getInstance();

        // set base url
        $url = 'index.php?option=com_jce&task=plugin.display';

        // add default context
        if (empty($options['context'])) {
            $options['context'] = $wf->getContext();
        }

        // append "caller" plugin
        if (!empty($options['plugin'])) {
            if (strpos($options['plugin'], 'browser') === false) {
                $options['plugin'] = 'browser.' . $options['plugin'];
            }
        } else {
            $options['plugin'] = 'browser';
        }

        $options['standalone'] = 1;
        $options[$token] = 1;
        $options['client'] = $app->getClientId();

        // filter options values
        $options = array_filter($options, function ($value) {
            if (is_array($value)) {
                return !empty($value);
            }

            return $value !== '' && $value !== null;
        });

        $url .= '&' . http_build_query($options);

        return $url;
    }

    public static function getMediaFieldOptions($options = array())
    {
        if (self::isMediaFieldEnabled() === false) {
            return $options;
        }

        $app = Factory::getApplication();

        // get component params to check for media field conversion
        $componentParams = ComponentHelper::getParams('com_jce');

        // merge default options
        $options = array_merge(array(
            'upload' => 0,
            'select_button' => 1,
            'convert' => 0,
            'mediafields' => array(),
        ), $options);

        // get editor instance
        $wf = WFApplication::getInstance();
        $profile = $wf->getActiveProfile(['plugin' => 'browser']);

        // is conversion enabled?
        $options['convert'] = (int) $componentParams->get('replace_media_manager', 1) && (int) $wf->getParam('browser.mediafield_conversion', 1);

        // add default context
        $options['context'] = $wf->getContext();

        // get allowed extensions
        $accept = $wf->getParam('browser.extensions', 'jpg,jpeg,png,gif,mp3,m4a,mp4a,ogg,mp4,mp4v,mpeg,mov,webm,doc,docx,odg,odp,ods,odt,pdf,ppt,pptx,txt,xcf,xls,xlsx,csv,zip,tar,gz');

        $options['accept'] = array_map(function ($value) {
            if ($value[0] != '-') {
                return $value;
            }
        }, explode(',', $accept));

        $options['accept'] = implode(',', array_filter($options['accept']));
        $options['upload'] = (int) $wf->getParam('browser.mediafield_upload', 1);
        $options['select_button'] = (int) $wf->getParam('browser.mediafield_select_button', 1);

        $app->triggerEvent('onWfMediaFieldGetOptions', array(&$options, $profile));

        return $options;
    }
}
PK5�!]�����
extension.phpnu&1i�<?php

/**
 * @copyright 	Copyright (c) 2009-2017 Ryan Demmer. All rights reserved
 * @license   	GNU/GPL 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * JCE is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses
 */
abstract class WFExtensionHelper
{
    protected static $component = array();
    protected static $plugin = array();

    public static function getComponent($id = null, $option = 'com_jce')
    {
        if (!isset(self::$component)) {
            self::$component = array();
        }

        $options = array($option);

        if (isset($id)) {
            $options[] = $id;
        }

        $signature = serialize($options);

        if (!isset(self::$component[$signature])) {
            if (defined('JPATH_PLATFORM')) {
                // get component table
                $component = JTable::getInstance('extension');

                if (!$id) {
                    $id = $component->find(array('type' => 'component', 'element' => $option));
                }

                $component->load($id);
            } else {
                // get component table
                $component = JTable::getInstance('component');

                if ($id) {
                    $component->load($id);
                } else {
                    $component->loadByOption($option);
                }
            }

            self::$component[$signature] = $component;
        }

        return self::$component[$signature];
    }

    public static function getPlugin($id = null, $element = 'jce', $folder = 'editors')
    {
        if (!isset(self::$plugin)) {
            self::$plugin = array();
        }

        $options = array($element, $folder);

        if (isset($id)) {
            $options[] = $id;
        }

        $signature = serialize($options);

        if (!isset(self::$plugin[$signature])) {
            if (defined('JPATH_PLATFORM')) {
                // get component table
                $plugin = JTable::getInstance('extension');

                if (!$id) {
                    $id = $plugin->find(array('type' => 'plugin', 'folder' => $folder, 'element' => $element));
                }

                $plugin->load($id);
                // map extension_id to id
                $plugin->id = $plugin->extension_id;

                // store result
                self::$plugin[$signature] = $plugin;
            } else {
                $plugin = JTable::getInstance('plugin');

                if (!$id) {
                    $db = JFactory::getDBO();
                    $query = 'SELECT id FROM #__plugins'.' WHERE folder = '.$db->Quote($folder);

                    if ($element) {
                        $query .= ' AND element = '.$db->Quote($element);
                    }

                    $db->setQuery($query);
                    $id = $db->loadResult();
                }

                $plugin->load($id);

                // store result
                self::$plugin[$signature] = $plugin;
            }
        }

        return self::$plugin[$signature];
    }
}
PK��!]I��,��html/contentadministrator.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_content
 *
 * @copyright   (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

JLoader::register('ContentHelper', JPATH_ADMINISTRATOR . '/components/com_content/helpers/content.php');

/**
 * Content HTML helper
 *
 * @since  3.0
 */
abstract class JHtmlContentAdministrator
{
	/**
	 * Render the list of associated items
	 *
	 * @param   integer  $articleid  The article item id
	 *
	 * @return  string  The language HTML
	 *
	 * @throws  Exception
	 */
	public static function association($articleid)
	{
		// Defaults
		$html = '';

		// Get the associations
		if ($associations = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', $articleid))
		{
			foreach ($associations as $tag => $associated)
			{
				$associations[$tag] = (int) $associated->id;
			}

			// Get the associated menu items
			$db = JFactory::getDbo();
			$query = $db->getQuery(true)
				->select('c.*')
				->select('l.sef as lang_sef')
				->select('l.lang_code')
				->from('#__content as c')
				->select('cat.title as category_title')
				->join('LEFT', '#__categories as cat ON cat.id=c.catid')
				->where('c.id IN (' . implode(',', array_values($associations)) . ')')
				->where('c.id != ' . $articleid)
				->join('LEFT', '#__languages as l ON c.language=l.lang_code')
				->select('l.image')
				->select('l.title as language_title');
			$db->setQuery($query);

			try
			{
				$items = $db->loadObjectList('id');
			}
			catch (RuntimeException $e)
			{
				throw new Exception($e->getMessage(), 500, $e);
			}

			if ($items)
			{
				foreach ($items as &$item)
				{
					$text    = $item->lang_sef ? strtoupper($item->lang_sef) : 'XX';
					$url     = JRoute::_('index.php?option=com_content&task=article.edit&id=' . (int) $item->id);

					$tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '<br />' . JText::sprintf('JCATEGORY_SPRINTF', $item->category_title);
					$classes = 'hasPopover label label-association label-' . $item->lang_sef;

					$item->link = '<a href="' . $url . '" title="' . $item->language_title . '" class="' . $classes
						. '" data-content="' . $tooltip . '" data-placement="top">'
						. $text . '</a>';
				}
			}

			JHtml::_('bootstrap.popover');

			$html = JLayoutHelper::render('joomla.content.associations', $items);
		}

		return $html;
	}

	/**
	 * Show the feature/unfeature links
	 *
	 * @param   integer  $value      The state value
	 * @param   integer  $i          Row number
	 * @param   boolean  $canChange  Is user allowed to change?
	 *
	 * @return  string       HTML code
	 */
	public static function featured($value = 0, $i = 0, $canChange = true)
	{
		JHtml::_('bootstrap.tooltip');

		// Array of image, task, title, action
		$states = array(
			0 => array('unfeatured', 'articles.featured', 'COM_CONTENT_UNFEATURED', 'JGLOBAL_TOGGLE_FEATURED'),
			1 => array('featured', 'articles.unfeatured', 'COM_CONTENT_FEATURED', 'JGLOBAL_TOGGLE_FEATURED'),
		);
		$state = ArrayHelper::getValue($states, (int) $value, $states[1]);
		$icon  = $state[0];

		if ($canChange)
		{
			$html = '<a href="#" onclick="return listItemTask(\'cb' . $i . '\',\'' . $state[1] . '\')" class="btn btn-micro hasTooltip'
				. ($value == 1 ? ' active' : '') . '" title="' . JHtml::_('tooltipText', $state[3])
				. '"><span class="icon-' . $icon . '" aria-hidden="true"></span></a>';
		}
		else
		{
			$html = '<a class="btn btn-micro hasTooltip disabled' . ($value == 1 ? ' active' : '') . '" title="'
				. JHtml::_('tooltipText', $state[2]) . '"><span class="icon-' . $icon . '" aria-hidden="true"></span></a>';
		}

		return $html;
	}
}
PK��!]�*\���content.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_content
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Content component helper.
 *
 * @since  1.6
 */
class ContentHelper extends JHelperContent
{
	public static $extension = 'com_content';

	/**
	 * Configure the Linkbar.
	 *
	 * @param   string  $vName  The name of the active view.
	 *
	 * @return  void
	 *
	 * @since   1.6
	 */
	public static function addSubmenu($vName)
	{
		JHtmlSidebar::addEntry(
			JText::_('JGLOBAL_ARTICLES'),
			'index.php?option=com_content&view=articles',
			$vName == 'articles'
		);
		JHtmlSidebar::addEntry(
			JText::_('COM_CONTENT_SUBMENU_CATEGORIES'),
			'index.php?option=com_categories&extension=com_content',
			$vName == 'categories'
		);

		JHtmlSidebar::addEntry(
			JText::_('COM_CONTENT_SUBMENU_FEATURED'),
			'index.php?option=com_content&view=featured',
			$vName == 'featured'
		);

		if (JComponentHelper::isEnabled('com_fields') && JComponentHelper::getParams('com_content')->get('custom_fields_enable', '1'))
		{
			JHtmlSidebar::addEntry(
				JText::_('JGLOBAL_FIELDS'),
				'index.php?option=com_fields&context=com_content.article',
				$vName == 'fields.fields'
			);
			JHtmlSidebar::addEntry(
				JText::_('JGLOBAL_FIELD_GROUPS'),
				'index.php?option=com_fields&view=groups&context=com_content.article',
				$vName == 'fields.groups'
			);
		}
	}

	/**
	 * Applies the content tag filters to arbitrary text as per settings for current user group
	 *
	 * @param   text  $text  The string to filter
	 *
	 * @return  string  The filtered string
	 *
	 * @deprecated  4.0  Use JComponentHelper::filterText() instead.
	 */
	public static function filterText($text)
	{
		try
		{
			JLog::add(
				sprintf('%s() is deprecated. Use JComponentHelper::filterText() instead', __METHOD__),
				JLog::WARNING,
				'deprecated'
			);
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		return JComponentHelper::filterText($text);
	}

	/**
	 * Adds Count Items for Category Manager.
	 *
	 * @param   stdClass[]  &$items  The category objects
	 *
	 * @return  stdClass[]
	 *
	 * @since   3.5
	 */
	public static function countItems(&$items)
	{
		$config = (object) array(
			'related_tbl'   => 'content',
			'state_col'     => 'state',
			'group_col'     => 'catid',
			'relation_type' => 'category_or_group',
		);

		return parent::countRelations($items, $config);
	}

	/**
	 * Adds Count Items for Tag Manager.
	 *
	 * @param   stdClass[]  &$items     The tag objects
	 * @param   string      $extension  The name of the active view.
	 *
	 * @return  stdClass[]
	 *
	 * @since   3.6
	 */
	public static function countTagItems(&$items, $extension)
	{
		$parts   = explode('.', $extension);
		$section = count($parts) > 1 ? $parts[1] : null;

		$config = (object) array(
			'related_tbl'   => ($section === 'category' ? 'categories' : 'content'),
			'state_col'     => ($section === 'category' ? 'published' : 'state'),
			'group_col'     => 'tag_id',
			'extension'     => $extension,
			'relation_type' => 'tag_assigments',
		);

		return parent::countRelations($items, $config);
	}

	/**
	 * Returns a valid section for articles. If it is not valid then null
	 * is returned.
	 *
	 * @param   string  $section  The section to get the mapping for
	 *
	 * @return  string|null  The new section
	 *
	 * @since   3.7.0
	 */
	public static function validateSection($section)
	{
		if (JFactory::getApplication()->isClient('site'))
		{
			// On the front end we need to map some sections
			switch ($section)
			{
				// Editing an article
				case 'form':

				// Category list view
				case 'featured':
				case 'category':
					$section = 'article';
			}
		}

		if ($section != 'article')
		{
			// We don't know other sections
			return null;
		}

		return $section;
	}

	/**
	 * Returns valid contexts
	 *
	 * @return  array
	 *
	 * @since   3.7.0
	 */
	public static function getContexts()
	{
		JFactory::getLanguage()->load('com_content', JPATH_ADMINISTRATOR);

		$contexts = array(
			'com_content.article'    => JText::_('COM_CONTENT'),
			'com_content.categories' => JText::_('JCATEGORY')
		);

		return $contexts;
	}
}
PKm"]��1OXXhtml/system.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_admin
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Utility class working with system
 *
 * @since  1.6
 */
abstract class JHtmlSystem
{
	/**
	 * Method to generate a string message for a value
	 *
	 * @param   string  $val  a php ini value
	 *
	 * @return  string html code
	 */
	public static function server($val)
	{
		return !empty($val) ? $val : JText::_('COM_ADMIN_NA');
	}
}
PKm"]b<^��html/directory.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_admin
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Utility class working with directory
 *
 * @since  1.6
 */
abstract class JHtmlDirectory
{
	/**
	 * Method to generate a (un)writable message for directory
	 *
	 * @param   boolean  $writable  is the directory writable?
	 *
	 * @return  string	html code
	 */
	public static function writable($writable)
	{
		if ($writable)
		{
			return '<span class="badge badge-success">' . JText::_('COM_ADMIN_WRITABLE') . '</span>';
		}

		return '<span class="badge badge-important">' . JText::_('COM_ADMIN_UNWRITABLE') . '</span>';
	}

	/**
	 * Method to generate a message for a directory
	 *
	 * @param   string   $dir      the directory
	 * @param   boolean  $message  the message
	 * @param   boolean  $visible  is the $dir visible?
	 *
	 * @return  string	html code
	 */
	public static function message($dir, $message, $visible = true)
	{
		$output = $visible ? $dir : '';

		if (empty($message))
		{
			return $output;
		}

		return $output . ' <strong>' . JText::_($message) . '</strong>';
	}
}
PKm"]ȻO�html/phpsetting.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_admin
 *
 * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Utility class working with phpsetting
 *
 * @since  1.6
 */
abstract class JHtmlPhpSetting
{
	/**
	 * Method to generate a boolean message for a value
	 *
	 * @param   boolean  $val  is the value set?
	 *
	 * @return  string html code
	 */
	public static function boolean($val)
	{
		return JText::_($val ? 'JON' : 'JOFF');
	}

	/**
	 * Method to generate a boolean message for a value
	 *
	 * @param   boolean  $val  is the value set?
	 *
	 * @return  string html code
	 */
	public static function set($val)
	{
		return JText::_($val ? 'JYES' : 'JNO');
	}

	/**
	 * Method to generate a string message for a value
	 *
	 * @param   string  $val  a php ini value
	 *
	 * @return  string html code
	 */
	public static function string($val)
	{
		return !empty($val) ? $val : JText::_('JNONE');
	}

	/**
	 * Method to generate an integer from a value
	 *
	 * @param   string  $val  a php ini value
	 *
	 * @return  string html code
	 *
	 * @deprecated  4.0  Use intval() or casting instead.
	 */
	public static function integer($val)
	{
		try
		{
			JLog::add(sprintf('%s() is deprecated. Use intval() or casting instead.', __METHOD__), JLog::WARNING, 'deprecated');
		}
		catch (RuntimeException $exception)
		{
			// Informational log only
		}

		return (int) $val;
	}
}
PK,"]�r�,,contenthistory.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_contenthistory
 *
 * @copyright   (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

/**
 * Categories helper.
 *
 * @since  3.2
 */
class ContenthistoryHelper
{
	/**
	 * Method to put all field names, including nested ones, in a single array for easy lookup.
	 *
	 * @param   stdClass  $object  Standard class object that may contain one level of nested objects.
	 *
	 * @return  array  Associative array of all field names, including ones in a nested object.
	 *
	 * @since   3.2
	 */
	public static function createObjectArray($object)
	{
		$result = array();

		if ($object === null)
		{
			return $result;
		}

		foreach ($object as $name => $value)
		{
			$result[$name] = $value;

			if (is_object($value))
			{
				foreach ($value as $subName => $subValue)
				{
					$result[$subName] = $subValue;
				}
			}
		}

		return $result;
	}

	/**
	 * Method to decode JSON-encoded fields in a standard object. Used to unpack JSON strings in the content history data column.
	 *
	 * @param   stdClass  $jsonString  Standard class object that may contain one or more JSON-encoded fields.
	 *
	 * @return  stdClass  Object with any JSON-encoded fields unpacked.
	 *
	 * @since   3.2
	 */
	public static function decodeFields($jsonString)
	{
		$object = json_decode($jsonString);

		if (is_object($object))
		{
			foreach ($object as $name => $value)
			{
				if ($subObject = json_decode($value))
				{
					$object->$name = $subObject;
				}
			}
		}

		return $object;
	}

	/**
	 * Method to get field labels for the fields in the JSON-encoded object.
	 * First we see if we can find translatable labels for the fields in the object.
	 * We translate any we can find and return an array in the format object->name => label.
	 *
	 * @param   stdClass           $object      Standard class object in the format name->value.
	 * @param   JTableContenttype  $typesTable  Table object with content history options.
	 *
	 * @return  stdClass  Contains two associative arrays.
	 *                    $formValues->labels in the format name => label (for example, 'id' => 'Article ID').
	 *                    $formValues->values in the format name => value (for example, 'state' => 'Published'.
	 *                    This translates the text from the selected option in the form.
	 *
	 * @since   3.2
	 */
	public static function getFormValues($object, JTableContenttype $typesTable)
	{
		$labels = array();
		$values = array();
		$expandedObjectArray = static::createObjectArray($object);
		static::loadLanguageFiles($typesTable->type_alias);

		if ($formFile = static::getFormFile($typesTable))
		{
			if ($xml = simplexml_load_file($formFile))
			{
				// Now we need to get all of the labels from the form
				$fieldArray = $xml->xpath('//field');
				$fieldArray = array_merge($fieldArray, $xml->xpath('//fields'));

				foreach ($fieldArray as $field)
				{
					if ($label = (string) $field->attributes()->label)
					{
						$labels[(string) $field->attributes()->name] = JText::_($label);
					}
				}

				// Get values for any list type fields
				$listFieldArray = $xml->xpath('//field[@type="list" or @type="radio"]');

				foreach ($listFieldArray as $field)
				{
					$name = (string) $field->attributes()->name;

					if (isset($expandedObjectArray[$name]))
					{
						$optionFieldArray = $field->xpath('option[@value="' . $expandedObjectArray[$name] . '"]');

						$valueText = null;

						if (is_array($optionFieldArray) && count($optionFieldArray))
						{
							$valueText = trim((string) $optionFieldArray[0]);
						}

						$values[(string) $field->attributes()->name] = JText::_($valueText);
					}
				}
			}
		}

		$result = new stdClass;
		$result->labels = $labels;
		$result->values = $values;

		return $result;
	}

	/**
	 * Method to get the XML form file for this component. Used to get translated field names for history preview.
	 *
	 * @param   JTableContenttype  $typesTable  Table object with content history options.
	 *
	 * @return  mixed  JModel object if successful, false if no model found.
	 *
	 * @since   3.2
	 */
	public static function getFormFile(JTableContenttype $typesTable)
	{
		$result = false;
		jimport('joomla.filesystem.file');
		jimport('joomla.filesystem.folder');

		// First, see if we have a file name in the $typesTable
		$options = json_decode($typesTable->content_history_options);

		if (is_object($options) && isset($options->formFile) && JFile::exists(JPATH_ROOT . '/' . $options->formFile))
		{
			$result = JPATH_ROOT . '/' . $options->formFile;
		}
		else
		{
			$aliasArray = explode('.', $typesTable->type_alias);

			if (count($aliasArray) == 2)
			{
				$component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0];
				$path  = JFolder::makeSafe(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/');
				$file = JFile::makeSafe($aliasArray[1] . '.xml');
				$result = JFile::exists($path . $file) ? $path . $file : false;
			}
		}

		return $result;
	}

	/**
	 * Method to query the database using values from lookup objects.
	 *
	 * @param   stdClass  $lookup  The std object with the values needed to do the query.
	 * @param   mixed     $value   The value used to find the matching title or name. Typically the id.
	 *
	 * @return  mixed  Value from database (for example, name or title) on success, false on failure.
	 *
	 * @since   3.2
	 */
	public static function getLookupValue($lookup, $value)
	{
		$result = false;

		if (isset($lookup->sourceColumn) && isset($lookup->targetTable) && isset($lookup->targetColumn)&& isset($lookup->displayColumn))
		{
			$db = JFactory::getDbo();
			$query = $db->getQuery(true);
			$query->select($db->quoteName($lookup->displayColumn))
				->from($db->quoteName($lookup->targetTable))
				->where($db->quoteName($lookup->targetColumn) . ' = ' . $db->quote($value));
			$db->setQuery($query);

			try
			{
				$result = $db->loadResult();
			}
			catch (Exception $e)
			{
				// Ignore any errors and just return false
				return false;
			}
		}

		return $result;
	}

	/**
	 * Method to remove fields from the object based on values entered in the #__content_types table.
	 *
	 * @param   stdClass           $object     Object to be passed to view layout file.
	 * @param   JTableContenttype  $typeTable  Table object with content history options.
	 *
	 * @return  stdClass  object with hidden fields removed.
	 *
	 * @since   3.2
	 */
	public static function hideFields($object, JTableContenttype $typeTable)
	{
		if ($options = json_decode($typeTable->content_history_options))
		{
			if (isset($options->hideFields) && is_array($options->hideFields))
			{
				foreach ($options->hideFields as $field)
				{
					unset($object->$field);
				}
			}
		}

		return $object;
	}

	/**
	 * Method to load the language files for the component whose history is being viewed.
	 *
	 * @param   string  $typeAlias  The type alias, for example 'com_content.article'.
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public static function loadLanguageFiles($typeAlias)
	{
		$aliasArray = explode('.', $typeAlias);

		if (is_array($aliasArray) && count($aliasArray) == 2)
		{
			$component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0];
			$lang = JFactory::getLanguage();

			/**
			 * Loading language file from the administrator/language directory then
			 * loading language file from the administrator/components/extension/language directory
			 */
			$lang->load($component, JPATH_ADMINISTRATOR, null, false, true)
			|| $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true);

			// Force loading of backend global language file
			$lang->load('joomla', JPath::clean(JPATH_ADMINISTRATOR), null, false, true);
		}
	}

	/**
	 * Method to create object to pass to the layout. Format is as follows:
	 * field is std object with name, value.
	 *
	 * Value can be a std object with name, value pairs.
	 *
	 * @param   stdClass  $object      The std object from the JSON string. Can be nested 1 level deep.
	 * @param   stdClass  $formValues  Standard class of label and value in an associative array.
	 *
	 * @return  stdClass  Object with translated labels where available
	 *
	 * @since   3.2
	 */
	public static function mergeLabels($object, $formValues)
	{
		$result = new stdClass;

		if ($object === null)
		{
			return $result;
		}

		$labelsArray = $formValues->labels;
		$valuesArray = $formValues->values;

		foreach ($object as $name => $value)
		{
			$result->$name = new stdClass;
			$result->$name->name = $name;
			$result->$name->value = isset($valuesArray[$name]) ? $valuesArray[$name] : $value;
			$result->$name->label = isset($labelsArray[$name]) ? $labelsArray[$name] : $name;

			if (is_object($value))
			{
				$subObject = new stdClass;

				foreach ($value as $subName => $subValue)
				{
					$subObject->$subName = new stdClass;
					$subObject->$subName->name = $subName;
					$subObject->$subName->value = isset($valuesArray[$subName]) ? $valuesArray[$subName] : $subValue;
					$subObject->$subName->label = isset($labelsArray[$subName]) ? $labelsArray[$subName] : $subName;
					$result->$name->value = $subObject;
				}
			}
		}

		return $result;
	}

	/**
	 * Method to prepare the object for the preview and compare views.
	 *
	 * @param   JTableContenthistory  $table  Table object loaded with data.
	 *
	 * @return  stdClass  Object ready for the views.
	 *
	 * @since   3.2
	 */
	public static function prepareData(JTableContenthistory $table)
	{
		$object = static::decodeFields($table->version_data);
		$typesTable = JTable::getInstance('Contenttype');
		$typesTable->load(array('type_id' => $table->ucm_type_id));
		$formValues = static::getFormValues($object, $typesTable);
		$object = static::mergeLabels($object, $formValues);
		$object = static::hideFields($object, $typesTable);
		$object = static::processLookupFields($object, $typesTable);

		return $object;
	}

	/**
	 * Method to process any lookup values found in the content_history_options column for this table.
	 * This allows category title and user name to be displayed instead of the id column.
	 *
	 * @param   stdClass           $object      The std object from the JSON string. Can be nested 1 level deep.
	 * @param   JTableContenttype  $typesTable  Table object loaded with data.
	 *
	 * @return  stdClass  Object with lookup values inserted.
	 *
	 * @since   3.2
	 */
	public static function processLookupFields($object, JTableContenttype $typesTable)
	{
		if ($options = json_decode($typesTable->content_history_options))
		{
			if (isset($options->displayLookup) && is_array($options->displayLookup))
			{
				foreach ($options->displayLookup as $lookup)
				{
					$sourceColumn = isset($lookup->sourceColumn) ? $lookup->sourceColumn : false;
					$sourceValue = isset($object->$sourceColumn->value) ? $object->$sourceColumn->value : false;

					if ($sourceColumn && $sourceValue && ($lookupValue = static::getLookupValue($lookup, $sourceValue)))
					{
						$object->$sourceColumn->value = $lookupValue;
					}
				}
			}
		}

		return $object;
	}
}
PK,"]�Gp��html/textdiff.phpnu&1i�<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_contenthistory
 *
 * @copyright   (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('JPATH_PLATFORM') or die;

/**
 * HTML utility class for creating text diffs using jQuery, diff_patch_match.js and jquery.pretty-text-diff.js JavaScript libraries.
 *
 * @since       3.2
 *
 * @deprecated  4.0 No replacement
 */
abstract class JHtmlTextdiff
{
	/**
	 * @var    array  Array containing information for loaded files
	 * @since  3.2
	 */
	protected static $loaded = array();

	/**
	 * Method to load Javascript text diff
	 *
	 * @param   string  $containerId  DOM id of the element where the diff will be rendered
	 *
	 * @return  void
	 *
	 * @since   3.2
	 */
	public static function textdiff($containerId)
	{
		// Only load once
		if (isset(static::$loaded[__METHOD__]))
		{
			return;
		}

		// Depends on jQuery UI
		JHtml::_('bootstrap.framework');
		JHtml::_('script', 'com_contenthistory/diff_match_patch.js', array('version' => 'auto', 'relative' => true));
		JHtml::_('script', 'com_contenthistory/jquery.pretty-text-diff.min.js', array('version' => 'auto', 'relative' => true));
		JHtml::_('stylesheet', 'com_contenthistory/jquery.pretty-text-diff.css', array('version' => 'auto', 'relative' => true));

		// Attach diff to document
		JFactory::getDocument()->addScriptDeclaration("
			(function ($){
				$(document).ready(function (){
 					$('#" . $containerId . " tr').prettyTextDiff();
 				});
			})(jQuery);
			"
		);

		// Set static array
		static::$loaded[__METHOD__] = true;

		return;
	}
}
PKAt!]��M�TT	route.phpnu&1i�PKBt!]�1Q����xmap.phpnu&1i�PKBt!]�#o,,
�index.htmlnu&1i�PK�t!]8�'��
mailto.phpnu&1i�PK�z!]u#ų�M�M
Lfields.phpnu&1i�PKT|!]ꠠ�
�
zehtml/banner.phpnu&1i�PKT|!]m�~'``�pbanners.phpnu&1i�PKW|!]��c��/�html/finder.phpnu&1i�PKW|!]�l(��9�9�indexer/indexer.phpnu&1i�PKW|!]C�y/'/'��indexer/taxonomy.phpnu&1i�PKW|!]��ѳ����e�indexer/query.phpnu&1i�PKW|!]���~LLc}indexer/driver/mysql.phpnu&1i�PKW|!]����h?h?��indexer/driver/postgresql.phpnu&1i�PKW|!][i��:G:Gp	indexer/driver/sqlsrv.phpnu&1i�PKW|!]��''�Pindexer/stemmer/porter_en.phpnu&1i�PKW|!]��9�[([(Kxindexer/stemmer/fr.phpnu&1i�PKW|!]�hU8�
�
�indexer/stemmer/snowball.phpnu&1i�PKW|!]�� ""�indexer/result.phpnu&1i�PKW|!]⁵��[�indexer/token.phpnu&1i�PKW|!]��&��K�indexer/parser/txt.phpnu&1i�PKW|!]����nno�indexer/parser/html.phpnu&1i�PKW|!]{�;  $�indexer/parser/rtf.phpnu&1i�PKW|!]<���8�8��indexer/helper.phpnu&1i�PKW|!]�W��U�Us0indexer/adapter.phpnu&1i�PKW|!]OB"d��p�indexer/parser.phpnu&1i�PKW|!]ƣj�vv��indexer/stemmer.phpnu&1i�PKW|!]�u�AC	C	
:�finder.phpnu&1i�PKW|!]������language.phpnu&1i�PK[|!]���\#\#
	�search.phpnu&1i�PK[|!]'˂����site.phpnu&1i�PK\|!]c������joomlaupdate.phpnu&1i�PK\|!]��CK��
��select.phpnu&1i�PK`|!]�E�-�
�
��html/messages.phpnu&1i�PK`|!]6-ll��messages.phpnu&1i�PK�|!](��	�	M�html/newsfeed.phpnu&1i�PK�|!]I�����
��newsfeeds.phpnu&1i�PK�|!]v�@�
�
�associations.phpnu&1i�PK�|!]k�+m"m"�icagenda.phpnu&1i�PK�|!]
:i��X5html/events.phpnu&1i�PK�|!]�6��;html/index.htmlnu&1i�PKw}!]X�1�7�7�;html/filter.phpnu&1i�PKw}!]�ش����shtml/query.phpnu&1i�PK�}!]�s�1��	�media.phpnu&1i�PK�!]WcH����category.phpnu&1i�PK�!]Aؽb��
&�banner.phpnu&1i�PKl�!]��bb	1�cache.phpnu&1i�PK�!]���qb$b$̩actionlogs.phpnu&1i�PK�!]�� 8i
i
l�actionlogsphp55.phpnu&1i�PK�!]j�/�			�users.phpnu&1i�PK�!]��TA��Z�html/users.phpnu&1i�PK�!]=ΓsKK	Ydebug.phpnu&1i�PKM�!]�:L���multilangstatus.phpnu&1i�PKM�!]Nbf��;html/languages.phpnu&1i�PKM�!]RQ-��
�
IDjsonresponse.phpnu&1i�PKM�!]��1��
<Olanguages.phpnu&1i�PKh�!]�����([association.phpnu&1i�PKh�!]�o��>licon.phpnu&1i�PKh�!]�oh			q�query.phpnu&1i�PKh�!]coJ�o'o'��legacyrouter.phpnu&1i�PK"�!]^�Vrrb�html/modules.phpnu&1i�PK"�!]���&#&#�modules.phpnu&1i�PK"�!]GU����u	xml.phpnu&1i�PK�!]�‚-vv�tags.phpnu&1i�PKB�!]��L�
�
.djimageslider.phpnu&1i�PKS�!]��nhtml/contact.phpnu&1i�PKS�!]�	����.contact.phpnu&1i�PKv�!]Z�|N>K>K
�=helper.phpnu&1i�PKv�!]N��++*�source/slidesmanager.phpnu&1i�PKv�!]�!	˔�
��ckfile.phpnu&1i�PKv�!]V��.	.	k�defines.phpnu&1i�PKv�!]S��bnn
ԣcktext.phpnu&1i�PKv�!]�[�gg	|�ckuri.phpnu&1i�PKv�!]�O�s���ckbrowse.phpnu&1i�PKv�!]���l�l�?�ckstyles.phpnu&1i�PKv�!]���ee�ckframework.phpnu&1i�PKv�!]�/㆞�����ckinterface.phpnu&1i�PKv�!]0����
h5ckpath.phpnu&1i�PKv�!]�nn66ckinput.phpnu&1i�PKv�!]·D���
�6ckview.phpnu&1i�PKv�!]{�Bmm�;ckcontroller.phpnu&1i�PKv�!];�a(4(4	�Yckfof.phpnu&1i�PKv�!]��h�����defines.js.phpnu&1i�PKv�!]�����ܒckfolder.phpnu&1i�PKv�!]��a5�7�7
��htmlfixer.phpnu&1i�PKv�!]�|�o
o
��ckmodel.phpnu&1i�PK�!]�����6�6	��menus.phpnu&1i�PK�!]l22���	html/menus.phpnu&1i�PKϠ!]=���
�
�&	html/templates.phpnu&1i�PKϠ!].��u�1	template.phpnu&1i�PKϠ!]�cYeii
�F	templates.phpnu&1i�PK;�!]Nj���
�X	plugin.phpnu&1i�PK;�!]�P�\g	export/domain.phpnu&1i�PK;�!]�H8����l	export/item.phpnu&1i�PK;�!]y��,,�q	export/field.phpnu&1i�PK;�!]=*N�s	html/helper.phpnu&1i�PK;�!]�:�<<Ex	removal/status.phpnu&1i�PK;�!]�7��{	privacy.phpnu&1i�PKP�!]F0fb11
�	html/xmap.phpnu&1i�PK��!]6�yC��
��	installer.phpnu&1i�PK��!]�'�a����	html/manage.phpnu&1i�PK��!]�3��YY֥	html/updatesites.phpnu&1i�PK5�!]J6XXs�	encrypt/aes.phpnu&1i�PK5�!]t�3Ɨ%�%�
plugins.jsonnu&1i�PK5�!]���SS
�)
commands.jsonnu&1i�PK5�!]��8�||39
encrypt.phpnu&1i�PK5�!]-�)3jj	�I
admin.phpnu&1i�PK5�!]`$z�/�/�Q
profiles.phpnu&1i�PK5�!]�=T�8�8�
plugins.phpnu&1i�PK5�!]Uէ���
:�
parameter.phpnu&1i�PK5�!]�7ċ��K�
browser.phpnu&1i�PK5�!]�����
~�
extension.phpnu&1i�PK��!]I��,����
html/contentadministrator.phpnu&1i�PK��!]�*\�����
content.phpnu&1i�PKm"]��1OXX�html/system.phpnu&1i�PKm"]b<^��shtml/directory.phpnu&1i�PKm"]ȻO��html/phpsetting.phpnu&1i�PK,"]�r�,,�contenthistory.phpnu&1i�PK,"]�Gp��9;html/textdiff.phpnu&1i�PKvv($B