fix share btn
This commit is contained in:
		
							parent
							
								
									20682ef682
								
							
						
					
					
						commit
						6918df9348
					
				@ -193,6 +193,16 @@ domains.forEach((domain: any) => {
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script define:vars={{ toolsData: tools, domainAgnosticSoftware, domainAgnosticTools }}>
 | 
			
		||||
  // Ensure isToolHosted is available
 | 
			
		||||
  if (!window.isToolHosted) {
 | 
			
		||||
    window.isToolHosted = function(tool) {
 | 
			
		||||
      return tool.projectUrl !== undefined && 
 | 
			
		||||
             tool.projectUrl !== null && 
 | 
			
		||||
             tool.projectUrl !== "" && 
 | 
			
		||||
             tool.projectUrl.trim() !== "";
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getSelectedPhase() {
 | 
			
		||||
    const activePhaseChip = document.querySelector('.phase-chip.active');
 | 
			
		||||
    return activePhaseChip ? activePhaseChip.getAttribute('data-phase') : '';
 | 
			
		||||
@ -216,9 +226,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    
 | 
			
		||||
    if (selectedDomain) {
 | 
			
		||||
      const domainRow = matrixTable.querySelector(`tr[data-domain="${selectedDomain}"]`);
 | 
			
		||||
      if (domainRow) {
 | 
			
		||||
        domainRow.classList.add('highlight-row');
 | 
			
		||||
      }
 | 
			
		||||
      if (domainRow) domainRow.classList.add('highlight-row');
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (selectedPhase) {
 | 
			
		||||
@ -231,9 +239,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
        const columnIndex = phaseIndex + 1; 
 | 
			
		||||
        matrixTable.querySelectorAll(`tr`).forEach(row => {
 | 
			
		||||
          const cell = row.children[columnIndex];
 | 
			
		||||
          if (cell) {
 | 
			
		||||
            cell.classList.add('highlight-column');
 | 
			
		||||
          }
 | 
			
		||||
          if (cell) cell.classList.add('highlight-column');
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -267,9 +273,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    const params = new URLSearchParams();
 | 
			
		||||
    params.set('tool', toolSlug);
 | 
			
		||||
    params.set('view', view);
 | 
			
		||||
    if (modal) {
 | 
			
		||||
      params.set('modal', modal);
 | 
			
		||||
    }
 | 
			
		||||
    if (modal) params.set('modal', modal);
 | 
			
		||||
    return `${baseUrl}?${params.toString()}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -301,7 +305,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  window.showShareDialog = function(shareButton) {
 | 
			
		||||
  function showShareDialog(shareButton) {
 | 
			
		||||
    const toolName = shareButton.getAttribute('data-tool-name');
 | 
			
		||||
    const context = shareButton.getAttribute('data-context');
 | 
			
		||||
    
 | 
			
		||||
@ -438,16 +442,11 @@ domains.forEach((domain: any) => {
 | 
			
		||||
        copyToClipboard(url, btn);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  window.toggleDomainAgnosticSection = toggleDomainAgnosticSection;
 | 
			
		||||
 | 
			
		||||
  window.showToolDetails = function(toolName, modalType = 'primary') {
 | 
			
		||||
  function showToolDetails(toolName, modalType = 'primary') {
 | 
			
		||||
    const tool = toolsData.find(t => t.name === toolName);
 | 
			
		||||
    if (!tool) {
 | 
			
		||||
      console.error('Tool not found:', toolName);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!tool) return;
 | 
			
		||||
    
 | 
			
		||||
    const isMethod = tool.type === 'method';
 | 
			
		||||
    const isConcept = tool.type === 'concept';
 | 
			
		||||
@ -462,10 +461,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    for (const [key, element] of Object.entries(elements)) {
 | 
			
		||||
      if (!element) {
 | 
			
		||||
        console.error(`Element not found: tool-${key}-${modalType}`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if (!element) return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const iconHtml = tool.icon ? `<span class="mr-3 text-xl">${tool.icon}</span>` : '';
 | 
			
		||||
@ -709,9 +705,9 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    if (primaryActive && secondaryActive) {
 | 
			
		||||
      document.body.classList.add('modals-side-by-side');
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  window.hideToolDetails = function(modalType = 'both') {
 | 
			
		||||
  function hideToolDetails(modalType = 'both') {
 | 
			
		||||
    const overlay = document.getElementById('modal-overlay');
 | 
			
		||||
    const primaryModal = document.getElementById('tool-details-primary');
 | 
			
		||||
    const secondaryModal = document.getElementById('tool-details-secondary');
 | 
			
		||||
@ -763,11 +759,22 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    } else {
 | 
			
		||||
      document.body.classList.remove('modals-side-by-side');
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  window.hideAllToolDetails = function() {
 | 
			
		||||
    window.hideToolDetails('both');
 | 
			
		||||
  };
 | 
			
		||||
  function hideAllToolDetails() {
 | 
			
		||||
    hideToolDetails('both');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Register all functions globally
 | 
			
		||||
  window.showToolDetails = showToolDetails;
 | 
			
		||||
  window.hideToolDetails = hideToolDetails;
 | 
			
		||||
  window.hideAllToolDetails = hideAllToolDetails;
 | 
			
		||||
  window.toggleDomainAgnosticSection = toggleDomainAgnosticSection;
 | 
			
		||||
  window.showShareDialog = showShareDialog;
 | 
			
		||||
 | 
			
		||||
  // Register matrix-prefixed versions for delegation
 | 
			
		||||
  window.matrixShowToolDetails = showToolDetails;
 | 
			
		||||
  window.matrixHideToolDetails = hideToolDetails;
 | 
			
		||||
 | 
			
		||||
  window.addEventListener('viewChanged', (event) => {
 | 
			
		||||
    const view = event.detail;
 | 
			
		||||
@ -798,13 +805,6 @@ domains.forEach((domain: any) => {
 | 
			
		||||
      const domainAgnosticPhaseIds = domainAgnosticSoftware.map(section => section.id);
 | 
			
		||||
      const isDomainAgnosticPhase = domainAgnosticPhaseIds.includes(selectedPhase);
 | 
			
		||||
      
 | 
			
		||||
      domainAgnosticSoftware.forEach(sectionData => {
 | 
			
		||||
        const section = document.getElementById(`domain-agnostic-section-${sectionData.id}`);
 | 
			
		||||
        const container = document.getElementById(`domain-agnostic-tools-${sectionData.id}`);
 | 
			
		||||
        
 | 
			
		||||
        if (!section || !container) return;
 | 
			
		||||
      });
 | 
			
		||||
      
 | 
			
		||||
      if (!isDomainAgnosticPhase) {
 | 
			
		||||
        document.getElementById('dfir-matrix-section').style.display = 'block';
 | 
			
		||||
        
 | 
			
		||||
@ -813,9 +813,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        filtered.forEach(tool => {
 | 
			
		||||
          if (tool.type === 'concept') {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          if (tool.type === 'concept') return;
 | 
			
		||||
          
 | 
			
		||||
          const isMethod = tool.type === 'method';
 | 
			
		||||
          const hasValidProjectUrl = window.isToolHosted(tool);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								src/env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								src/env.d.ts
									
									
									
									
										vendored
									
									
								
							@ -11,6 +11,9 @@ declare global {
 | 
			
		||||
    showToolDetails: (toolName: string, modalType?: string) => void;
 | 
			
		||||
    hideToolDetails: (modalType?: string) => void;
 | 
			
		||||
    hideAllToolDetails: () => void;
 | 
			
		||||
    matrixShowToolDetails?: (toolName: string, modalType?: string) => void;
 | 
			
		||||
    matrixHideToolDetails?: (modalType?: string) => void;
 | 
			
		||||
    
 | 
			
		||||
    toggleKbEntry: (entryId: string) => void;
 | 
			
		||||
    toggleDomainAgnosticSection: (sectionId: string) => void;
 | 
			
		||||
    restoreAIResults?: () => void;
 | 
			
		||||
 | 
			
		||||
@ -26,20 +26,41 @@ const { title, description = 'ForensicPathways - A comprehensive directory of di
 | 
			
		||||
  
 | 
			
		||||
<script>
 | 
			
		||||
  async function loadUtilityFunctions() {
 | 
			
		||||
    try {
 | 
			
		||||
      const { createToolSlug, findToolByIdentifier, isToolHosted } = await import('../utils/clientUtils.js');
 | 
			
		||||
      
 | 
			
		||||
      (window as any).createToolSlug = createToolSlug;
 | 
			
		||||
      (window as any).findToolByIdentifier = findToolByIdentifier;
 | 
			
		||||
      (window as any).isToolHosted = isToolHosted;
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      console.error('Failed to load utility functions:', error);
 | 
			
		||||
      (window as any).createToolSlug = (toolName: string) => {
 | 
			
		||||
        if (!toolName || typeof toolName !== 'string') return '';
 | 
			
		||||
        return toolName.toLowerCase().replace(/[^a-z0-9\s-]/g, '').replace(/\s+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
 | 
			
		||||
      };
 | 
			
		||||
      try {
 | 
			
		||||
        const { createToolSlug, findToolByIdentifier, isToolHosted } = await import('../utils/clientUtils.js');
 | 
			
		||||
        
 | 
			
		||||
        (window as any).createToolSlug = createToolSlug;
 | 
			
		||||
        (window as any).findToolByIdentifier = findToolByIdentifier;
 | 
			
		||||
        (window as any).isToolHosted = isToolHosted;
 | 
			
		||||
        
 | 
			
		||||
        console.log('[UTILS] Utility functions loaded successfully');
 | 
			
		||||
      } catch (error) {
 | 
			
		||||
        console.error('Failed to load utility functions:', error);
 | 
			
		||||
        
 | 
			
		||||
        // Provide fallback implementations
 | 
			
		||||
        (window as any).createToolSlug = (toolName: string) => {
 | 
			
		||||
          if (!toolName || typeof toolName !== 'string') return '';
 | 
			
		||||
          return toolName.toLowerCase().replace(/[^a-z0-9\s-]/g, '').replace(/\s+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        (window as any).findToolByIdentifier = (tools: any[], identifier: string) => {
 | 
			
		||||
          if (!identifier || !Array.isArray(tools)) return undefined;
 | 
			
		||||
          return tools.find((tool: any) => 
 | 
			
		||||
            tool.name === identifier || 
 | 
			
		||||
            (window as any).createToolSlug(tool.name) === identifier.toLowerCase()
 | 
			
		||||
          );
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        (window as any).isToolHosted = (tool: any) => {
 | 
			
		||||
          return tool.projectUrl !== undefined && 
 | 
			
		||||
                tool.projectUrl !== null && 
 | 
			
		||||
                tool.projectUrl !== "" && 
 | 
			
		||||
                tool.projectUrl.trim() !== "";
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        console.log('[UTILS] Fallback utility functions registered');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function scrollToElement(element: Element | null, options = {}) {
 | 
			
		||||
    if (!element) return;
 | 
			
		||||
@ -97,8 +118,9 @@ const { title, description = 'ForensicPathways - A comprehensive directory of di
 | 
			
		||||
  (window as any).scrollToElementBySelector = scrollToElementBySelector;
 | 
			
		||||
  (window as any).prioritizeSearchResults = prioritizeSearchResults;
 | 
			
		||||
 | 
			
		||||
  document.addEventListener('DOMContentLoaded', () => {
 | 
			
		||||
    loadUtilityFunctions();
 | 
			
		||||
  document.addEventListener('DOMContentLoaded', async () => {
 | 
			
		||||
    // CRITICAL: Load utility functions FIRST before any URL handling
 | 
			
		||||
    await loadUtilityFunctions();
 | 
			
		||||
    
 | 
			
		||||
    const THEME_KEY = 'dfir-theme';
 | 
			
		||||
 | 
			
		||||
@ -150,6 +172,44 @@ const { title, description = 'ForensicPathways - A comprehensive directory of di
 | 
			
		||||
      toggleTheme,
 | 
			
		||||
      getStoredTheme
 | 
			
		||||
    };
 | 
			
		||||
  
 | 
			
		||||
  (window as any).showToolDetails = function(toolName: string, modalType: string = 'primary') {
 | 
			
		||||
    
 | 
			
		||||
    let attempts = 0;
 | 
			
		||||
    const maxAttempts = 50;
 | 
			
		||||
    
 | 
			
		||||
    const tryDelegate = () => {
 | 
			
		||||
      const matrixShowToolDetails = (window as any).matrixShowToolDetails;
 | 
			
		||||
      
 | 
			
		||||
      if (matrixShowToolDetails && typeof matrixShowToolDetails === 'function') {
 | 
			
		||||
        return matrixShowToolDetails(toolName, modalType);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      const directShowToolDetails = (window as any).directShowToolDetails;
 | 
			
		||||
      if (directShowToolDetails && typeof directShowToolDetails === 'function') {
 | 
			
		||||
        return directShowToolDetails(toolName, modalType);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      attempts++;
 | 
			
		||||
      if (attempts < maxAttempts) {
 | 
			
		||||
        setTimeout(tryDelegate, 100);
 | 
			
		||||
      } else {
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    tryDelegate();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    (window as any).hideToolDetails = function(modalType: string = 'both') {
 | 
			
		||||
      const matrixHideToolDetails = (window as any).matrixHideToolDetails;
 | 
			
		||||
      if (matrixHideToolDetails && typeof matrixHideToolDetails === 'function') {
 | 
			
		||||
        return matrixHideToolDetails(modalType);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    (window as any).hideAllToolDetails = function() {
 | 
			
		||||
      (window as any).hideToolDetails('both');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    async function checkClientAuth(context = 'general') {
 | 
			
		||||
      try {
 | 
			
		||||
 | 
			
		||||
@ -510,6 +510,8 @@ if (aiAuthRequired) {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    function handleSharedURL() {
 | 
			
		||||
      console.log('[SHARE] Handling shared URL:', window.location.search);
 | 
			
		||||
      
 | 
			
		||||
      const urlParams = new URLSearchParams(window.location.search);
 | 
			
		||||
      const toolParam = urlParams.get('tool');
 | 
			
		||||
      const viewParam = urlParams.get('view');
 | 
			
		||||
@ -521,13 +523,19 @@ if (aiAuthRequired) {
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
            
 | 
			
		||||
      if (!window.findToolByIdentifier) {
 | 
			
		||||
        console.error('[SHARE] findToolByIdentifier not available, retrying...');
 | 
			
		||||
        setTimeout(() => handleSharedURL(), 200);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      const tool = window.findToolByIdentifier(window.toolsData, toolParam);
 | 
			
		||||
      if (!tool) {
 | 
			
		||||
        console.warn('Shared tool not found:', toolParam);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
      const cleanUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
 | 
			
		||||
      window.history.replaceState({}, document.title, cleanUrl);
 | 
			
		||||
      
 | 
			
		||||
@ -549,125 +557,125 @@ if (aiAuthRequired) {
 | 
			
		||||
          default:
 | 
			
		||||
            window.navigateToGrid(tool.name);
 | 
			
		||||
        }
 | 
			
		||||
      }, 100);
 | 
			
		||||
      }, 300);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  window.addEventListener('toolsFiltered', (event) => {
 | 
			
		||||
    const { tools: filtered, semanticSearch } = event.detail;
 | 
			
		||||
    const currentView = document.querySelector('.view-toggle.active')?.getAttribute('data-view');
 | 
			
		||||
    
 | 
			
		||||
    if (currentView === 'matrix' || currentView === 'ai') {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const allToolCards = document.querySelectorAll('.tool-card');
 | 
			
		||||
    const filteredNames = new Set(filtered.map(tool => tool.name.toLowerCase()));
 | 
			
		||||
    const toolsContainer = document.getElementById('tools-container');
 | 
			
		||||
    
 | 
			
		||||
    let visibleCount = 0;
 | 
			
		||||
    
 | 
			
		||||
    if (semanticSearch && filtered.length > 0) {
 | 
			
		||||
      console.log('[SEMANTIC] Reordering tools by semantic similarity');
 | 
			
		||||
    window.addEventListener('toolsFiltered', (event) => {
 | 
			
		||||
      const { tools: filtered, semanticSearch } = event.detail;
 | 
			
		||||
      const currentView = document.querySelector('.view-toggle.active')?.getAttribute('data-view');
 | 
			
		||||
      
 | 
			
		||||
      const orderedCards = [];
 | 
			
		||||
      const remainingCards = [];
 | 
			
		||||
      if (currentView === 'matrix' || currentView === 'ai') {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      filtered.forEach(tool => {
 | 
			
		||||
        const toolName = tool.name.toLowerCase();
 | 
			
		||||
        const matchingCard = Array.from(allToolCards).find(card => 
 | 
			
		||||
          card.getAttribute('data-tool-name') === toolName
 | 
			
		||||
        );
 | 
			
		||||
      const allToolCards = document.querySelectorAll('.tool-card');
 | 
			
		||||
      const filteredNames = new Set(filtered.map(tool => tool.name.toLowerCase()));
 | 
			
		||||
      const toolsContainer = document.getElementById('tools-container');
 | 
			
		||||
      
 | 
			
		||||
      let visibleCount = 0;
 | 
			
		||||
      
 | 
			
		||||
      if (semanticSearch && filtered.length > 0) {
 | 
			
		||||
        console.log('[SEMANTIC] Reordering tools by semantic similarity');
 | 
			
		||||
        
 | 
			
		||||
        if (matchingCard) {
 | 
			
		||||
          matchingCard.style.display = 'block';
 | 
			
		||||
          orderedCards.push(matchingCard);
 | 
			
		||||
          visibleCount++;
 | 
			
		||||
        const orderedCards = [];
 | 
			
		||||
        const remainingCards = [];
 | 
			
		||||
        
 | 
			
		||||
        filtered.forEach(tool => {
 | 
			
		||||
          const toolName = tool.name.toLowerCase();
 | 
			
		||||
          const matchingCard = Array.from(allToolCards).find(card => 
 | 
			
		||||
            card.getAttribute('data-tool-name') === toolName
 | 
			
		||||
          );
 | 
			
		||||
          
 | 
			
		||||
          if (tool._semanticSimilarity) {
 | 
			
		||||
            matchingCard.setAttribute('data-semantic-similarity', tool._semanticSimilarity.toFixed(3));
 | 
			
		||||
            matchingCard.setAttribute('data-semantic-rank', tool._semanticRank || '');
 | 
			
		||||
          if (matchingCard) {
 | 
			
		||||
            matchingCard.style.display = 'block';
 | 
			
		||||
            orderedCards.push(matchingCard);
 | 
			
		||||
            visibleCount++;
 | 
			
		||||
            
 | 
			
		||||
            const header = matchingCard.querySelector('.tool-card-header h3');
 | 
			
		||||
            if (header && tool._semanticRank <= 3) {
 | 
			
		||||
              const existingIndicator = header.querySelector('.semantic-rank-indicator');
 | 
			
		||||
              if (existingIndicator) {
 | 
			
		||||
                existingIndicator.remove();
 | 
			
		||||
              }
 | 
			
		||||
            if (tool._semanticSimilarity) {
 | 
			
		||||
              matchingCard.setAttribute('data-semantic-similarity', tool._semanticSimilarity.toFixed(3));
 | 
			
		||||
              matchingCard.setAttribute('data-semantic-rank', tool._semanticRank || '');
 | 
			
		||||
              
 | 
			
		||||
              const indicator = document.createElement('span');
 | 
			
		||||
              indicator.className = 'semantic-rank-indicator';
 | 
			
		||||
              indicator.style.cssText = `
 | 
			
		||||
                display: inline-block;
 | 
			
		||||
                width: 6px;
 | 
			
		||||
                height: 6px;
 | 
			
		||||
                background-color: var(--color-accent);
 | 
			
		||||
                border-radius: 50%;
 | 
			
		||||
                margin-left: 0.5rem;
 | 
			
		||||
                opacity: ${1 - (tool._semanticRank - 1) * 0.3};
 | 
			
		||||
              `;
 | 
			
		||||
              indicator.title = `Semantische Relevanz: ${tool._semanticSimilarity.toFixed(3)}`;
 | 
			
		||||
              header.appendChild(indicator);
 | 
			
		||||
              const header = matchingCard.querySelector('.tool-card-header h3');
 | 
			
		||||
              if (header && tool._semanticRank <= 3) {
 | 
			
		||||
                const existingIndicator = header.querySelector('.semantic-rank-indicator');
 | 
			
		||||
                if (existingIndicator) {
 | 
			
		||||
                  existingIndicator.remove();
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                const indicator = document.createElement('span');
 | 
			
		||||
                indicator.className = 'semantic-rank-indicator';
 | 
			
		||||
                indicator.style.cssText = `
 | 
			
		||||
                  display: inline-block;
 | 
			
		||||
                  width: 6px;
 | 
			
		||||
                  height: 6px;
 | 
			
		||||
                  background-color: var(--color-accent);
 | 
			
		||||
                  border-radius: 50%;
 | 
			
		||||
                  margin-left: 0.5rem;
 | 
			
		||||
                  opacity: ${1 - (tool._semanticRank - 1) * 0.3};
 | 
			
		||||
                `;
 | 
			
		||||
                indicator.title = `Semantische Relevanz: ${tool._semanticSimilarity.toFixed(3)}`;
 | 
			
		||||
                header.appendChild(indicator);
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      
 | 
			
		||||
      allToolCards.forEach(card => {
 | 
			
		||||
        const toolName = card.getAttribute('data-tool-name');
 | 
			
		||||
        if (!filteredNames.has(toolName)) {
 | 
			
		||||
          card.style.display = 'none';
 | 
			
		||||
          remainingCards.push(card);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      
 | 
			
		||||
      const allCards = [...orderedCards, ...remainingCards];
 | 
			
		||||
      allCards.forEach(card => {
 | 
			
		||||
        toolsContainer.appendChild(card);
 | 
			
		||||
      });
 | 
			
		||||
      
 | 
			
		||||
    } else {
 | 
			
		||||
      allToolCards.forEach(card => {
 | 
			
		||||
        const toolName = card.getAttribute('data-tool-name');
 | 
			
		||||
        
 | 
			
		||||
        card.removeAttribute('data-semantic-similarity');
 | 
			
		||||
        card.removeAttribute('data-semantic-rank');
 | 
			
		||||
        const semanticIndicator = card.querySelector('.semantic-rank-indicator');
 | 
			
		||||
        if (semanticIndicator) {
 | 
			
		||||
          semanticIndicator.remove();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (filteredNames.has(toolName)) {
 | 
			
		||||
          card.style.display = 'block';
 | 
			
		||||
          visibleCount++;
 | 
			
		||||
        } else {
 | 
			
		||||
          card.style.display = 'none';
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      
 | 
			
		||||
      if (!semanticSearch) {
 | 
			
		||||
        const originalOrder = Array.from(allToolCards).sort((a, b) => {
 | 
			
		||||
          const aIndex = Array.from(allToolCards).indexOf(a);
 | 
			
		||||
          const bIndex = Array.from(allToolCards).indexOf(b);
 | 
			
		||||
          return aIndex - bIndex;
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        originalOrder.forEach(card => {
 | 
			
		||||
        allToolCards.forEach(card => {
 | 
			
		||||
          const toolName = card.getAttribute('data-tool-name');
 | 
			
		||||
          if (!filteredNames.has(toolName)) {
 | 
			
		||||
            card.style.display = 'none';
 | 
			
		||||
            remainingCards.push(card);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        const allCards = [...orderedCards, ...remainingCards];
 | 
			
		||||
        allCards.forEach(card => {
 | 
			
		||||
          toolsContainer.appendChild(card);
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
      } else {
 | 
			
		||||
        allToolCards.forEach(card => {
 | 
			
		||||
          const toolName = card.getAttribute('data-tool-name');
 | 
			
		||||
          
 | 
			
		||||
          card.removeAttribute('data-semantic-similarity');
 | 
			
		||||
          card.removeAttribute('data-semantic-rank');
 | 
			
		||||
          const semanticIndicator = card.querySelector('.semantic-rank-indicator');
 | 
			
		||||
          if (semanticIndicator) {
 | 
			
		||||
            semanticIndicator.remove();
 | 
			
		||||
          }
 | 
			
		||||
          
 | 
			
		||||
          if (filteredNames.has(toolName)) {
 | 
			
		||||
            card.style.display = 'block';
 | 
			
		||||
            visibleCount++;
 | 
			
		||||
          } else {
 | 
			
		||||
            card.style.display = 'none';
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        if (!semanticSearch) {
 | 
			
		||||
          const originalOrder = Array.from(allToolCards).sort((a, b) => {
 | 
			
		||||
            const aIndex = Array.from(allToolCards).indexOf(a);
 | 
			
		||||
            const bIndex = Array.from(allToolCards).indexOf(b);
 | 
			
		||||
            return aIndex - bIndex;
 | 
			
		||||
          });
 | 
			
		||||
          
 | 
			
		||||
          originalOrder.forEach(card => {
 | 
			
		||||
            toolsContainer.appendChild(card);
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (visibleCount === 0) {
 | 
			
		||||
      noResults.style.display = 'block';
 | 
			
		||||
    } else {
 | 
			
		||||
      noResults.style.display = 'none';
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (semanticSearch) {
 | 
			
		||||
      console.log(`[SEMANTIC] Displayed ${visibleCount} tools in semantic order`);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
    
 | 
			
		||||
      
 | 
			
		||||
      if (visibleCount === 0) {
 | 
			
		||||
        noResults.style.display = 'block';
 | 
			
		||||
      } else {
 | 
			
		||||
        noResults.style.display = 'none';
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      if (semanticSearch) {
 | 
			
		||||
        console.log(`[SEMANTIC] Displayed ${visibleCount} tools in semantic order`);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
      
 | 
			
		||||
    window.addEventListener('viewChanged', (event) => {
 | 
			
		||||
      const view = event.detail;
 | 
			
		||||
      if (!event.triggeredByButton) {
 | 
			
		||||
@ -678,7 +686,11 @@ if (aiAuthRequired) {
 | 
			
		||||
    window.switchToAIView = () => switchToView('ai');
 | 
			
		||||
    window.switchToView = switchToView;
 | 
			
		||||
 | 
			
		||||
    handleSharedURL();
 | 
			
		||||
    // CRITICAL: Handle shared URLs AFTER everything is set up
 | 
			
		||||
    // Increased timeout to ensure all components and utility functions are loaded
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      handleSharedURL();
 | 
			
		||||
    }, 1000);
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
</BaseLayout>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user