403Webshell
Server IP : 172.67.191.97  /  Your IP : 104.23.243.196
Web Server : Apache/2.4.63 (Ubuntu)
System : Linux adminpruebas-Virtual-Machine 6.14.0-37-generic #37-Ubuntu SMP PREEMPT_DYNAMIC Fri Nov 14 22:10:32 UTC 2025 x86_64
User : www-data ( 33)
PHP Version : 8.4.5
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /proc/self/root/var/www/biblioteca/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/self/root/var/www/biblioteca/js/tutoriales.js
const tutorialsRoot = document.querySelector('[data-tutorials-root]');
const tutorialsDataNode = document.getElementById('tutorialsData');

if (tutorialsRoot && tutorialsDataNode) {
  let tutorials = [];

  try {
    tutorials = JSON.parse(tutorialsDataNode.textContent || '[]');
  } catch (error) {
    tutorials = [];
  }

  if (Array.isArray(tutorials) && tutorials.length > 0) {
    const stage = document.getElementById('tutorialStage');
    const viewerFrame = document.getElementById('tutorialViewerFrame');
    const titleNode = document.getElementById('tutorialTitle');
    const descriptionNode = document.getElementById('tutorialDescription');
    const sourceNode = document.getElementById('tutorialSource');
    const providerNode = document.getElementById('tutorialProvider');
    const openLink = document.getElementById('tutorialOpenLink');
    const buttons = Array.from(tutorialsRoot.querySelectorAll('.tutorial-trigger'));
    const groupNodes = Array.from(tutorialsRoot.querySelectorAll('.tutorial-group'));
    const groupToggles = Array.from(tutorialsRoot.querySelectorAll('[data-group-toggle]'));
    const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');

    let activeId = tutorialsRoot.getAttribute('data-initial-tutorial') || tutorials[0].id;
    let switchToken = 0;
    let readyTimeoutId = 0;

    const getTutorialById = (id) => tutorials.find((item) => item.id === id);

    const buildFallback = (item) => {
      const wrapper = document.createElement('div');
      const inner = document.createElement('div');
      const heading = document.createElement('h3');
      const text = document.createElement('p');

      wrapper.className = 'tutorial-fallback';
      heading.textContent = item?.name || 'Tutorial';
      text.textContent = item?.fallback_message || 'Este tutorial aun no tiene un video asociado.';

      inner.append(heading, text);
      wrapper.append(inner);
      return wrapper;
    };

    const buildMedia = (item) => {
      const source = item?.source || {};

      if (item?.source_type === 'local') {
        const video = document.createElement('video');
        const mediaSource = document.createElement('source');

        video.className = 'tutorial-media';
        video.controls = true;
        video.preload = 'metadata';

        mediaSource.src = item?.embed_url || '';
        mediaSource.type = source.mime || 'video/mp4';
        video.appendChild(mediaSource);

        return {
          element: video,
          readyEvent: 'loadeddata',
        };
      }

      const iframe = document.createElement('iframe');
      iframe.className = 'tutorial-media';
      iframe.src = item?.embed_url || '';
      iframe.title = `Tutorial de ${item?.name || 'recurso'}`;
      iframe.loading = 'eager';
      iframe.referrerPolicy = 'strict-origin-when-cross-origin';
      iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share';
      iframe.allowFullscreen = true;

      return {
        element: iframe,
        readyEvent: 'load',
      };
    };

    const setGroupState = (groupKey, isOpen) => {
      const group = groupNodes.find((node) => node.dataset.tutorialGroup === groupKey);
      if (!group) return;

      const toggle = group.querySelector('[data-group-toggle]');
      const panel = group.querySelector('.tutorials-group-panel');
      if (!toggle || !panel) return;

      group.classList.toggle('is-open', isOpen);
      toggle.setAttribute('aria-expanded', String(isOpen));
      panel.hidden = !isOpen;
    };

    const ensureGroupOpen = (groupKey) => {
      if (!groupKey) return;
      setGroupState(groupKey, true);
    };

    const finishLoading = (token) => {
      if (token !== switchToken || !stage || !viewerFrame) return;

      stage.classList.remove('is-loading');
      window.clearTimeout(readyTimeoutId);

      window.setTimeout(() => {
        if (token === switchToken) {
          stage.classList.remove('is-switching');
        }
      }, 220);

      viewerFrame.setAttribute('aria-busy', 'false');
    };

    const renderTutorial = (id, options = {}) => {
      const item = getTutorialById(id);
      if (!item || !stage || !viewerFrame || !titleNode || !descriptionNode || !sourceNode || !providerNode || !openLink) {
        return;
      }

      const shouldScroll = Boolean(options.scrollIntoView);
      switchToken += 1;
      activeId = item.id;

      buttons.forEach((button) => {
        const isActive = button.dataset.tutorialId === item.id;
        button.classList.toggle('is-active', isActive);
        button.setAttribute('aria-selected', String(isActive));
      });

      ensureGroupOpen(item.category || '');

      stage.style.setProperty('--tutorial-accent', item.accent || '#b5121b');
      stage.setAttribute('aria-labelledby', `tutorial-tab-${item.id}`);
      stage.classList.remove('has-error');
      stage.classList.add('is-loading', 'is-switching');

      titleNode.textContent = item.name || '';
      descriptionNode.textContent = item.description || '';
      sourceNode.textContent = item.source_label || 'Pendiente';
      providerNode.textContent = item.provider || '';

      const openUrl = item.open_url || '';
      openLink.href = openUrl || '#';
      openLink.textContent = item.source_type === 'local'
        ? 'Abrir video local'
        : openUrl
          ? 'Abrir fuente original'
          : 'Video pendiente';
      openLink.classList.toggle('is-disabled', !openUrl);

      if (openUrl) {
        openLink.setAttribute('target', '_blank');
        openLink.setAttribute('rel', 'noopener noreferrer');
        openLink.removeAttribute('aria-disabled');
        openLink.removeAttribute('tabindex');
      } else {
        openLink.removeAttribute('target');
        openLink.removeAttribute('rel');
        openLink.setAttribute('aria-disabled', 'true');
        openLink.setAttribute('tabindex', '-1');
      }

      viewerFrame.setAttribute('aria-busy', 'true');
      viewerFrame.innerHTML = '';

      if (!item.has_media) {
        viewerFrame.appendChild(buildFallback(item));
        finishLoading(switchToken);
        return;
      }

      const token = switchToken;
      const media = buildMedia(item);
      const onReady = () => finishLoading(token);
      const onError = () => {
        if (token !== switchToken) return;

        stage.classList.remove('is-loading');
        viewerFrame.setAttribute('aria-busy', 'false');
        viewerFrame.innerHTML = '';
        viewerFrame.appendChild(buildFallback(item));
      };

      media.element.addEventListener(media.readyEvent, onReady, { once: true });
      media.element.addEventListener('error', onError, { once: true });
      viewerFrame.appendChild(media.element);

      window.clearTimeout(readyTimeoutId);
      readyTimeoutId = window.setTimeout(onReady, item.source_type === 'local' ? 450 : 900);

      if (shouldScroll && window.innerWidth < 960) {
        stage.scrollIntoView({
          behavior: reducedMotion.matches ? 'auto' : 'smooth',
          block: 'start',
        });
      }
    };

    const moveSelection = (currentButton, direction) => {
      const visibleButtons = buttons.filter((button) => !button.closest('.tutorials-group-panel')?.hidden);
      const currentIndex = visibleButtons.indexOf(currentButton);
      if (currentIndex === -1) return;

      let nextIndex = currentIndex;

      if (direction === 'next') {
        nextIndex = (currentIndex + 1) % visibleButtons.length;
      } else if (direction === 'prev') {
        nextIndex = (currentIndex - 1 + visibleButtons.length) % visibleButtons.length;
      } else if (direction === 'first') {
        nextIndex = 0;
      } else if (direction === 'last') {
        nextIndex = visibleButtons.length - 1;
      }

      const nextButton = visibleButtons[nextIndex];
      if (!nextButton) return;

      nextButton.focus();
      renderTutorial(nextButton.dataset.tutorialId || activeId);
    };

    buttons.forEach((button) => {
      button.addEventListener('click', () => {
        const id = button.dataset.tutorialId || activeId;
        renderTutorial(id, { scrollIntoView: true });
      });

      button.addEventListener('keydown', (event) => {
        if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
          event.preventDefault();
          moveSelection(button, 'next');
        }

        if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
          event.preventDefault();
          moveSelection(button, 'prev');
        }

        if (event.key === 'Home') {
          event.preventDefault();
          moveSelection(button, 'first');
        }

        if (event.key === 'End') {
          event.preventDefault();
          moveSelection(button, 'last');
        }
      });
    });

    groupToggles.forEach((toggle) => {
      toggle.addEventListener('click', () => {
        const group = toggle.closest('.tutorial-group');
        const groupKey = group?.dataset.tutorialGroup || '';
        const isOpen = toggle.getAttribute('aria-expanded') === 'true';
        setGroupState(groupKey, !isOpen);
      });
    });

    if (!getTutorialById(activeId)) {
      renderTutorial(tutorials[0].id);
    }
  }
}

Youez - 2016 - github.com/yon3zu
LinuXploit