
    `gj.w                         d Z ddlZddlZddlZddlmZmZmZ ddlm	Z	 dZ
dZdZdZd	Zd
ZdZdZdZdZdedefdZdedefdZdeeeef      defdZdeeeef      defdZdeeef   defdZy)a  
HTML Export generator for Hermes sessions.
Generates a standalone, beautiful HTML file with all messages embedded.
Supports single and multi-session exports with a professional sidebar.
No remote dependencies.
Enhanced with UI-UX-PRO-MAX design intelligence.
    N)AnyDictList)quotea)  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-user"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>ai  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bot"><path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/></svg>a$  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-terminal"><polyline points="4 17 10 11 4 5"/><line x1="12" x2="20" y1="19" y2="19"/></svg>a|  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-wrench"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>a  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sparkles"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/></svg>z<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right"><path d="m9 18 6-6-6-6"/></svg>a  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>a  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-shield"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.5 3.8 17 5 19 5a1 1 0 0 1 1 1z"/></svg>a  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#FFD700" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></svg>uF  <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'nonce-{script_nonce}'; style-src 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src data:; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; object-src 'none'">
    <title>{page_title}</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
    <style>
        :root {{
            --bg-color: #F8FAFC;
            --text-color: #0F172A;
            --secondary-text: #475569;
            --user-bg: #FFFFFF;
            --assistant-bg: #F1F5F9;
            --border-color: #E2E8F0;
            --accent-color: #CD7F32;
            --accent-foreground: #FFFFFF;
            --code-bg: #1E293B;
            --code-text: #F8FAFC;
            --reasoning-bg: #FFFBEB;
            --reasoning-border: #FEF3C7;
            --tool-bg: #F0F9FF;
            --tool-border: #E0F2FE;
            --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
            --sidebar-bg: #FFFFFF;
            --sidebar-width: 320px;
        }}

        @media (prefers-color-scheme: dark) {{
            :root {{
                --bg-color: #000101;
                --text-color: #FFF8DC;
                --secondary-text: #94A3B8;
                --user-bg: #041c1c;
                --assistant-bg: #0c1a1a;
                --border-color: #CD7F32;
                --accent-color: #FFD700;
                --code-bg: #000000;
                --reasoning-bg: #1a1a1a;
                --reasoning-border: #CD7F32;
                --tool-bg: #0c4a6e;
                --tool-border: #075985;
                --shadow: 0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3);
                --sidebar-bg: #041c1c;
            }}
        }}

        * {{
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }}

        body {{
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            line-height: 1.6;
            color: var(--text-color);
            background-color: var(--bg-color);
            -webkit-font-smoothing: antialiased;
            overflow-x: hidden;
        }}

        .layout {{
            display: flex;
            min-height: 100vh;
        }}

        /* Sidebar */
        .sidebar {{
            width: var(--sidebar-width);
            background-color: var(--sidebar-bg);
            border-right: 1px solid var(--border-color);
            display: flex;
            flex-direction: column;
            position: fixed;
            height: 100vh;
            z-index: 100;
            transition: transform 0.3s ease;
        }}

        @media (max-width: 768px) {{
            .sidebar {{
                transform: translateX(-100%);
            }}
            .sidebar.open {{
                transform: translateX(0);
            }}
            .main-content {{
                margin-left: 0 !important;
            }}
        }}

        .sidebar-header {{
            padding: 1.5rem;
            border-bottom: 1px solid var(--border-color);
        }}

        .sidebar-brand {{
            display: flex;
            align-items: center;
            gap: 0.75rem;
            font-weight: 700;
            font-size: 1.25rem;
            color: var(--accent-color);
            margin-bottom: 1rem;
        }}

        .search-container {{
            position: relative;
        }}

        .search-container input {{
            width: 100%;
            padding: 0.5rem 1rem 0.5rem 2.25rem;
            border-radius: 0.5rem;
            border: 1px solid var(--border-color);
            background-color: var(--bg-color);
            color: var(--text-color);
            font-size: 0.875rem;
            outline: none;
        }}

        .search-container svg {{
            position: absolute;
            left: 0.75rem;
            top: 50%;
            transform: translateY(-50%);
            color: var(--secondary-text);
        }}

        .session-list {{
            flex: 1;
            overflow-y: auto;
            padding: 1rem;
        }}

        .session-item {{
            display: block;
            padding: 0.75rem 1rem;
            border-radius: 0.5rem;
            margin-bottom: 0.5rem;
            cursor: pointer;
            transition: all 0.2s ease;
            text-decoration: none;
            color: inherit;
            border: 1px solid transparent;
        }}

        .session-item:hover {{
            background-color: rgba(0, 0, 0, 0.05);
        }}

        @media (prefers-color-scheme: dark) {{
            .session-item:hover {{
                background-color: rgba(255, 255, 255, 0.05);
            }}
        }}

        .session-item.active {{
            background-color: var(--user-bg);
            border-color: var(--accent-color);
            box-shadow: var(--shadow);
        }}

        .session-item-title {{
            font-weight: 600;
            font-size: 0.875rem;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            margin-bottom: 0.25rem;
        }}

        .session-item-meta {{
            font-size: 0.75rem;
            color: var(--secondary-text);
            display: flex;
            justify-content: space-between;
        }}

        /* Main Content */
        .main-content {{
            flex: 1;
            margin-left: {main_margin};
            padding: 3rem 2rem;
            max-width: 100%;
            transition: margin-left 0.3s ease;
        }}

        .session-view {{
            display: none;
            width: 100%;
            margin: 0 auto;
        }}

        .layout-single .session-view {{
            max-width: 90%;
            margin: 0 auto;
        }}

        .layout-multi .session-view {{
            max-width: 100%;
            margin: 0;
        }}

        .layout-multi .main-content {{
            width: 0;
        }}

        .session-view.active {{
            display: block;
        }}

        header {{
            margin-bottom: 3rem;
            text-align: center;
        }}

        .meta {{
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            gap: 1.5rem;
            margin-top: 1rem;
            font-size: 0.875rem;
            color: var(--secondary-text);
         }}

        .meta-item strong {{
            color: var(--text-color);
        }}

        /* Messages */
        .message {{
            margin-bottom: 1.5rem;
            border-radius: 0.75rem;
            background-color: var(--user-bg);
            border: 1px solid var(--border-color);
            box-shadow: var(--shadow);
            overflow: hidden;
        }}

        .message-user {{
            background-color: #f0fdf4;
        }}

        .message-assistant {{
            background-color: var(--assistant-bg);
            border-left: 4px solid var(--accent-color);
        }}

        .message-system {{
            background-color: var(--bg-color);
            border-left: 4px solid var(--secondary-text);
            opacity: 0.9;
        }}

        .message-tool {{
            background-color: #f8fafc;
            border-style: dotted;
        }}

        @media (prefers-color-scheme: dark) {{
            .message-user {{
                background-color: #0c2121;
            }}

            .message-assistant {{
                background-color: #041c1c;
            }}

            .message-system {{
                background-color: #020617;
                border-left: 4px solid var(--secondary-text);
            }}

            .message-tool {{
                background-color: #0f172a;
            }}
        }}

        .message-header {{
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 1rem 1.5rem;
            cursor: pointer;
            user-select: none;
            transition: background-color 0.2s ease;
        }}

        .message-header:hover {{
            background-color: rgba(0,0,0,0.02);
        }}

        .message-header svg.chevron {{
            transition: transform 0.2s ease;
            color: var(--secondary-text);
        }}

        .message.active svg.chevron {{
            transform: rotate(90deg);
        }}

        .role-badge {{
            display: flex;
            align-items: center;
            gap: 0.5rem;
            font-size: 0.75rem;
            font-weight: 700;
            text-transform: uppercase;
            letter-spacing: 0.05em;
            color: var(--secondary-text);
        }}

        .role-badge svg {{
            color: var(--accent-color);
        }}

        .timestamp {{
            font-size: 0.75rem;
            color: var(--secondary-text);
            font-variant-numeric: tabular-nums;
        }}

        .message-body {{
            display: none;
            padding: 0 1.5rem 1.5rem 1.5rem;
            border-top: 1px solid var(--border-color);
            padding-top: 1.5rem;
        }}

        .message.active .message-body {{
            display: block;
        }}

        .content {{
            white-space: pre-wrap;
            word-break: break-word;
            font-size: 1rem;
        }}

        /* Code Blocks */
        code {{
            font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
            background-color: rgba(0,0,0,0.05);
            padding: 0.2rem 0.4rem;
            border-radius: 0.375rem;
            font-size: 0.9em;
        }}

        pre {{
            background-color: var(--code-bg);
            color: var(--code-text);
            padding: 1.25rem;
            border-radius: 0.75rem;
            overflow-x: auto;
            margin: 1.25rem 0;
            font-size: 0.9rem;
            line-height: 1.5;
            box-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.1);
        }}

        pre code {{
            background-color: transparent;
            padding: 0;
            border-radius: 0;
            color: inherit;
        }}

        /* Tool Calls */
        .tool-call {{
            margin: 1rem 0;
            border-radius: 0.5rem;
            overflow: hidden;
            border: 1px solid var(--tool-border);
            background-color: var(--tool-bg);
        }}

        .tool-call-header {{
            padding: 0.75rem 1rem;
            display: flex;
            align-items: center;
            gap: 0.5rem;
            cursor: pointer;
            user-select: none;
            font-size: 0.875rem;
            font-weight: 600;
        }}

        .tool-call-header:hover {{
            background-color: rgba(0,0,0,0.03);
        }}

        .tool-call-header svg.chevron {{
            transition: transform 0.2s ease;
            color: var(--secondary-text);
        }}

        .tool-call.active svg.chevron {{
            transform: rotate(90deg);
        }}

        .tool-call-content {{
            display: none;
            padding: 0 1rem 1rem 1rem;
        }}

        .tool-call.active .tool-call-content {{
            display: block;
        }}

        /* Reasoning */
        .reasoning {{
            margin-top: 1.5rem;
            border-radius: 0.75rem;
            border: 1px solid var(--reasoning-border);
            background-color: var(--reasoning-bg);
            overflow: hidden;
        }}

        .reasoning-header {{
            padding: 0.75rem 1rem;
            display: flex;
            align-items: center;
            gap: 0.5rem;
            cursor: pointer;
            user-select: none;
            font-size: 0.875rem;
            font-weight: 600;
        }}

        .reasoning-header:hover {{
            background-color: rgba(0,0,0,0.02);
        }}

        .reasoning-header svg.chevron {{
            transition: transform 0.2s ease;
            color: var(--secondary-text);
        }}

        .reasoning.active svg.chevron {{
            transform: rotate(90deg);
        }}

        .reasoning-content {{
            display: none;
            padding: 0 1rem 1rem 1rem;
            font-size: 0.925rem;
            color: var(--secondary-text);
            border-top: 1px solid var(--reasoning-border);
            padding-top: 1rem;
        }}

        .reasoning.active .reasoning-content {{
            display: block;
        }}

        /* System Prompt Section */
        .system-prompt-section {{
            margin-top: 2rem;
            border-radius: 0.75rem;
            border: 1px solid var(--border-color);
            background-color: var(--user-bg);
            overflow: hidden;
            text-align: left;
            max-width: 800px;
            margin-left: auto;
            margin-right: auto;
        }}

        .system-prompt-header {{
            padding: 0.75rem 1.25rem;
            display: flex;
            align-items: center;
            gap: 0.6rem;
            cursor: pointer;
            user-select: none;
            font-size: 0.875rem;
            font-weight: 600;
            color: var(--secondary-text);
        }}

        .system-prompt-header:hover {{
            background-color: rgba(0,0,0,0.02);
        }}

        .system-prompt-header svg.chevron {{
            transition: transform 0.2s ease;
        }}

        .system-prompt-section.active svg.chevron {{
            transform: rotate(90deg);
        }}

        .system-prompt-content {{
            display: none;
            padding: 0 1.25rem 1.25rem 1.25rem;
            font-size: 0.9rem;
            border-top: 1px solid var(--border-color);
            padding-top: 1rem;
        }}

        .system-prompt-section.active .system-prompt-content {{
            display: block;
        }}

        footer {{
            margin-top: 5rem;
            padding-top: 2rem;
            border-top: 1px solid var(--border-color);
            text-align: center;
            font-size: 0.875rem;
            color: var(--secondary-text);
        }}

        /* Animation */
        .fade-in {{
            animation: fadeIn 0.4s ease-out backwards;
        }}

        @keyframes fadeIn {{
            from {{ opacity: 0; transform: translateY(10px); }}
            to {{ opacity: 1; transform: translateY(0); }}
        }}

        /* Utilities */
        .hidden {{ display: none !important; }}
    </style>
</head>
<body>
    <div class="layout {layout_class}">
        {sidebar_html}
        
        <div class="main-content">
            {sessions_html}
            
            <footer>
                Built with ☤ Hermes Agent • Generated on {generated_at}
            </footer>
        </div>
    </div>

    <script nonce="{script_nonce}">
        // Session Switching
        function showSession(id) {{
            // Update Sidebar
            document.querySelectorAll('.session-item').forEach(el => {{
                el.classList.toggle('active', el.dataset.id === id);
            }});

            // Update View
            document.querySelectorAll('.session-view').forEach(el => {{
                el.classList.remove('active');
            }});
            const activeView = document.getElementById(`view-${{id}}`);
            if (activeView) activeView.classList.add('active');

            // Store in URL hash
            window.location.hash = encodeURIComponent(id);
        }}

        document.querySelectorAll('.session-item').forEach(item => {{
            item.addEventListener('click', (e) => {{
                e.preventDefault();
                showSession(item.dataset.id || '');
            }});
        }});

        // Search Filter
        const searchInput = document.getElementById('session-search');
        if (searchInput) {{
            searchInput.addEventListener('input', (e) => {{
                const term = e.target.value.toLowerCase();
                document.querySelectorAll('.session-item').forEach(item => {{
                    const text = item.innerText.toLowerCase();
                    if (text.includes(term)) {{
                        item.classList.remove('hidden');
                    }} else {{
                        item.classList.add('hidden');
                    }}
                }});
            }});
        }}

        // Card Toggles
        document.addEventListener('click', function(e) {{
            const header = e.target.closest('.message-header, .tool-call-header, .reasoning-header, .system-prompt-header');
            if (header) {{
                header.parentElement.classList.toggle('active');
            }}
        }});

        // Initialization
        window.addEventListener('load', () => {{
            const hash = decodeURIComponent(window.location.hash.slice(1));
            if (hash) {{
                showSession(hash);
            }} else {{
                // Show first session by default if none selected
                const first = document.querySelector('.session-item');
                if (first) showSession(first.getAttribute('data-id'));
            }}
        }});

        // Intersection Observer for scroll animations
        if ('IntersectionObserver' in window) {{
            var observer = new IntersectionObserver(function(entries) {{
                entries.forEach(function(entry) {{
                    if (entry.isIntersecting) {{
                        entry.target.classList.add('fade-in');
                        observer.unobserve(entry.target);
                    }}
                }});
            }}, {{ threshold: 0.1 }});

            document.querySelectorAll('.message').forEach(function(m) {{ observer.observe(m); }});
        }}
    </script>
</body>
</html>
textreturnc                     t        | t              st        |       } | j                  dd      j                  dd      j                  dd      j                  dd      j                  d	d
      S )N&z&amp;<z&lt;>z&gt;"z&quot;'z&#39;)
isinstancestrreplace)r   s    Q/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/session_export_html.py_escape_htmlr     s^    dC 4y<<W%--c6:BB3OWWX[]efnnort{||    tsc                 d    | syt         j                   j                  |       j                  d      S )NN/A%Y-%m-%d %H:%M:%S)datetimefromtimestampstrftime)r   s    r   _format_timestampr     s*    e**2.778KLLr   messagesc                 D   g }t        |       D ]  \  }}|j                  dd      }|dk(  r|j                  d      xs d}t        |j                  dd            }t        }|dk(  rt        }n|d	k(  rt
        }n|d
k(  rt        }t        |t              rg }|D ]  }	t        |	t              r]|	j                  d      dk(  r"|j                  |	j                  dd             I|	j                  d      dk(  s^|j                  d       p|j                  t        |	              dj                  |      }t        |      }
dj                  d t        |      j                         D              }d| d}|dk  rdt        |dz  d       dnd}t         j#                  dd      }d| d| d}|dz  }|d| d| d|
 d z  }|d!| d z  }|d"z  }|d#z  }|j                  d$      }|r|D ]  }|j                  d%i       j                  d&d      }|j                  d%i       j                  d'd(      }|d)t         j#                  dd       d*t$         d+t        |       d,t        |       d-	z  } |r*|d.k(  r|d/t        |       d0z  }n|d1t        |       d z  }|j                  d2      xs |j                  d3      }|r0|d4t         j#                  dd       d5t&         d6t        |       d7z  }|d"z  }|d z  }|j                  |        dj                  |      S )8Nroleunknownsession_metacontent 	timestampr   user	assistantsystemtyper   	image_urlz[Image Attachment]
c              3   L   K   | ]  }|j                         s|d v r|nd  yw)z-_-N)isalnum).0cs     r   	<genexpr>z*_generate_messages_html.<locals>.<genexpr>  s#     _!))+dQC_s   "$zmessage message- active
   z style="animation-delay: g?g      ?zs"class="class="chevron z<div class="r   r   z  <div class="message-header">z    <div class="role-badge"> z</div>z    <div class="timestamp">z  </div>z  <div class="message-body">
tool_callsfunctionname	argumentsz{}zt
                <div class="tool-call">
                    <div class="tool-call-header">
                        z
                        z Tool Call: zs
                    </div>
                    <div class="tool-call-content">
                        <pre><code>zP</code></pre>
                    </div>
                </div>
                toolz"  <div class="content"><pre><code>z</code></pre></div>z  <div class="content">	reasoningreasoning_contentzh
            <div class="reasoning">
                <div class="reasoning-header">
                    
                    z{ Reasoning
                </div>
                <div class="reasoning-content">
                    <div class="content">=</div>
                </div>
            </div>
            )	enumerategetr   ICON_TERMINAL	ICON_USERICON_BOTICON_SHIELDr   listdictappendr   joinr   lowerminICON_CHEVRON_RIGHTr   ICON_WRENCHICON_SPARKLES)r   	html_listimsgr   r"   r$   	role_iconcontent_partspart	safe_role
role_class	msg_classdelay_stylechevron_htmlhtmlr6   tcfn_nameargsr;   s                        r   _generate_messages_htmlr]     s   IH% `3wwvy) >!'')$*%cggk1&=>	 "	6>!I[  IX#I gt$M 4dD)xx'61%,,TXXfb-AB&)[8%,,-AB!((T34 ii.G !&	WW_SQUY__M^__
&zl':	LMPRF1#a$h2D1ERHXZ)11)=NOi[+a801.|nAi[)TZ[[-i[??
.. WW\*
  &&R044VYGvvj"-11+tD  ,33I?PQR S$\,w2G1H I$ %1$6#7 8
 
  v~<\'=R<SSfgg1,w2G1HOO GGK(HCGG4G,H	  (//	;LMN O"O $* +7y*A)B C
 
