function recurseCats($id, $itemsByCats, $catChildrenByCats, $level = 0, $asCategoryTitleField, $liveSite, $targetOption, $targetView, $targetViewName, $additionalQueryStringParams, $openTarget, $arrayKeysDiff, $titleIdentifier, $idIdentifier, $idURLFilter, $catidIdentifier, $catidURLFilter, $supportedRouterHelperAdapters, $guessItemid, $mainTable)
 {
     if (isset($catChildrenByCats[$id])) {
         foreach ($catChildrenByCats[$id] as $catChild) {
             $itemsOfCategory = isset($itemsByCats[$catChild['id']]) ? $itemsByCats[$catChild['id']] : null;
             $catTitleName = $catChild['catname'];
             // Multilevel tree for items and parent containing cats
             if ($asCategoryTitleField) {
                 // Set for empty category root nodes that should not be clickable
                 $noExpandableNode = count($itemsOfCategory) ? '' : ' noexpandable';
                 echo '<ul class="jmap_filetree" style="margin-left:' . $level * 15 . 'px"><li class="' . $noExpandableNode . '"><span class="folder">' . $catTitleName . '</span>';
                 echo '<ul>';
             } else {
                 // Multilevel tree of categories itself
                 echo '<ul style="margin-left:' . $level * 15 . 'px">';
             }
             if (count($itemsOfCategory)) {
                 foreach ($itemsOfCategory as $elm) {
                     $title = isset($titleIdentifier) && $titleIdentifier != '' ? $elm->{$titleIdentifier} : null;
                     // Additional fields
                     $additionalParamsQueryString = null;
                     $objectVars = array_diff_key(get_object_vars($elm), $arrayKeysDiff);
                     // Filter URL safe alias fields id/catid
                     if (isset($objectVars[$idIdentifier]) && $idURLFilter) {
                         $objectVars[$idIdentifier] = JFilterOutput::stringURLSafe($objectVars[$idIdentifier]);
                     }
                     if (isset($objectVars[$catidIdentifier]) && $catidURLFilter) {
                         $objectVars[$catidIdentifier] = JFilterOutput::stringURLSafe($objectVars[$catidIdentifier]);
                     }
                     if (is_array($objectVars) && count($objectVars)) {
                         $additionalQueryStringFromObjectProp = '&' . http_build_query($objectVars);
                     }
                     if (isset($supportedRouterHelperAdapters[$targetOption]) && $supportedRouterHelperAdapters[$targetOption]) {
                         include 'adapters/' . $targetOption . '.php';
                     } else {
                         $guessedItemid = null;
                         if ($guessItemid) {
                             $guessedItemid = JMapRouteHelper::getItemRoute($targetOption, $targetViewName, $elm->{$idIdentifier}, $elm, $mainTable);
                             if ($guessedItemid) {
                                 $guessedItemid = '&Itemid=' . $guessedItemid;
                             }
                         }
                         $seflink = JRoute::_('index.php?option=' . $targetOption . $targetView . $additionalQueryStringFromObjectProp . $additionalQueryStringParams . $guessedItemid);
                     }
                     echo '<li>' . '<a target="' . $openTarget . '" href="' . $liveSite . $seflink . '" >' . $title . '</a></li>';
                 }
             }
             echo '</ul>';
             if ($asCategoryTitleField) {
                 echo '</li></ul>';
             }
             recurseCats($catChild['id'], $itemsByCats, $catChildrenByCats, $level + 1, $asCategoryTitleField, $liveSite, $targetOption, $targetView, $targetViewName, $additionalQueryStringParams, $openTarget, $arrayKeysDiff, $titleIdentifier, $idIdentifier, $idURLFilter, $catidIdentifier, $catidURLFilter, $supportedRouterHelperAdapters, $guessItemid, $mainTable);
         }
     }
 }
}
// Include common template init
include 'default_common_user.php';
// Check if linkable cats is enabled to inject vars into js domain
$sitemapTemplate = $this->cparams->get('sitemap_html_template', '');
$isMindMap = $sitemapTemplate == 'mindmap' ? true : false;
if (($linkableCatsMode = $this->sourceparams->get('linkable_cats', null)) && !$isMindMap) {
    $this->document->addScriptDeclaration('jmapLinkableCatsSources["' . $targetOption . '"] = "' . $linkableCatsMode . '";');
}
if (count($this->source->data)) {
    // If categorization detected for datasource elements according to adiacency/multi adiacency setup, Feature Detection
    if (isset($this->source->catRecursion) && isset($this->source->itemsByCat) && isset($this->source->catChildrenByCat)) {
        $hasCategoryNamespace = (bool) (isset($this->asCategoryTitleField) && $this->asCategoryTitleField) ? '.items' : null;
        echo '<ul class="jmap_filetree" data-hash="' . $targetOption . $hasCategoryNamespace . '"><li><span class="folder">' . $sourceTitle . '</span>';
        // Start building tree
        recurseCats(0, $this->source->itemsByCat, $this->source->catChildrenByCat, 0, $this->asCategoryTitleField, $this->liveSite, $targetOption, $targetView, $targetViewName, $additionalQueryStringParams, $openTarget, $arrayKeysDiff, $titleIdentifier, $idIdentifier, $idURLFilter, $catidIdentifier, $catidURLFilter, $supportedRouterHelperAdapters, $guessItemid, $mainTable);
        echo '</ul></li></ul></li></ul>';
    } elseif (isset($this->source->data[0]->{$this->asCategoryTitleField}) || isset($this->source->data[0]->jsitemap_level)) {
        $first = true;
        $catsave = null;
        $catRecursion = false;
        $liIndent = null;
        $hasValidCategoryTitleField = (bool) (isset($this->asCategoryTitleField) && $this->asCategoryTitleField);
        $hasCategoryNamespace = $hasValidCategoryTitleField ? '.items' : null;
        // Manage levels, Feature Detection
        if (isset($this->source->catRecursion) && isset($this->source->data[0]->jsitemap_level) && $this->source->recursionType == 'level') {
            $catRecursion = true;
        }
        echo '<ul class="jmap_filetree" data-hash="' . $targetOption . $hasCategoryNamespace . '"><li><span class="folder">' . $sourceTitle . '</span>';
        foreach ($this->source->data as $elm) {
            // Calculate element indentation, Feature Detection