D 	
A`B 99Yr   sessionsc                    | syt        |       dkD  }t        j                  j                         j                  d      }d}|r g }| D ]  }t	        |j                  dd            }t        |      }|j                  d      xs |j                  d      xs d	}t        |      d
kD  r|d d dz   }t        |j                  dd            j                  d      d   }	d| dt        |d       dt        |       dt        |d d        d|	 d}
|j                  |
        dt         dt         ddj                  |       d}g }| D ]  }t	        |j                  dd            }t        |      }|j                  d      xs d}|j                  dd      }t        |j                  dd            }|j                  dg       }t        |      }d }|s|d!z  }d"| }|j                  d#      }d}|r-d$t        j!                  d%d&       d't"         d(t        |       d)}d*| d+| d,t        |       d-| d.t        |       d/| d0| d1| d2}|j                  |        t%        j&                  d3      }t(        j+                  |rd4nt        | d   j                  dd            |d5j                  |      |rd6nd7|rd8nd9||:      S );Nz9<html><body><h1>No sessions to export.</h1></body></html>   r   r#   idr   titlepreviewzUntitled Session2   /   z...
started_atr   r5   z.
            <a class="session-item" data-id="z	" href="#)safez3">
                <div class="session-item-title">zQ</div>
                <div class="session-item-meta">
                    <span>   z"</span>
                    <span>z<</span>
                </div>
            </a>
            z
        <aside class="sidebar">
            <div class="sidebar-header">
                <div class="sidebar-brand">
                    zj Hermes History
                </div>
                <div class="search-container">
                    z
                    <input type="text" id="session-search" placeholder="Search sessions...">
                </div>
            </div>
            <div class="session-list">
                z-
            </div>
        </aside>
        zHermes SessionmodelUnknownr   zsession-viewr1   zview-system_promptz
            <div class="system-prompt-section active">
                <div class="system-prompt-header">
                    r3   r4   r=   z System Prompt (Persona)
                </div>
                <div class="system-prompt-content">
                    <div class="content">r>   z
        <div class="z" id="z<">
            <header class="fade-in">
                <h1>zi</h1>
                <div class="meta">
                    <div class="meta-item"><strong>ID:</strong> zJ</div>
                    <div class="meta-item"><strong>Model:</strong> zL</div>
                    <div class="meta-item"><strong>Started:</strong> z.</div>
                </div>
                z:
            </header>
            <main>
                z,
            </main>
        </div>
           zHermes Session Exportr*   zvar(--sidebar-width)0zlayout-multizlayout-single)
page_titlesidebar_htmlsessions_htmlmain_marginlayout_classgenerated_atscript_nonce)lenr   nowr   r   r@   r   r   splitr   rG   ICON_HERMESICON_SEARCHrH   r]   rK   r   rD   secretstoken_urlsafeHTML_TEMPLATEformat)r^   is_multirs   ro   sidebar_itemsssidescaped_sidrb   dateitemsessions_html_listri   rf   r   messages_html
view_classsession_view_idrk   system_htmlsession_htmlrt   s                         r   "generate_multi_session_html_exportr     sb   J8}q H$$((*334GHL L 	'AaeeD%()C&s+KEE'NLaeeI&6L:LE5zBcr
U(:$QUU<%;<BB3GJD..9])E#TVDWCX Y11=e1D0E F'BQ01 2& !D   &!	'$ !M " !M "
 '( )	$  .0!%%e$%"3'g2"2gy)&quu\1'=>
55R(/9#
y0!+/o. (//	;LMN O M "* +7}*E)F G
KL&7 8!%() *AAL NDDPQVDWCX YFFP\ R    	  	!!,/].0` ((,L.6*LRSY`brIs<t!ii 23.6*C'/^_!!    r   session_datac                     t        | g      S )z)Legacy wrapper for single session export.)r   )r   s    r   generate_html_exportr   e  s    -|n==r   )__doc__jsonr   rz   typingr   r   r   urllib.parser   rB   rC   rA   rL   rM   rK   ry   rD   rx   r|   r   r   floatr   r]   r   r    r   r   <module>r      s       " "  x	 w w M j P  b U Wp	d}s }s }
M% MC Mc d4S>&: c s c Jid38n1E i# iV>tCH~ ># >r   