@mounaji_npm/forum 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +445 -0
- package/dist/mounajiforum.es.js +1090 -0
- package/dist/mounajiforum.es.js.map +1 -0
- package/dist/mounajiforum.umd.cjs +2 -0
- package/dist/mounajiforum.umd.cjs.map +1 -0
- package/package.json +47 -0
- package/src/CreatePostPage.jsx +237 -0
- package/src/ForumPage.jsx +193 -0
- package/src/PostPage.jsx +122 -0
- package/src/components/CategoryNav.jsx +83 -0
- package/src/components/PostCard.jsx +186 -0
- package/src/components/PostDetail.jsx +89 -0
- package/src/components/ReplyThread.jsx +244 -0
- package/src/components/shared.jsx +171 -0
- package/src/demo.js +125 -0
- package/src/index.js +48 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mounajiforum.es.js","sources":["../src/components/CategoryNav.jsx","../src/components/shared.jsx","../src/components/PostCard.jsx","../src/demo.js","../src/ForumPage.jsx","../src/components/PostDetail.jsx","../src/components/ReplyThread.jsx","../src/PostPage.jsx","../src/CreatePostPage.jsx"],"sourcesContent":["/**\n * CategoryNav — @mounaji_npm/forum\n *\n * Sidebar category list with counts and active state.\n *\n * Props:\n * categories — { id, label, icon?, count?, pinned? }[]\n * active — string (category id)\n * onChange(id) — callback\n * isDark — boolean\n * title — string (default: 'Categories')\n * style — CSSProperties\n */\n\nexport function CategoryNav({ categories = [], active = 'all', onChange, isDark = true, title = 'Categories', style }) {\n const card = isDark ? 'var(--mn-color-card-dark, #0B0F23)' : 'var(--mn-color-card-light, #FAFAF8)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const textPri = isDark ? 'var(--mn-text-primary-dark, #F0F4FF)' : 'var(--mn-text-primary-light, #1A1A2E)';\n const textSec = isDark ? 'var(--mn-text-secondary-dark, #94A3B8)' : 'var(--mn-text-secondary-light, #64748B)';\n\n return (\n <div style={{\n borderRadius: 'var(--mn-radius-lg, 0.75rem)',\n backgroundColor: card,\n border: `1px solid ${border}`,\n overflow: 'hidden',\n ...style,\n }}>\n {title && (\n <div style={{ padding: '12px 16px', borderBottom: `1px solid ${border}` }}>\n <p style={{ margin: 0, fontSize: '0.75rem', fontWeight: 600, color: textSec, textTransform: 'uppercase', letterSpacing: '0.07em' }}>\n {title}\n </p>\n </div>\n )}\n <div style={{ padding: '8px 0' }}>\n {categories.map(cat => {\n const isActive = active === cat.id;\n return (\n <button\n key={cat.id}\n onClick={() => onChange?.(cat.id)}\n style={{\n width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between',\n padding: '7px 16px', border: 'none', cursor: 'pointer', fontFamily: 'inherit',\n backgroundColor: isActive\n ? (isDark ? 'rgba(59,130,246,0.1)' : 'rgba(59,130,246,0.07)')\n : 'transparent',\n borderLeft: `3px solid ${isActive ? 'var(--mn-color-primary, #3B82F6)' : 'transparent'}`,\n transition: 'all 100ms',\n gap: 8,\n }}\n onMouseEnter={e => { if (!isActive) e.currentTarget.style.backgroundColor = isDark ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.03)'; }}\n onMouseLeave={e => { if (!isActive) e.currentTarget.style.backgroundColor = 'transparent'; }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>\n {cat.icon && <span style={{ fontSize: 14, flexShrink: 0 }}>{cat.icon}</span>}\n <span style={{\n fontSize: '0.875rem',\n fontWeight: isActive ? 600 : 400,\n color: isActive ? 'var(--mn-color-primary, #3B82F6)' : textPri,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',\n }}>\n {cat.label}\n </span>\n </div>\n {cat.count != null && (\n <span style={{\n fontSize: '0.7rem', fontWeight: 500, padding: '1px 7px', borderRadius: 9999,\n backgroundColor: isActive ? 'rgba(59,130,246,0.15)' : (isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'),\n color: isActive ? 'var(--mn-color-primary, #3B82F6)' : textSec,\n flexShrink: 0,\n }}>\n {cat.count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","/**\n * shared.jsx — @mounaji_npm/forum\n * Small reusable primitives: VoteButton, AuthorMeta, TagChip, CategoryBadge\n */\n\nimport { useState } from 'react';\n\n// ─── VoteButton ────────────────────────────────────────────────────────────────\n\n/**\n * Props:\n * count — number\n * userVote — 1 | 0 | -1\n * onChange(newVote: 1 | 0 | -1)\n * vertical — boolean (default: false — horizontal layout)\n * isDark — boolean\n */\nexport function VoteButton({ count = 0, userVote = 0, onChange, vertical = false, isDark = true, size = 'md' }) {\n const [optimistic, setOptimistic] = useState(null);\n\n const vote = optimistic ?? userVote;\n const total = optimistic !== null ? count + (optimistic - userVote) : count;\n const upCol = vote === 1 ? '#10B981' : (isDark ? '#64748B' : '#94A3B8');\n const downCol = vote === -1 ? '#EF4444' : (isDark ? '#64748B' : '#94A3B8');\n const numCol = vote === 1 ? '#10B981' : vote === -1 ? '#EF4444' : (isDark ? '#F0F4FF' : '#1A1A2E');\n const btnSz = size === 'sm' ? 22 : 28;\n const iconSz = size === 'sm' ? 11 : 13;\n\n function cast(v) {\n const next = vote === v ? 0 : v;\n setOptimistic(next);\n onChange?.(next);\n }\n\n const wrapStyle = vertical\n ? { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2 }\n : { display: 'flex', alignItems: 'center', gap: 4 };\n\n return (\n <div style={wrapStyle}>\n <VBtn size={btnSz} icon={size === 'sm' ? '▲' : '▲'} color={upCol} iconSz={iconSz} onClick={() => cast(1)} title=\"Upvote\" />\n <span style={{ fontSize: size === 'sm' ? '0.75rem' : '0.875rem', fontWeight: 700, color: numCol, minWidth: 20, textAlign: 'center' }}>\n {total}\n </span>\n {vertical && <VBtn size={btnSz} icon=\"▼\" color={downCol} iconSz={iconSz} onClick={() => cast(-1)} title=\"Downvote\" />}\n </div>\n );\n}\n\nfunction VBtn({ size, icon, color, iconSz, onClick, title }) {\n return (\n <button\n onClick={onClick}\n title={title}\n style={{\n width: size, height: size, borderRadius: 4, border: 'none', cursor: 'pointer',\n backgroundColor: 'transparent', color, fontSize: iconSz,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n transition: 'background 100ms, color 100ms', padding: 0, fontFamily: 'inherit',\n }}\n onMouseEnter={e => { e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.07)'; }}\n onMouseLeave={e => { e.currentTarget.style.backgroundColor = 'transparent'; }}\n >\n {icon}\n </button>\n );\n}\n\n// ─── AuthorMeta ────────────────────────────────────────────────────────────────\n\n/**\n * Props:\n * author — { name, avatar? }\n * date — string | Date\n * prefix — string (default: '')\n * isDark — boolean\n * size — 'sm' | 'md'\n */\nexport function AuthorMeta({ author, date, prefix = '', isDark = true, size = 'md' }) {\n const textSec = isDark ? '#94A3B8' : '#64748B';\n const textPri = isDark ? '#F0F4FF' : '#1A1A2E';\n const avatarSz = size === 'sm' ? 18 : 22;\n const fontSize = size === 'sm' ? '0.75rem' : '0.8125rem';\n\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <Avatar name={author?.name ?? '?'} size={avatarSz} src={author?.avatar} />\n <span style={{ fontSize, color: textPri, fontWeight: 500 }}>{author?.name ?? 'unknown'}</span>\n {(prefix || date) && (\n <span style={{ fontSize, color: textSec }}>\n {prefix && <>{prefix} </>}{date ? formatRelative(date) : ''}\n </span>\n )}\n </div>\n );\n}\n\n// ─── TagChip ─────────────────────────────────────────────────────────────────\n\nexport function TagChip({ label, onClick, isDark = true }) {\n const bg = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)';\n const border = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)';\n const color = isDark ? '#94A3B8' : '#64748B';\n return (\n <span\n onClick={onClick}\n style={{\n fontSize: '0.7rem', padding: '2px 8px', borderRadius: 9999,\n backgroundColor: bg, color, border: `1px solid ${border}`,\n cursor: onClick ? 'pointer' : 'default', fontFamily: 'inherit',\n transition: 'background 100ms',\n }}\n >\n #{label}\n </span>\n );\n}\n\n// ─── CategoryBadge ────────────────────────────────────────────────────────────\n\nconst CAT_COLORS = {\n announcements: { bg: 'rgba(239,68,68,0.12)', text: '#F87171', border: 'rgba(239,68,68,0.25)' },\n general: { bg: 'rgba(59,130,246,0.12)', text: '#60A5FA', border: 'rgba(59,130,246,0.25)' },\n questions: { bg: 'rgba(245,158,11,0.12)', text: '#FCD34D', border: 'rgba(245,158,11,0.25)' },\n ideas: { bg: 'rgba(139,92,246,0.12)', text: '#A78BFA', border: 'rgba(139,92,246,0.25)' },\n bugs: { bg: 'rgba(239,68,68,0.12)', text: '#FCA5A5', border: 'rgba(239,68,68,0.2)' },\n default: { bg: 'rgba(255,255,255,0.06)', text: '#94A3B8', border: 'rgba(255,255,255,0.1)' },\n};\n\nexport function CategoryBadge({ category }) {\n const c = CAT_COLORS[category?.id] ?? CAT_COLORS.default;\n return (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: '0.7rem', fontWeight: 500, padding: '2px 8px', borderRadius: 9999, backgroundColor: c.bg, color: c.text, border: `1px solid ${c.border}` }}>\n {category?.icon && <span>{category.icon}</span>}\n {category?.label}\n </span>\n );\n}\n\n// ─── Avatar ───────────────────────────────────────────────────────────────────\n\nexport function Avatar({ name, size = 24, src }) {\n const initials = (name ?? '?').slice(0, 1).toUpperCase();\n const hue = [...(name ?? '')].reduce((h, c) => (h * 31 + c.charCodeAt(0)) % 360, 0);\n const bg = `hsl(${hue}, 55%, 35%)`;\n\n if (src) {\n return <img src={src} alt={name} style={{ width: size, height: size, borderRadius: '50%', objectFit: 'cover' }} />;\n }\n return (\n <div style={{ width: size, height: size, borderRadius: '50%', backgroundColor: bg, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: size * 0.45, fontWeight: 700, color: '#fff', flexShrink: 0, userSelect: 'none' }}>\n {initials}\n </div>\n );\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nexport function formatRelative(date) {\n const d = typeof date === 'string' ? new Date(date) : date;\n const diff = (Date.now() - d.getTime()) / 1000;\n if (diff < 60) return 'just now';\n if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;\n if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;\n if (diff < 604800) return `${Math.floor(diff / 86400)}d ago`;\n return d.toLocaleDateString();\n}\n\nexport function plural(n, word) {\n return `${n} ${word}${n === 1 ? '' : 's'}`;\n}\n","/**\n * PostCard — @mounaji_npm/forum\n *\n * Compact card shown in the forum listing. Displays vote count, category badge,\n * title, preview text, author meta, reply/view counts, and status badges.\n *\n * Props (single post):\n * post — Post object (see data shape in demo.js)\n * onClick — () => void\n * onVote — (postId, vote: 1|0|-1) => void\n * isDark — boolean\n * compact — boolean (smaller variant, no body preview)\n * style — CSSProperties\n *\n * PostList:\n * posts, onPostClick, onVote, isLoading, isDark\n */\n\nimport { VoteButton, AuthorMeta, TagChip, CategoryBadge } from './shared.jsx';\n\n// ─── PostCard ────────────────────────────────────────────────────────────────\n\nexport function PostCard({ post, onClick, onVote, isDark = true, compact = false, style }) {\n const card = isDark ? 'var(--mn-color-card-dark, #0B0F23)' : 'var(--mn-color-card-light, #FAFAF8)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const textPri = isDark ? 'var(--mn-text-primary-dark, #F0F4FF)' : 'var(--mn-text-primary-light, #1A1A2E)';\n const textSec = isDark ? 'var(--mn-text-secondary-dark, #94A3B8)' : 'var(--mn-text-secondary-light, #64748B)';\n\n return (\n <div\n onClick={onClick}\n style={{\n display: 'flex', gap: 14, padding: compact ? '12px 16px' : '16px 18px',\n borderRadius: 'var(--mn-radius-lg, 0.75rem)',\n backgroundColor: card, border: `1px solid ${border}`,\n cursor: onClick ? 'pointer' : 'default',\n transition: 'border-color 120ms, background 120ms',\n ...style,\n }}\n onMouseEnter={e => { if (onClick) { e.currentTarget.style.borderColor = isDark ? 'rgba(255,255,255,0.14)' : 'rgba(0,0,0,0.16)'; } }}\n onMouseLeave={e => { e.currentTarget.style.borderColor = border; }}\n >\n {/* Vote column */}\n <div\n onClick={e => e.stopPropagation()}\n style={{ flexShrink: 0, paddingTop: 2 }}\n >\n <VoteButton\n count={post.votes}\n userVote={post.userVote ?? 0}\n onChange={v => onVote?.(post.id, v)}\n vertical\n isDark={isDark}\n size=\"sm\"\n />\n </div>\n\n {/* Content */}\n <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 6 }}>\n {/* Badges row */}\n <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>\n {post.isPinned && (\n <span style={{ fontSize: '0.7rem', fontWeight: 600, padding: '2px 7px', borderRadius: 9999, backgroundColor: 'rgba(245,158,11,0.12)', color: '#FCD34D', border: '1px solid rgba(245,158,11,0.25)' }}>\n 📌 Pinned\n </span>\n )}\n {post.isSolved && (\n <span style={{ fontSize: '0.7rem', fontWeight: 600, padding: '2px 7px', borderRadius: 9999, backgroundColor: 'rgba(16,185,129,0.12)', color: '#34D399', border: '1px solid rgba(16,185,129,0.25)' }}>\n ✓ Solved\n </span>\n )}\n <CategoryBadge category={post.category} />\n </div>\n\n {/* Title */}\n <h3 style={{ margin: 0, fontSize: compact ? '0.9375rem' : '1rem', fontWeight: 600, color: textPri, lineHeight: 1.4 }}>\n {post.title}\n </h3>\n\n {/* Body preview */}\n {!compact && post.body && (\n <p style={{ margin: 0, fontSize: '0.8125rem', color: textSec, lineHeight: 1.55, display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>\n {post.body}\n </p>\n )}\n\n {/* Tags */}\n {post.tags?.length > 0 && (\n <div style={{ display: 'flex', gap: 5, flexWrap: 'wrap' }}>\n {post.tags.map(t => <TagChip key={t} label={t} isDark={isDark} />)}\n </div>\n )}\n\n {/* Footer meta */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap', marginTop: 2 }}>\n <AuthorMeta author={post.author} date={post.createdAt} isDark={isDark} size=\"sm\" />\n <MetaCount icon=\"💬\" value={post.replyCount} label=\"replies\" isDark={isDark} />\n <MetaCount icon=\"👁\" value={post.viewCount} label=\"views\" isDark={isDark} />\n </div>\n </div>\n </div>\n );\n}\n\nfunction MetaCount({ icon, value, label, isDark }) {\n const color = isDark ? '#64748B' : '#94A3B8';\n return (\n <span style={{ display: 'flex', alignItems: 'center', gap: 4, fontSize: '0.75rem', color }}>\n <span style={{ fontSize: 12 }}>{icon}</span>\n {value} {label}\n </span>\n );\n}\n\n// ─── PostList ─────────────────────────────────────────────────────────────────\n\nexport function PostList({ posts = [], onPostClick, onVote, isLoading = false, isDark = true }) {\n if (isLoading) {\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n {Array.from({ length: 4 }).map((_, i) => (\n <SkeletonCard key={i} isDark={isDark} />\n ))}\n </div>\n );\n }\n\n if (posts.length === 0) {\n return <EmptyPostList isDark={isDark} />;\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n {posts.map(post => (\n <PostCard\n key={post.id}\n post={post}\n onClick={() => onPostClick?.(post.id)}\n onVote={onVote}\n isDark={isDark}\n />\n ))}\n </div>\n );\n}\n\nexport function EmptyPostList({ isDark = true, message = 'No posts yet', cta, onCta }) {\n const textPri = isDark ? '#F0F4FF' : '#1A1A2E';\n const textSec = isDark ? '#94A3B8' : '#64748B';\n return (\n <div style={{ textAlign: 'center', padding: '64px 24px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12 }}>\n <p style={{ fontSize: 40, margin: 0 }}>💬</p>\n <p style={{ margin: 0, fontSize: '1rem', fontWeight: 600, color: textPri }}>{message}</p>\n <p style={{ margin: 0, fontSize: '0.875rem', color: textSec }}>Be the first to start a discussion.</p>\n {cta && (\n <button\n onClick={onCta}\n style={{ marginTop: 8, padding: '8px 20px', borderRadius: 'var(--mn-radius-md, 0.5rem)', border: 'none', cursor: 'pointer', backgroundColor: 'var(--mn-color-primary, #3B82F6)', color: '#fff', fontSize: '0.875rem', fontWeight: 600, fontFamily: 'inherit' }}\n >\n {cta}\n </button>\n )}\n </div>\n );\n}\n\nfunction SkeletonCard({ isDark }) {\n const bg = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const S = (w, h = 12) => ({ width: w, height: h, borderRadius: 6, backgroundColor: bg, animation: 'mn-pulse 1.4s ease infinite' });\n return (\n <div style={{ display: 'flex', gap: 14, padding: '16px 18px', borderRadius: 'var(--mn-radius-lg, 0.75rem)', backgroundColor: isDark ? 'var(--mn-color-card-dark, #0B0F23)' : 'var(--mn-color-card-light, #FAFAF8)', border: `1px solid ${border}` }}>\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, paddingTop: 2, flexShrink: 0 }}>\n <div style={S(22, 10)} />\n <div style={S(22, 10)} />\n </div>\n <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 9 }}>\n <div style={S('60%', 8)} />\n <div style={S('85%', 14)} />\n <div style={S('50%', 8)} />\n <div style={S('40%', 8)} />\n </div>\n <style>{`@keyframes mn-pulse { 0%,100%{opacity:.5} 50%{opacity:1} }`}</style>\n </div>\n );\n}\n","/**\n * Demo data for @mounaji_npm/forum\n * Import to populate forum components during prototyping.\n */\n\nexport const DEMO_CATEGORIES = [\n { id: 'all', label: 'All Posts', icon: '◉', count: 124 },\n { id: 'announcements', label: 'Announcements', icon: '📣', count: 8, pinned: true },\n { id: 'general', label: 'General', icon: '💬', count: 32 },\n { id: 'questions', label: 'Questions', icon: '❓', count: 45 },\n { id: 'ideas', label: 'Ideas', icon: '💡', count: 27 },\n { id: 'bugs', label: 'Bug Reports', icon: '🐛', count: 12 },\n];\n\nexport const DEMO_POSTS = [\n {\n id: '1',\n title: 'Introducing the new dark mode token system',\n body: 'We have completely overhauled the design token system to support seamless dark/light mode switching. The new system uses CSS custom properties under a `data-mn-theme` attribute, which means zero-JavaScript theme switching in most cases.',\n author: { id: 'u1', name: 'alex_m', avatar: null },\n category: { id: 'announcements', label: 'Announcements', icon: '📣' },\n tags: ['design-system', 'tokens', 'dark-mode'],\n votes: 87,\n userVote: 0,\n replyCount: 14,\n viewCount: 420,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 3).toISOString(),\n isPinned: true,\n isSolved: false,\n },\n {\n id: '2',\n title: 'How do I add custom categories to my forum?',\n body: 'I am setting up a community forum and want to add my own categories beyond the defaults. Is there a config option for this, or do I need to pass a custom categories array?',\n author: { id: 'u2', name: 'sara_dev', avatar: null },\n category: { id: 'questions', label: 'Questions', icon: '❓' },\n tags: ['configuration', 'categories'],\n votes: 12,\n userVote: 0,\n replyCount: 5,\n viewCount: 98,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 6).toISOString(),\n isSolved: true,\n },\n {\n id: '3',\n title: 'Feature request: markdown support in replies',\n body: 'It would be great to have rich text / markdown support in the reply composer. Being able to add code blocks, links, and bold/italic text would make the forum much more useful for technical discussions.',\n author: { id: 'u3', name: 'techwriter_k', avatar: null },\n category: { id: 'ideas', label: 'Ideas', icon: '💡' },\n tags: ['markdown', 'editor', 'replies'],\n votes: 34,\n userVote: 1,\n replyCount: 9,\n viewCount: 203,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 12).toISOString(),\n },\n {\n id: '4',\n title: 'Vote count not updating in real-time',\n body: 'After clicking the upvote button, the vote count updates locally but does not sync back from the server on page refresh. Seems like the onVote callback is firing but the optimistic update is not being persisted.',\n author: { id: 'u4', name: 'james_d', avatar: null },\n category: { id: 'bugs', label: 'Bug Reports', icon: '🐛' },\n tags: ['voting', 'bug', 'real-time'],\n votes: 7,\n userVote: 0,\n replyCount: 3,\n viewCount: 61,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 18).toISOString(),\n },\n {\n id: '5',\n title: 'Best practices for organizing forum categories',\n body: 'We are launching a developer community and are unsure how to structure our categories. Should we go broad (3-5 categories) or granular (10+ sub-categories)? Looking for advice from people who have run communities before.',\n author: { id: 'u5', name: 'community_lead', avatar: null },\n category: { id: 'general', label: 'General', icon: '💬' },\n tags: ['community', 'organization', 'best-practices'],\n votes: 22,\n userVote: 0,\n replyCount: 17,\n viewCount: 312,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 24).toISOString(),\n },\n {\n id: '6',\n title: 'Building a searchable FAQ from pinned posts',\n body: 'One pattern I have found useful is using pinned posts as a structured FAQ. You can tag them with `faq` and surface them in a dedicated section. Here is how I set it up with the forum module.',\n author: { id: 'u1', name: 'alex_m', avatar: null },\n category: { id: 'general', label: 'General', icon: '💬' },\n tags: ['faq', 'pinned', 'pattern'],\n votes: 41,\n userVote: 0,\n replyCount: 6,\n viewCount: 188,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 36).toISOString(),\n },\n];\n\nexport const DEMO_REPLIES = [\n {\n id: 'r1',\n body: 'You can pass a `categories` prop directly to `<ForumPage>`. The shape is `{ id, label, icon, count }`. If you want a global default, set it in your `mn-config.js` under the `forum` key.',\n author: { id: 'u1', name: 'alex_m', avatar: null },\n votes: 15,\n userVote: 1,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 5).toISOString(),\n isAccepted: true,\n },\n {\n id: 'r2',\n body: 'Also worth noting — you can use the `CategoryNav` component standalone if you want to place it somewhere other than the default sidebar.',\n author: { id: 'u3', name: 'techwriter_k', avatar: null },\n votes: 8,\n userVote: 0,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 4).toISOString(),\n },\n {\n id: 'r3',\n body: 'Great question — I had the same issue when I first set up the forum. The docs example in the README shows the full config including custom categories.',\n author: { id: 'u5', name: 'community_lead', avatar: null },\n votes: 3,\n userVote: 0,\n createdAt: new Date(Date.now() - 1000 * 60 * 60 * 3).toISOString(),\n },\n];\n","/**\n * ForumPage — @mounaji_npm/forum\n *\n * Full forum listing page: category sidebar + search/sort header + post list.\n * Self-contained — no router assumptions, all navigation via callbacks.\n *\n * Props:\n * categories — Category[] sidebar list (default: DEMO_CATEGORIES)\n * posts — Post[] (default: DEMO_POSTS)\n * activeCategory — string category id (default: 'all')\n * searchQuery — string\n * sortBy — 'newest'|'top'|'unanswered'\n * onCategoryChange — (id) => void\n * onSearch — (q) => void\n * onSortChange — (sort) => void\n * onPostClick — (postId) => void\n * onNewPost — () => void\n * onVote — (postId, vote) => void\n * isLoading — boolean\n * isDark — boolean (default: true)\n * header — React node\n * title — string (default: 'Forum')\n * subtitle — string\n * style — CSSProperties\n */\n\nimport { useState, useMemo } from 'react';\nimport { CategoryNav } from './components/CategoryNav.jsx';\nimport { PostList } from './components/PostCard.jsx';\nimport { DEMO_POSTS, DEMO_CATEGORIES } from './demo.js';\n\nconst SORTS = [\n { id: 'newest', label: 'Newest' },\n { id: 'top', label: 'Top Voted' },\n { id: 'unanswered', label: 'Unanswered' },\n];\n\nexport function ForumPage({\n categories = DEMO_CATEGORIES,\n posts = DEMO_POSTS,\n activeCategory = 'all',\n searchQuery = '',\n sortBy = 'newest',\n onCategoryChange,\n onSearch,\n onSortChange,\n onPostClick,\n onNewPost,\n onVote,\n isLoading = false,\n isDark = true,\n header,\n title = 'Forum',\n subtitle = 'Discussions, questions, and ideas from the community.',\n style,\n}) {\n const [localSearch, setLocalSearch] = useState(searchQuery);\n const [localSort, setLocalSort] = useState(sortBy);\n const [localCategory, setLocalCategory] = useState(activeCategory);\n\n const textPri = isDark ? 'var(--mn-text-primary-dark, #F0F4FF)' : 'var(--mn-text-primary-light, #1A1A2E)';\n const textSec = isDark ? 'var(--mn-text-secondary-dark, #94A3B8)' : 'var(--mn-text-secondary-light, #64748B)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const inputBg = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.04)';\n\n function handleSearch(q) {\n setLocalSearch(q);\n onSearch?.(q);\n }\n\n function handleSort(s) {\n setLocalSort(s);\n onSortChange?.(s);\n }\n\n function handleCategory(id) {\n setLocalCategory(id);\n onCategoryChange?.(id);\n }\n\n // Client-side filter + sort (overridden by server data when posts prop changes)\n const displayed = useMemo(() => {\n let list = posts;\n if (localCategory !== 'all') {\n list = list.filter(p => p.category?.id === localCategory);\n }\n if (localSearch.trim()) {\n const q = localSearch.toLowerCase();\n list = list.filter(p => p.title.toLowerCase().includes(q) || p.body?.toLowerCase().includes(q));\n }\n if (localSort === 'top') list = [...list].sort((a, b) => b.votes - a.votes);\n if (localSort === 'newest') list = [...list].sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));\n if (localSort === 'unanswered') list = list.filter(p => !p.isSolved && (p.replyCount ?? 0) === 0);\n // Pinned always first\n return [...list].sort((a, b) => (b.isPinned ? 1 : 0) - (a.isPinned ? 1 : 0));\n }, [posts, localCategory, localSearch, localSort]);\n\n return (\n <div style={{\n padding: 'var(--mn-spacing-xl, 32px)',\n display: 'flex', flexDirection: 'column', gap: 24,\n fontFamily: 'var(--mn-font-family, system-ui, sans-serif)',\n ...style,\n }}>\n {/* Header */}\n {header ?? (\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: 12 }}>\n <div>\n <h1 style={{ margin: 0, fontSize: 'var(--mn-font-size-2xl, 1.5rem)', fontWeight: 700, color: textPri }}>{title}</h1>\n {subtitle && <p style={{ margin: '4px 0 0', fontSize: '0.875rem', color: textSec }}>{subtitle}</p>}\n </div>\n <button\n onClick={onNewPost}\n style={{ padding: '8px 18px', borderRadius: 'var(--mn-radius-md, 0.5rem)', border: 'none', cursor: 'pointer', backgroundColor: 'var(--mn-color-primary, #3B82F6)', color: '#fff', fontSize: '0.875rem', fontWeight: 600, fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 6 }}\n >\n + New Post\n </button>\n </div>\n )}\n\n {/* Body: sidebar + main */}\n <div style={{ display: 'flex', gap: 20, alignItems: 'flex-start' }}>\n {/* Sidebar */}\n <div style={{ width: 200, flexShrink: 0, position: 'sticky', top: 80 }}>\n <CategoryNav\n categories={categories}\n active={localCategory}\n onChange={handleCategory}\n isDark={isDark}\n />\n </div>\n\n {/* Main column */}\n <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 14 }}>\n {/* Search + sort bar */}\n <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>\n {/* Search */}\n <div style={{ position: 'relative', flex: '1 1 200px' }}>\n <span style={{ position: 'absolute', left: 10, top: '50%', transform: 'translateY(-50%)', color: textSec, pointerEvents: 'none', fontSize: 14 }}>🔍</span>\n <input\n value={localSearch}\n onChange={e => handleSearch(e.target.value)}\n placeholder=\"Search posts…\"\n style={{ width: '100%', boxSizing: 'border-box', padding: '8px 10px 8px 32px', borderRadius: 'var(--mn-radius-md, 0.5rem)', backgroundColor: inputBg, border: `1px solid ${border}`, color: textPri, fontSize: '0.875rem', fontFamily: 'inherit', outline: 'none' }}\n onFocus={e => { e.target.style.borderColor = 'var(--mn-color-primary, #3B82F6)'; }}\n onBlur={e => { e.target.style.borderColor = border; }}\n />\n </div>\n\n {/* Sort tabs */}\n <div style={{ display: 'flex', gap: 2, backgroundColor: isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)', padding: 3, borderRadius: 'var(--mn-radius-md, 0.5rem)' }}>\n {SORTS.map(s => {\n const isActive = localSort === s.id;\n return (\n <button\n key={s.id}\n onClick={() => handleSort(s.id)}\n style={{\n padding: '4px 12px', borderRadius: 6, border: 'none', cursor: 'pointer',\n backgroundColor: isActive ? (isDark ? 'rgba(255,255,255,0.09)' : '#fff') : 'transparent',\n color: isActive ? textPri : textSec,\n fontSize: '0.8125rem', fontWeight: isActive ? 600 : 400, fontFamily: 'inherit',\n transition: 'all 100ms',\n }}\n >\n {s.label}\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Post count */}\n {!isLoading && (\n <p style={{ margin: 0, fontSize: '0.8125rem', color: textSec }}>\n {displayed.length} {displayed.length === 1 ? 'post' : 'posts'}\n {localSearch ? ` matching \"${localSearch}\"` : ''}\n </p>\n )}\n\n {/* Post list */}\n <PostList\n posts={displayed}\n onPostClick={onPostClick}\n onVote={onVote}\n isLoading={isLoading}\n isDark={isDark}\n />\n </div>\n </div>\n </div>\n );\n}\n","/**\n * PostDetail — @mounaji_npm/forum\n *\n * Full post content view: title, body, metadata, tags.\n * Used inside PostPage.\n *\n * Props:\n * post — Post object\n * onVote — (postId, vote) => void\n * isDark — boolean\n */\n\nimport { VoteButton, AuthorMeta, TagChip, CategoryBadge } from './shared.jsx';\n\nexport function PostDetail({ post, onVote, isDark = true }) {\n const card = isDark ? 'var(--mn-color-card-dark, #0B0F23)' : 'var(--mn-color-card-light, #FAFAF8)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const textPri = isDark ? 'var(--mn-text-primary-dark, #F0F4FF)' : 'var(--mn-text-primary-light, #1A1A2E)';\n const textSec = isDark ? 'var(--mn-text-secondary-dark, #94A3B8)' : 'var(--mn-text-secondary-light, #64748B)';\n\n return (\n <div style={{ borderRadius: 'var(--mn-radius-lg, 0.75rem)', backgroundColor: card, border: `1px solid ${border}`, overflow: 'hidden' }}>\n {/* Post header */}\n <div style={{ padding: '20px 24px', borderBottom: `1px solid ${border}` }}>\n {/* Badges */}\n <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 12 }}>\n {post.isPinned && <StatusBadge color=\"warning\">📌 Pinned</StatusBadge>}\n {post.isSolved && <StatusBadge color=\"success\">✓ Solved</StatusBadge>}\n {post.isLocked && <StatusBadge color=\"muted\">🔒 Locked</StatusBadge>}\n <CategoryBadge category={post.category} />\n </div>\n\n {/* Title */}\n <h1 style={{ margin: '0 0 14px', fontSize: 'var(--mn-font-size-xl, 1.25rem)', fontWeight: 700, color: textPri, lineHeight: 1.4 }}>\n {post.title}\n </h1>\n\n {/* Author + date + stats */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>\n <AuthorMeta author={post.author} date={post.createdAt} prefix=\"posted\" isDark={isDark} />\n <span style={{ fontSize: '0.8125rem', color: textSec }}>👁 {post.viewCount ?? 0} views</span>\n <span style={{ fontSize: '0.8125rem', color: textSec }}>💬 {post.replyCount ?? 0} replies</span>\n </div>\n </div>\n\n {/* Post body + vote */}\n <div style={{ display: 'flex', gap: 0 }}>\n {/* Vote column */}\n <div style={{ padding: '20px 16px', borderRight: `1px solid ${border}`, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, flexShrink: 0 }}>\n <VoteButton\n count={post.votes}\n userVote={post.userVote ?? 0}\n onChange={v => onVote?.(post.id, v)}\n vertical\n isDark={isDark}\n />\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, padding: '20px 24px' }}>\n <div style={{ fontSize: '0.9375rem', color: textPri, lineHeight: 1.7, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n {post.body}\n </div>\n\n {/* Tags */}\n {post.tags?.length > 0 && (\n <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 18 }}>\n {post.tags.map(t => <TagChip key={t} label={t} isDark={isDark} />)}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nfunction StatusBadge({ color, children }) {\n const COLORS = {\n warning: { bg: 'rgba(245,158,11,0.12)', text: '#FCD34D', border: 'rgba(245,158,11,0.25)' },\n success: { bg: 'rgba(16,185,129,0.12)', text: '#34D399', border: 'rgba(16,185,129,0.25)' },\n muted: { bg: 'rgba(107,114,128,0.12)', text: '#9CA3AF', border: 'rgba(107,114,128,0.2)' },\n };\n const c = COLORS[color] ?? COLORS.muted;\n return (\n <span style={{ fontSize: '0.7rem', fontWeight: 600, padding: '2px 8px', borderRadius: 9999, backgroundColor: c.bg, color: c.text, border: `1px solid ${c.border}` }}>\n {children}\n </span>\n );\n}\n","/**\n * ReplyThread — @mounaji_npm/forum\n *\n * Exports:\n * ReplyCard — single reply with vote + accepted badge\n * ReplyThread — ordered list of ReplyCards + ReplyComposer\n * ReplyComposer — textarea + submit button for writing a reply\n */\n\nimport { useState } from 'react';\nimport { VoteButton, AuthorMeta, Avatar } from './shared.jsx';\n\n// ─── ReplyCard ────────────────────────────────────────────────────────────────\n\n/**\n * Props:\n * reply — Reply object { id, body, author, votes, userVote, createdAt, isAccepted }\n * onVote — (replyId, vote) => void\n * onAccept — (replyId) => void (marks as accepted answer)\n * canAccept — boolean (only post author can accept)\n * isDark — boolean\n */\nexport function ReplyCard({ reply, onVote, onAccept, canAccept = false, isDark = true }) {\n const card = isDark ? 'var(--mn-color-card-dark, #0B0F23)' : 'var(--mn-color-card-light, #FAFAF8)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const textPri = isDark ? 'var(--mn-text-primary-dark, #F0F4FF)' : 'var(--mn-text-primary-light, #1A1A2E)';\n const textSec = isDark ? 'var(--mn-text-secondary-dark, #94A3B8)' : 'var(--mn-text-secondary-light, #64748B)';\n\n const acceptedBorder = reply.isAccepted ? 'rgba(16,185,129,0.35)' : border;\n const acceptedBg = reply.isAccepted\n ? (isDark ? 'rgba(16,185,129,0.05)' : 'rgba(16,185,129,0.04)')\n : card;\n\n return (\n <div style={{ display: 'flex', borderRadius: 'var(--mn-radius-lg, 0.75rem)', backgroundColor: acceptedBg, border: `1px solid ${acceptedBorder}`, overflow: 'hidden' }}>\n {/* Vote column */}\n <div style={{ padding: '16px 14px', borderRight: `1px solid ${border}`, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, flexShrink: 0 }}>\n <VoteButton\n count={reply.votes}\n userVote={reply.userVote ?? 0}\n onChange={v => onVote?.(reply.id, v)}\n vertical\n isDark={isDark}\n size=\"sm\"\n />\n {/* Accept button */}\n {(reply.isAccepted || canAccept) && (\n <button\n onClick={() => onAccept?.(reply.id)}\n title={reply.isAccepted ? 'Accepted answer' : 'Mark as accepted'}\n style={{\n marginTop: 6, width: 28, height: 28, borderRadius: 6, border: 'none', cursor: canAccept ? 'pointer' : 'default',\n backgroundColor: reply.isAccepted ? 'rgba(16,185,129,0.15)' : 'transparent',\n color: reply.isAccepted ? '#10B981' : textSec,\n display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14,\n transition: 'background 100ms',\n }}\n onMouseEnter={e => { if (canAccept && !reply.isAccepted) e.currentTarget.style.backgroundColor = 'rgba(16,185,129,0.1)'; }}\n onMouseLeave={e => { if (!reply.isAccepted) e.currentTarget.style.backgroundColor = 'transparent'; }}\n >\n ✓\n </button>\n )}\n </div>\n\n {/* Content */}\n <div style={{ flex: 1, padding: '16px 18px', minWidth: 0 }}>\n {reply.isAccepted && (\n <div style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: '0.75rem', fontWeight: 600, color: '#10B981', marginBottom: 10 }}>\n <span>✓</span> Accepted Answer\n </div>\n )}\n\n <div style={{ fontSize: '0.9375rem', color: textPri, lineHeight: 1.65, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>\n {reply.body}\n </div>\n\n <div style={{ marginTop: 12 }}>\n <AuthorMeta author={reply.author} date={reply.createdAt} prefix=\"replied\" isDark={isDark} size=\"sm\" />\n </div>\n </div>\n </div>\n );\n}\n\n// ─── ReplyThread ──────────────────────────────────────────────────────────────\n\n/**\n * Props:\n * replies — Reply[]\n * onVote — (replyId, vote) => void\n * onAccept — (replyId) => void\n * canAccept — boolean\n * currentUser — { id, name, avatar? } | null\n * onSubmit — (body: string) => void | Promise<void>\n * isLocked — boolean\n * isDark — boolean\n */\nexport function ReplyThread({ replies = [], onVote, onAccept, canAccept = false, currentUser, onSubmit, isLocked = false, isDark = true }) {\n const textPri = isDark ? '#F0F4FF' : '#1A1A2E';\n const textSec = isDark ? '#94A3B8' : '#64748B';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n\n // Pin accepted answer to top, then sort by votes\n const sorted = [...replies].sort((a, b) => {\n if (a.isAccepted && !b.isAccepted) return -1;\n if (!a.isAccepted && b.isAccepted) return 1;\n return b.votes - a.votes;\n });\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>\n {/* Header */}\n {replies.length > 0 && (\n <div style={{ paddingBottom: 12, borderBottom: `1px solid ${border}` }}>\n <h2 style={{ margin: 0, fontSize: '1rem', fontWeight: 600, color: textPri }}>\n {replies.length} {replies.length === 1 ? 'Reply' : 'Replies'}\n </h2>\n </div>\n )}\n\n {/* Reply cards */}\n {sorted.length > 0 && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\n {sorted.map(reply => (\n <ReplyCard\n key={reply.id}\n reply={reply}\n onVote={onVote}\n onAccept={onAccept}\n canAccept={canAccept}\n isDark={isDark}\n />\n ))}\n </div>\n )}\n\n {/* Composer or locked notice */}\n {isLocked ? (\n <div style={{ textAlign: 'center', padding: '20px', color: textSec, fontSize: '0.875rem', backgroundColor: isDark ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.03)', borderRadius: 'var(--mn-radius-md, 0.5rem)', border: `1px solid ${border}` }}>\n 🔒 This thread is locked — no new replies allowed.\n </div>\n ) : (\n <ReplyComposer\n currentUser={currentUser}\n onSubmit={onSubmit}\n isDark={isDark}\n placeholder={replies.length === 0 ? 'Be the first to reply…' : 'Write a reply…'}\n />\n )}\n </div>\n );\n}\n\n// ─── ReplyComposer ────────────────────────────────────────────────────────────\n\n/**\n * Props:\n * currentUser — { name, avatar? } | null\n * onSubmit — (body: string) => void | Promise<void>\n * placeholder — string\n * isDark — boolean\n */\nexport function ReplyComposer({ currentUser, onSubmit, placeholder = 'Write a reply…', isDark = true }) {\n const [body, setBody] = useState('');\n const [submitting, setSub] = useState(false);\n const [error, setError] = useState('');\n\n const card = isDark ? 'var(--mn-color-card-dark, #0B0F23)' : 'var(--mn-color-card-light, #FAFAF8)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const textPri = isDark ? '#F0F4FF' : '#1A1A2E';\n const textSec = isDark ? '#94A3B8' : '#64748B';\n const inputBg = isDark ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.03)';\n\n async function handleSubmit() {\n const trimmed = body.trim();\n if (!trimmed) { setError('Reply cannot be empty.'); return; }\n setError('');\n setSub(true);\n try {\n await onSubmit?.(trimmed);\n setBody('');\n } finally {\n setSub(false);\n }\n }\n\n return (\n <div style={{ borderRadius: 'var(--mn-radius-lg, 0.75rem)', backgroundColor: card, border: `1px solid ${border}`, padding: '16px 18px', display: 'flex', flexDirection: 'column', gap: 12 }}>\n {/* Composer header */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n <Avatar name={currentUser?.name ?? '?'} size={26} src={currentUser?.avatar} />\n <span style={{ fontSize: '0.8125rem', fontWeight: 600, color: textPri }}>\n {currentUser ? currentUser.name : 'Reply as Guest'}\n </span>\n </div>\n\n {/* Textarea */}\n <textarea\n value={body}\n onChange={e => { setBody(e.target.value); if (error) setError(''); }}\n placeholder={placeholder}\n rows={4}\n style={{\n width: '100%', boxSizing: 'border-box',\n padding: '10px 12px', borderRadius: 'var(--mn-radius-md, 0.5rem)',\n backgroundColor: inputBg, border: `1px solid ${error ? 'rgba(239,68,68,0.4)' : border}`,\n color: textPri, fontSize: '0.9375rem', lineHeight: 1.6, resize: 'vertical',\n fontFamily: 'var(--mn-font-family, system-ui, sans-serif)', outline: 'none',\n transition: 'border-color 120ms',\n }}\n onFocus={e => { e.target.style.borderColor = 'var(--mn-color-primary, #3B82F6)'; }}\n onBlur={e => { e.target.style.borderColor = error ? 'rgba(239,68,68,0.4)' : border; }}\n />\n\n {error && <p style={{ margin: 0, fontSize: '0.8125rem', color: '#F87171' }}>{error}</p>}\n\n {/* Footer */}\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\n <span style={{ fontSize: '0.75rem', color: textSec }}>{body.length} / 8000</span>\n <button\n onClick={handleSubmit}\n disabled={submitting || !body.trim()}\n style={{\n padding: '7px 18px', borderRadius: 'var(--mn-radius-md, 0.5rem)', border: 'none',\n cursor: submitting || !body.trim() ? 'not-allowed' : 'pointer',\n backgroundColor: submitting || !body.trim() ? 'rgba(59,130,246,0.4)' : 'var(--mn-color-primary, #3B82F6)',\n color: '#fff', fontSize: '0.875rem', fontWeight: 600, fontFamily: 'inherit',\n transition: 'background 120ms', display: 'flex', alignItems: 'center', gap: 7,\n }}\n >\n {submitting && <Spinner />}\n {submitting ? 'Posting…' : 'Post Reply'}\n </button>\n </div>\n </div>\n );\n}\n\nfunction Spinner() {\n return <span style={{ display: 'inline-block', width: 12, height: 12, border: '2px solid rgba(255,255,255,0.3)', borderTopColor: '#fff', borderRadius: '50%', animation: 'mn-spin 0.6s linear infinite' }}>\n <style>{`@keyframes mn-spin { to { transform: rotate(360deg); } }`}</style>\n </span>;\n}\n","/**\n * PostPage — @mounaji_npm/forum\n *\n * Full post detail page: back button, post content, reply thread.\n * No router assumptions — navigation via callbacks.\n *\n * Props:\n * post — Post object (required)\n * replies — Reply[]\n * currentUser — { id, name, avatar? } | null\n * onBack — () => void\n * onVotePost — (postId, vote) => void\n * onVoteReply — (replyId, vote) => void\n * onAccept — (replyId) => void\n * onSubmitReply — (body: string) => void | Promise<void>\n * isLoading — boolean\n * isDark — boolean (default: true)\n * style — CSSProperties\n */\n\nimport { PostDetail } from './components/PostDetail.jsx';\nimport { ReplyThread } from './components/ReplyThread.jsx';\nimport { DEMO_POSTS, DEMO_REPLIES } from './demo.js';\n\nexport function PostPage({\n post = DEMO_POSTS[0],\n replies = DEMO_REPLIES,\n currentUser = null,\n onBack,\n onVotePost,\n onVoteReply,\n onAccept,\n onSubmitReply,\n isLoading = false,\n isDark = true,\n style,\n}) {\n const textPri = isDark ? 'var(--mn-text-primary-dark, #F0F4FF)' : 'var(--mn-text-primary-light, #1A1A2E)';\n const textSec = isDark ? 'var(--mn-text-secondary-dark, #94A3B8)' : 'var(--mn-text-secondary-light, #64748B)';\n\n // Only the post author can accept replies\n const canAccept = currentUser && post?.author?.id === currentUser?.id;\n\n if (isLoading) {\n return (\n <div style={{ padding: 'var(--mn-spacing-xl, 32px)', fontFamily: 'var(--mn-font-family, system-ui, sans-serif)', ...style }}>\n <PostSkeleton isDark={isDark} />\n </div>\n );\n }\n\n if (!post) {\n return (\n <div style={{ padding: 'var(--mn-spacing-xl, 32px)', textAlign: 'center', color: textSec, fontFamily: 'var(--mn-font-family, system-ui, sans-serif)', ...style }}>\n <p style={{ fontSize: 32, margin: '0 0 12px' }}>🔍</p>\n <p style={{ margin: 0, fontWeight: 600, color: textPri }}>Post not found</p>\n </div>\n );\n }\n\n return (\n <div style={{\n padding: 'var(--mn-spacing-xl, 32px)',\n display: 'flex', flexDirection: 'column', gap: 20, maxWidth: 860,\n fontFamily: 'var(--mn-font-family, system-ui, sans-serif)',\n ...style,\n }}>\n {/* Back nav */}\n <button\n onClick={onBack}\n style={{\n alignSelf: 'flex-start', display: 'flex', alignItems: 'center', gap: 6,\n padding: '6px 12px', borderRadius: 'var(--mn-radius-md, 0.5rem)', border: 'none',\n cursor: 'pointer', backgroundColor: isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)',\n color: textSec, fontSize: '0.875rem', fontFamily: 'inherit', transition: 'background 100ms',\n }}\n onMouseEnter={e => { e.currentTarget.style.backgroundColor = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)'; }}\n onMouseLeave={e => { e.currentTarget.style.backgroundColor = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'; }}\n >\n ← Back to Forum\n </button>\n\n {/* Post content */}\n <PostDetail\n post={post}\n onVote={onVotePost}\n isDark={isDark}\n />\n\n {/* Reply thread */}\n <ReplyThread\n replies={replies}\n onVote={onVoteReply}\n onAccept={onAccept}\n canAccept={canAccept}\n currentUser={currentUser}\n onSubmit={onSubmitReply}\n isLocked={post.isLocked}\n isDark={isDark}\n />\n </div>\n );\n}\n\nfunction PostSkeleton({ isDark }) {\n const bg = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const card = isDark ? 'var(--mn-color-card-dark, #0B0F23)' : 'var(--mn-color-card-light, #FAFAF8)';\n const S = (w, h = 12) => ({ width: w, height: h, borderRadius: 6, backgroundColor: bg, animation: 'mn-pulse 1.4s ease infinite' });\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n <div style={S(80)} />\n <div style={{ borderRadius: 'var(--mn-radius-lg, 0.75rem)', backgroundColor: card, border: `1px solid ${border}`, padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 14 }}>\n <div style={S('30%', 8)} />\n <div style={S('70%', 20)} />\n <div style={S('45%', 10)} />\n <div style={{ height: 80, borderRadius: 6, backgroundColor: bg }} />\n </div>\n <style>{`@keyframes mn-pulse { 0%,100%{opacity:.5} 50%{opacity:1} }`}</style>\n </div>\n );\n}\n","/**\n * CreatePostPage — @mounaji_npm/forum\n *\n * New post form: title, body, category selector, tags input.\n * No router assumptions.\n *\n * Props:\n * categories — Category[]\n * onSubmit — (post: { title, body, categoryId, tags }) => void | Promise\n * onCancel — () => void\n * currentUser — { name, avatar? } | null\n * isDark — boolean (default: true)\n * style — CSSProperties\n */\n\nimport { useState } from 'react';\nimport { DEMO_CATEGORIES } from './demo.js';\nimport { Avatar } from './components/shared.jsx';\n\nexport function CreatePostPage({\n categories = DEMO_CATEGORIES.filter(c => c.id !== 'all'),\n onSubmit,\n onCancel,\n currentUser = null,\n isDark = true,\n style,\n}) {\n const [title, setTitle] = useState('');\n const [body, setBody] = useState('');\n const [categoryId, setCategory] = useState('');\n const [tagInput, setTagInput] = useState('');\n const [tags, setTags] = useState([]);\n const [submitting, setSub] = useState(false);\n const [errors, setErrors] = useState({});\n\n const card = isDark ? 'var(--mn-color-card-dark, #0B0F23)' : 'var(--mn-color-card-light, #FAFAF8)';\n const border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n const textPri = isDark ? 'var(--mn-text-primary-dark, #F0F4FF)' : 'var(--mn-text-primary-light, #1A1A2E)';\n const textSec = isDark ? 'var(--mn-text-secondary-dark, #94A3B8)' : 'var(--mn-text-secondary-light, #64748B)';\n const inputBg = isDark ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.03)';\n\n function validate() {\n const e = {};\n if (!title.trim()) e.title = 'Title is required.';\n if (title.length > 200) e.title = 'Title must be under 200 characters.';\n if (!body.trim()) e.body = 'Body is required.';\n if (!categoryId) e.category = 'Please choose a category.';\n return e;\n }\n\n async function handleSubmit(e) {\n e.preventDefault();\n const errs = validate();\n if (Object.keys(errs).length) { setErrors(errs); return; }\n setErrors({});\n setSub(true);\n try {\n await onSubmit?.({ title: title.trim(), body: body.trim(), categoryId, tags });\n } finally {\n setSub(false);\n }\n }\n\n function handleTagKeyDown(e) {\n if ((e.key === 'Enter' || e.key === ',') && tagInput.trim()) {\n e.preventDefault();\n const newTag = tagInput.trim().toLowerCase().replace(/[^a-z0-9-]/g, '-');\n if (!tags.includes(newTag) && tags.length < 5) {\n setTags(prev => [...prev, newTag]);\n }\n setTagInput('');\n }\n if (e.key === 'Backspace' && !tagInput && tags.length) {\n setTags(prev => prev.slice(0, -1));\n }\n }\n\n const inputStyle = (hasError) => ({\n width: '100%', boxSizing: 'border-box', padding: '10px 12px',\n borderRadius: 'var(--mn-radius-md, 0.5rem)',\n backgroundColor: inputBg, border: `1px solid ${hasError ? 'rgba(239,68,68,0.4)' : border}`,\n color: textPri, fontSize: '0.9375rem', fontFamily: 'var(--mn-font-family, system-ui, sans-serif)',\n outline: 'none', transition: 'border-color 120ms',\n });\n\n return (\n <div style={{\n padding: 'var(--mn-spacing-xl, 32px)',\n display: 'flex', flexDirection: 'column', gap: 20,\n maxWidth: 780, fontFamily: 'var(--mn-font-family, system-ui, sans-serif)',\n ...style,\n }}>\n {/* Header */}\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>\n <div>\n <h1 style={{ margin: 0, fontSize: 'var(--mn-font-size-xl, 1.25rem)', fontWeight: 700, color: textPri }}>New Post</h1>\n <p style={{ margin: '4px 0 0', fontSize: '0.875rem', color: textSec }}>Share a question, idea, or discussion with the community.</p>\n </div>\n {onCancel && (\n <button\n onClick={onCancel}\n style={{ padding: '6px 14px', borderRadius: 'var(--mn-radius-md, 0.5rem)', border: `1px solid ${border}`, cursor: 'pointer', backgroundColor: 'transparent', color: textSec, fontSize: '0.875rem', fontFamily: 'inherit' }}\n >\n Cancel\n </button>\n )}\n </div>\n\n {/* Form card */}\n <form\n onSubmit={handleSubmit}\n style={{ borderRadius: 'var(--mn-radius-lg, 0.75rem)', backgroundColor: card, border: `1px solid ${border}`, padding: '24px', display: 'flex', flexDirection: 'column', gap: 20 }}\n >\n {/* Author hint */}\n {currentUser && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '8px 12px', borderRadius: 'var(--mn-radius-md, 0.5rem)', backgroundColor: isDark ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.03)', border: `1px solid ${border}` }}>\n <Avatar name={currentUser.name} size={24} src={currentUser.avatar} />\n <span style={{ fontSize: '0.875rem', color: textPri }}>Posting as <strong>{currentUser.name}</strong></span>\n </div>\n )}\n\n {/* Title */}\n <Field label=\"Title\" error={errors.title} required>\n <input\n value={title}\n onChange={e => { setTitle(e.target.value); if (errors.title) setErrors(p => ({ ...p, title: '' })); }}\n placeholder=\"What is your question or topic?\"\n style={inputStyle(errors.title)}\n onFocus={e => { e.target.style.borderColor = 'var(--mn-color-primary, #3B82F6)'; }}\n onBlur={e => { e.target.style.borderColor = errors.title ? 'rgba(239,68,68,0.4)' : border; }}\n />\n <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 4 }}>\n <span style={{ fontSize: '0.75rem', color: title.length > 180 ? '#F87171' : textSec }}>{title.length}/200</span>\n </div>\n </Field>\n\n {/* Category */}\n <Field label=\"Category\" error={errors.category} required>\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\n {categories.map(cat => {\n const isSelected = categoryId === cat.id;\n return (\n <button\n key={cat.id}\n type=\"button\"\n onClick={() => { setCategory(cat.id); if (errors.category) setErrors(p => ({ ...p, category: '' })); }}\n style={{\n display: 'flex', alignItems: 'center', gap: 6, padding: '7px 14px',\n borderRadius: 'var(--mn-radius-md, 0.5rem)', border: `1px solid ${isSelected ? 'var(--mn-color-primary, #3B82F6)' : border}`,\n cursor: 'pointer', fontFamily: 'inherit', fontSize: '0.875rem',\n backgroundColor: isSelected ? 'rgba(59,130,246,0.1)' : inputBg,\n color: isSelected ? 'var(--mn-color-primary, #3B82F6)' : textPri,\n transition: 'all 100ms', fontWeight: isSelected ? 600 : 400,\n }}\n >\n {cat.icon && <span>{cat.icon}</span>}\n {cat.label}\n </button>\n );\n })}\n </div>\n </Field>\n\n {/* Body */}\n <Field label=\"Body\" error={errors.body} required>\n <textarea\n value={body}\n onChange={e => { setBody(e.target.value); if (errors.body) setErrors(p => ({ ...p, body: '' })); }}\n placeholder=\"Describe your question or topic in detail. The more context you provide, the better the community can help.\"\n rows={8}\n style={{ ...inputStyle(errors.body), resize: 'vertical', lineHeight: 1.65 }}\n onFocus={e => { e.target.style.borderColor = 'var(--mn-color-primary, #3B82F6)'; }}\n onBlur={e => { e.target.style.borderColor = errors.body ? 'rgba(239,68,68,0.4)' : border; }}\n />\n </Field>\n\n {/* Tags */}\n <Field label=\"Tags\" hint=\"Up to 5 tags. Press Enter or comma to add.\">\n <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', padding: '8px 10px', borderRadius: 'var(--mn-radius-md, 0.5rem)', backgroundColor: inputBg, border: `1px solid ${border}`, minHeight: 42, alignItems: 'center' }}>\n {tags.map(t => (\n <span key={t} style={{ display: 'flex', alignItems: 'center', gap: 4, fontSize: '0.75rem', padding: '2px 8px', borderRadius: 9999, backgroundColor: isDark ? 'rgba(59,130,246,0.1)' : 'rgba(59,130,246,0.07)', color: '#60A5FA', border: '1px solid rgba(59,130,246,0.2)' }}>\n #{t}\n <button type=\"button\" onClick={() => setTags(prev => prev.filter(x => x !== t))} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'inherit', padding: 0, fontSize: 12, lineHeight: 1, display: 'flex', alignItems: 'center' }}>×</button>\n </span>\n ))}\n {tags.length < 5 && (\n <input\n value={tagInput}\n onChange={e => setTagInput(e.target.value)}\n onKeyDown={handleTagKeyDown}\n placeholder={tags.length === 0 ? 'e.g. bug, question, feature' : ''}\n style={{ border: 'none', outline: 'none', backgroundColor: 'transparent', color: textPri, fontSize: '0.875rem', fontFamily: 'inherit', flex: 1, minWidth: 120 }}\n />\n )}\n </div>\n </Field>\n\n {/* Submit */}\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10, paddingTop: 4, borderTop: `1px solid ${border}`, marginTop: 4 }}>\n {onCancel && (\n <button type=\"button\" onClick={onCancel} style={{ padding: '9px 20px', borderRadius: 'var(--mn-radius-md, 0.5rem)', border: `1px solid ${border}`, cursor: 'pointer', backgroundColor: 'transparent', color: textSec, fontSize: '0.875rem', fontFamily: 'inherit' }}>\n Cancel\n </button>\n )}\n <button\n type=\"submit\"\n disabled={submitting}\n style={{ padding: '9px 24px', borderRadius: 'var(--mn-radius-md, 0.5rem)', border: 'none', cursor: submitting ? 'wait' : 'pointer', backgroundColor: submitting ? 'rgba(59,130,246,0.5)' : 'var(--mn-color-primary, #3B82F6)', color: '#fff', fontSize: '0.875rem', fontWeight: 600, fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 8 }}\n >\n {submitting && <Spinner />}\n {submitting ? 'Publishing…' : 'Publish Post'}\n </button>\n </div>\n </form>\n </div>\n );\n}\n\nfunction Field({ label, children, error, hint, required }) {\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>\n <label style={{ fontSize: '0.875rem', fontWeight: 600, color: 'var(--mn-text-primary-dark, #F0F4FF)', display: 'flex', gap: 4 }}>\n {label}\n {required && <span style={{ color: '#F87171' }}>*</span>}\n </label>\n {children}\n {hint && !error && <p style={{ margin: 0, fontSize: '0.75rem', color: 'var(--mn-text-secondary-dark, #94A3B8)' }}>{hint}</p>}\n {error && <p style={{ margin: 0, fontSize: '0.8125rem', color: '#F87171' }}>{error}</p>}\n </div>\n );\n}\n\nfunction Spinner() {\n return <span style={{ display: 'inline-block', width: 12, height: 12, border: '2px solid rgba(255,255,255,0.3)', borderTopColor: '#fff', borderRadius: '50%', animation: 'mn-spin 0.6s linear infinite' }}>\n <style>{`@keyframes mn-spin { to { transform: rotate(360deg); } }`}</style>\n </span>;\n}\n"],"names":["CategoryNav","categories","active","onChange","isDark","title","style","card","border","textPri","textSec","jsxs","jsx","cat","isActive","e","VoteButton","count","userVote","vertical","size","optimistic","setOptimistic","useState","vote","total","upCol","downCol","numCol","btnSz","iconSz","cast","v","next","VBtn","icon","color","onClick","AuthorMeta","author","date","prefix","avatarSz","fontSize","Avatar","Fragment","formatRelative","TagChip","label","CAT_COLORS","CategoryBadge","category","c","name","src","initials","bg","h","d","diff","PostCard","post","onVote","compact","_a","t","MetaCount","value","PostList","posts","onPostClick","isLoading","_","i","SkeletonCard","EmptyPostList","message","cta","onCta","S","w","DEMO_CATEGORIES","DEMO_POSTS","DEMO_REPLIES","SORTS","ForumPage","activeCategory","searchQuery","sortBy","onCategoryChange","onSearch","onSortChange","onNewPost","header","subtitle","localSearch","setLocalSearch","localSort","setLocalSort","localCategory","setLocalCategory","inputBg","handleSearch","q","handleSort","s","handleCategory","id","displayed","useMemo","list","p","a","b","PostDetail","StatusBadge","children","COLORS","ReplyCard","reply","onAccept","canAccept","acceptedBorder","acceptedBg","ReplyThread","replies","currentUser","onSubmit","isLocked","sorted","ReplyComposer","placeholder","body","setBody","submitting","setSub","error","setError","handleSubmit","trimmed","Spinner","PostPage","onBack","onVotePost","onVoteReply","onSubmitReply","PostSkeleton","CreatePostPage","onCancel","setTitle","categoryId","setCategory","tagInput","setTagInput","tags","setTags","errors","setErrors","validate","errs","handleTagKeyDown","newTag","prev","inputStyle","hasError","Field","isSelected","x","hint","required"],"mappings":";;;AAcO,SAASA,EAAY,EAAE,YAAAC,IAAa,CAAA,GAAI,QAAAC,IAAS,OAAO,UAAAC,GAAU,QAAAC,IAAS,IAAM,OAAAC,IAAQ,cAAc,OAAAC,KAAS;AACrH,QAAMC,IAAUH,IAAS,uCAA2C,uCAC9DI,IAAUJ,IAAS,2BAA4C,oBAC/DK,IAAUL,IAAS,yCAA2C,yCAC9DM,IAAUN,IAAS,2CAA2C;AAEpE,SACE,gBAAAO,EAAC,SAAI,OAAO;AAAA,IACV,cAAc;AAAA,IACd,iBAAiBJ;AAAA,IACjB,QAAQ,aAAaC,CAAM;AAAA,IAC3B,UAAU;AAAA,IACV,GAAGF;AAAA,EAAA,GAEF,UAAA;AAAA,IAAAD,KACC,gBAAAO,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,aAAa,cAAc,aAAaJ,CAAM,GAAA,GACnE,UAAA,gBAAAI,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,WAAW,YAAY,KAAK,OAAOF,GAAS,eAAe,aAAa,eAAe,SAAA,GACrH,aACH,GACF;AAAA,IAEF,gBAAAE,EAAC,SAAI,OAAO,EAAE,SAAS,QAAA,GACpB,UAAAX,EAAW,IAAI,CAAAY,MAAO;AACrB,YAAMC,IAAWZ,MAAWW,EAAI;AAChC,aACE,gBAAAF;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,SAAS,MAAMR,KAAA,gBAAAA,EAAWU,EAAI;AAAA,UAC9B,OAAO;AAAA,YACL,OAAO;AAAA,YAAQ,SAAS;AAAA,YAAQ,YAAY;AAAA,YAAU,gBAAgB;AAAA,YACtE,SAAS;AAAA,YAAY,QAAQ;AAAA,YAAQ,QAAQ;AAAA,YAAW,YAAY;AAAA,YACpE,iBAAiBC,IACZV,IAAS,yBAAyB,0BACnC;AAAA,YACJ,YAAY,aAAaU,IAAW,qCAAqC,aAAa;AAAA,YACtF,YAAY;AAAA,YACZ,KAAK;AAAA,UAAA;AAAA,UAEP,cAAc,CAAAC,MAAK;AAAE,YAAKD,MAAUC,EAAE,cAAc,MAAM,kBAAkBX,IAAS,2BAA2B;AAAA,UAAoB;AAAA,UACpI,cAAc,CAAAW,MAAK;AAAE,YAAKD,MAAUC,EAAE,cAAc,MAAM,kBAAkB;AAAA,UAAe;AAAA,UAE3F,UAAA;AAAA,YAAA,gBAAAJ,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,GAAG,UAAU,EAAA,GACpE,UAAA;AAAA,cAAAE,EAAI,QAAQ,gBAAAD,EAAC,QAAA,EAAK,OAAO,EAAE,UAAU,IAAI,YAAY,EAAA,GAAM,UAAAC,EAAI,KAAA,CAAK;AAAA,cACrE,gBAAAD,EAAC,UAAK,OAAO;AAAA,gBACX,UAAU;AAAA,gBACV,YAAYE,IAAW,MAAM;AAAA,gBAC7B,OAAOA,IAAW,qCAAqCL;AAAA,gBACvD,YAAY;AAAA,gBAAU,UAAU;AAAA,gBAAU,cAAc;AAAA,cAAA,GAEvD,YAAI,MAAA,CACP;AAAA,YAAA,GACF;AAAA,YACCI,EAAI,SAAS,QACZ,gBAAAD,EAAC,UAAK,OAAO;AAAA,cACX,UAAU;AAAA,cAAU,YAAY;AAAA,cAAK,SAAS;AAAA,cAAW,cAAc;AAAA,cACvE,iBAAiBE,IAAW,0BAA2BV,IAAS,2BAA2B;AAAA,cAC3F,OAAOU,IAAW,qCAAqCJ;AAAA,cACvD,YAAY;AAAA,YAAA,GAEX,YAAI,MAAA,CACP;AAAA,UAAA;AAAA,QAAA;AAAA,QAlCGG,EAAI;AAAA,MAAA;AAAA,IAsCf,CAAC,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;ACjEO,SAASG,EAAW,EAAE,OAAAC,IAAQ,GAAG,UAAAC,IAAW,GAAG,UAAAf,GAAU,UAAAgB,IAAW,IAAO,QAAAf,IAAS,IAAM,MAAAgB,IAAO,QAAQ;AAC9G,QAAM,CAACC,GAAYC,CAAa,IAAIC,EAAS,IAAI,GAE3CC,IAASH,KAAcH,GACvBO,IAASJ,MAAe,OAAOJ,KAASI,IAAaH,KAAYD,GACjES,IAASF,MAAS,IAAK,YAAapB,IAAS,YAAY,WACzDuB,IAAUH,MAAS,KAAK,YAAapB,IAAS,YAAY,WAC1DwB,IAAUJ,MAAS,IAAK,YAAYA,MAAS,KAAK,YAAapB,IAAS,YAAY,WACpFyB,IAAUT,MAAS,OAAO,KAAK,IAC/BU,IAAUV,MAAS,OAAO,KAAK;AAErC,WAASW,EAAKC,GAAG;AACf,UAAMC,IAAOT,MAASQ,IAAI,IAAIA;AAC9B,IAAAV,EAAcW,CAAI,GAClB9B,KAAA,QAAAA,EAAW8B;AAAA,EACb;AAMA,SACE,gBAAAtB,EAAC,OAAA,EAAI,OALWQ,IACd,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,KAAK,EAAA,IACvE,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,EAAA,GAI9C,UAAA;AAAA,IAAA,gBAAAP,EAACsB,KAAK,MAAML,GAAO,MAAsB,KAAW,OAAOH,GAAO,QAAAI,GAAgB,SAAS,MAAMC,EAAK,CAAC,GAAG,OAAM,UAAS;AAAA,sBACxH,QAAA,EAAK,OAAO,EAAE,UAAUX,MAAS,OAAO,YAAY,YAAY,YAAY,KAAK,OAAOQ,GAAQ,UAAU,IAAI,WAAW,SAAA,GACvH,UAAAH,GACH;AAAA,IACCN,KAAY,gBAAAP,EAACsB,GAAA,EAAK,MAAML,GAAO,MAAK,KAAI,OAAOF,GAAS,QAAAG,GAAgB,SAAS,MAAMC,EAAK,EAAE,GAAG,OAAM,WAAA,CAAW;AAAA,EAAA,GACrH;AAEJ;AAEA,SAASG,EAAK,EAAE,MAAAd,GAAM,MAAAe,GAAM,OAAAC,GAAO,QAAAN,GAAQ,SAAAO,GAAS,OAAAhC,KAAS;AAC3D,SACE,gBAAAO;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAAyB;AAAA,MACA,OAAAhC;AAAA,MACA,OAAO;AAAA,QACL,OAAOe;AAAA,QAAM,QAAQA;AAAA,QAAM,cAAc;AAAA,QAAG,QAAQ;AAAA,QAAQ,QAAQ;AAAA,QACpE,iBAAiB;AAAA,QAAe,OAAAgB;AAAA,QAAO,UAAUN;AAAA,QACjD,SAAS;AAAA,QAAQ,YAAY;AAAA,QAAU,gBAAgB;AAAA,QACvD,YAAY;AAAA,QAAiC,SAAS;AAAA,QAAG,YAAY;AAAA,MAAA;AAAA,MAEvE,cAAc,CAAAf,MAAK;AAAE,QAAAA,EAAE,cAAc,MAAM,kBAAkB;AAAA,MAA0B;AAAA,MACvF,cAAc,CAAAA,MAAK;AAAE,QAAAA,EAAE,cAAc,MAAM,kBAAkB;AAAA,MAAe;AAAA,MAE3E,UAAAoB;AAAA,IAAA;AAAA,EAAA;AAGP;AAYO,SAASG,EAAW,EAAE,QAAAC,GAAQ,MAAAC,GAAM,QAAAC,IAAS,IAAI,QAAArC,IAAS,IAAM,MAAAgB,IAAO,QAAQ;AACpF,QAAMV,IAAUN,IAAS,YAAY,WAC/BK,IAAUL,IAAS,YAAY,WAC/BsC,IAAWtB,MAAS,OAAO,KAAK,IAChCuB,IAAWvB,MAAS,OAAO,YAAY;AAE7C,SACE,gBAAAT,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,EAAA,GACxD,UAAA;AAAA,IAAA,gBAAAC,EAACgC,GAAA,EAAO,OAAML,KAAA,gBAAAA,EAAQ,SAAQ,KAAK,MAAMG,GAAU,KAAKH,KAAA,gBAAAA,EAAQ,OAAA,CAAQ;AAAA,IACxE,gBAAA3B,EAAC,QAAA,EAAK,OAAO,EAAE,UAAA+B,GAAU,OAAOlC,GAAS,YAAY,IAAA,GAAQ,WAAA8B,KAAA,gBAAAA,EAAQ,SAAQ,UAAA,CAAU;AAAA,KACrFE,KAAUD,MACV,gBAAA7B,EAAC,QAAA,EAAK,OAAO,EAAE,UAAAgC,GAAU,OAAOjC,EAAA,GAC7B,UAAA;AAAA,MAAA+B,KAAU,gBAAA9B,EAAAkC,GAAA,EAAG,UAAA;AAAA,QAAAJ;AAAA,QAAO;AAAA,MAAA,GAAC;AAAA,MAAKD,IAAOM,EAAeN,CAAI,IAAI;AAAA,IAAA,EAAA,CAC3D;AAAA,EAAA,GAEJ;AAEJ;AAIO,SAASO,EAAQ,EAAE,OAAAC,GAAO,SAAAX,GAAS,QAAAjC,IAAS,MAAQ;AAIzD,SACE,gBAAAO;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAA0B;AAAA,MACA,OAAO;AAAA,QACL,UAAU;AAAA,QAAU,SAAS;AAAA,QAAW,cAAc;AAAA,QACtD,iBARSjC,IAAS,2BAA2B;AAAA,QAQxB,OANZA,IAAS,YAAY;AAAA,QAMF,QAAQ,aAP3BA,IAAS,0BAA2B,iBAOU;AAAA,QACvD,QAAQiC,IAAU,YAAY;AAAA,QAAW,YAAY;AAAA,QACrD,YAAY;AAAA,MAAA;AAAA,MAEf,UAAA;AAAA,QAAA;AAAA,QACGW;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGR;AAIA,MAAMC,IAAa;AAAA,EACjB,eAAe,EAAE,IAAI,wBAAyB,MAAM,WAAW,QAAQ,uBAAA;AAAA,EACvE,SAAe,EAAE,IAAI,yBAA0B,MAAM,WAAW,QAAQ,wBAAA;AAAA,EACxE,WAAe,EAAE,IAAI,yBAA0B,MAAM,WAAW,QAAQ,wBAAA;AAAA,EACxE,OAAe,EAAE,IAAI,yBAA0B,MAAM,WAAW,QAAQ,wBAAA;AAAA,EACxE,MAAe,EAAE,IAAI,wBAA0B,MAAM,WAAW,QAAQ,sBAAA;AAAA,EACxE,SAAe,EAAE,IAAI,0BAA0B,MAAM,WAAW,QAAQ,wBAAA;AAC1E;AAEO,SAASC,EAAc,EAAE,UAAAC,KAAY;AAC1C,QAAMC,IAAIH,EAAWE,KAAA,gBAAAA,EAAU,EAAE,KAAKF,EAAW;AACjD,SACE,gBAAAtC,EAAC,QAAA,EAAK,OAAO,EAAE,SAAS,eAAe,YAAY,UAAU,KAAK,GAAG,UAAU,UAAU,YAAY,KAAK,SAAS,WAAW,cAAc,MAAM,iBAAiByC,EAAE,IAAI,OAAOA,EAAE,MAAM,QAAQ,aAAaA,EAAE,MAAM,MAClN,UAAA;AAAA,KAAAD,KAAA,gBAAAA,EAAU,SAAQ,gBAAAvC,EAAC,QAAA,EAAM,UAAAuC,EAAS,MAAK;AAAA,IACvCA,KAAA,gBAAAA,EAAU;AAAA,EAAA,GACb;AAEJ;AAIO,SAASP,EAAO,EAAE,MAAAS,GAAM,MAAAjC,IAAO,IAAI,KAAAkC,KAAO;AAC/C,QAAMC,KAAYF,KAAQ,KAAK,MAAM,GAAG,CAAC,EAAE,YAAA,GAErCG,IAAM,OADA,CAAC,GAAIH,KAAQ,EAAG,EAAE,OAAO,CAACI,GAAGL,OAAOK,IAAI,KAAKL,EAAE,WAAW,CAAC,KAAK,KAAK,CAAC,CAC5D;AAEtB,SAAIE,IACK,gBAAA1C,EAAC,OAAA,EAAI,KAAA0C,GAAU,KAAKD,GAAM,OAAO,EAAE,OAAOjC,GAAM,QAAQA,GAAM,cAAc,OAAO,WAAW,WAAW,IAGhH,gBAAAR,EAAC,OAAA,EAAI,OAAO,EAAE,OAAOQ,GAAM,QAAQA,GAAM,cAAc,OAAO,iBAAiBoC,GAAI,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,UAAUpC,IAAO,MAAM,YAAY,KAAK,OAAO,QAAQ,YAAY,GAAG,YAAY,OAAA,GACnO,UAAAmC,GACH;AAEJ;AAIO,SAAST,EAAeN,GAAM;AACnC,QAAMkB,IAAO,OAAOlB,KAAS,WAAW,IAAI,KAAKA,CAAI,IAAIA,GACnDmB,KAAQ,KAAK,IAAA,IAAQD,EAAE,aAAa;AAC1C,SAAIC,IAAO,KAAc,aACrBA,IAAO,OAAc,GAAG,KAAK,MAAMA,IAAO,EAAE,CAAC,UAC7CA,IAAO,QAAc,GAAG,KAAK,MAAMA,IAAO,IAAI,CAAC,UAC/CA,IAAO,SAAe,GAAG,KAAK,MAAMA,IAAO,KAAK,CAAC,UAC9CD,EAAE,mBAAA;AACX;AChJO,SAASE,GAAS,EAAE,MAAAC,GAAM,SAAAxB,GAAS,QAAAyB,GAAQ,QAAA1D,IAAS,IAAM,SAAA2D,IAAU,IAAO,OAAAzD,KAAS;;AACzF,QAAMC,IAAUH,IAAS,uCAA2C,uCAC9DI,IAAUJ,IAAS,2BAA4C,oBAC/DK,IAAUL,IAAS,yCAA2C,yCAC9DM,IAAUN,IAAS,2CAA2C;AAEpE,SACE,gBAAAO;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,SAAA0B;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,QAAQ,KAAK;AAAA,QAAI,SAAS0B,IAAU,cAAc;AAAA,QAC3D,cAAc;AAAA,QACd,iBAAiBxD;AAAA,QAAM,QAAQ,aAAaC,CAAM;AAAA,QAClD,QAAQ6B,IAAU,YAAY;AAAA,QAC9B,YAAY;AAAA,QACZ,GAAG/B;AAAA,MAAA;AAAA,MAEL,cAAc,CAAAS,MAAK;AAAE,QAAIsB,MAAWtB,EAAE,cAAc,MAAM,cAAcX,IAAS,2BAA2B;AAAA,MAAsB;AAAA,MAClI,cAAc,CAAAW,MAAK;AAAE,QAAAA,EAAE,cAAc,MAAM,cAAcP;AAAA,MAAQ;AAAA,MAGjE,UAAA;AAAA,QAAA,gBAAAI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,CAAAG,MAAKA,EAAE,gBAAA;AAAA,YAChB,OAAO,EAAE,YAAY,GAAG,YAAY,EAAA;AAAA,YAEpC,UAAA,gBAAAH;AAAA,cAACI;AAAA,cAAA;AAAA,gBACC,OAAO6C,EAAK;AAAA,gBACZ,UAAUA,EAAK,YAAY;AAAA,gBAC3B,UAAU,CAAA7B,MAAK8B,KAAA,gBAAAA,EAASD,EAAK,IAAI7B;AAAA,gBACjC,UAAQ;AAAA,gBACR,QAAA5B;AAAA,gBACA,MAAK;AAAA,cAAA;AAAA,YAAA;AAAA,UACP;AAAA,QAAA;AAAA,QAIF,gBAAAO,EAAC,OAAA,EAAI,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,QAAQ,eAAe,UAAU,KAAK,KAEjF,UAAA;AAAA,UAAA,gBAAAA,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,UAAU,QAAQ,YAAY,SAAA,GAClE,UAAA;AAAA,YAAAkD,EAAK,8BACH,QAAA,EAAK,OAAO,EAAE,UAAU,UAAU,YAAY,KAAK,SAAS,WAAW,cAAc,MAAM,iBAAiB,yBAAyB,OAAO,WAAW,QAAQ,kCAAA,GAAqC,UAAA,YAAA,CAErM;AAAA,YAEDA,EAAK,YACJ,gBAAAjD,EAAC,QAAA,EAAK,OAAO,EAAE,UAAU,UAAU,YAAY,KAAK,SAAS,WAAW,cAAc,MAAM,iBAAiB,yBAAyB,OAAO,WAAW,QAAQ,kCAAA,GAAqC,UAAA,WAAA,CAErM;AAAA,YAEF,gBAAAA,EAACsC,GAAA,EAAc,UAAUW,EAAK,SAAA,CAAU;AAAA,UAAA,GAC1C;AAAA,4BAGC,MAAA,EAAG,OAAO,EAAE,QAAQ,GAAG,UAAUE,IAAU,cAAc,QAAQ,YAAY,KAAK,OAAOtD,GAAS,YAAY,IAAA,GAC5G,YAAK,OACR;AAAA,UAGC,CAACsD,KAAWF,EAAK,QAChB,gBAAAjD,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,aAAa,OAAOF,GAAS,YAAY,MAAM,SAAS,eAAe,iBAAiB,GAAG,iBAAiB,YAAY,UAAU,SAAA,GAChK,UAAAmD,EAAK,KAAA,CACR;AAAA,YAIDG,IAAAH,EAAK,SAAL,gBAAAG,EAAW,UAAS,KACnB,gBAAApD,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,UAAU,UAC9C,UAAAiD,EAAK,KAAK,IAAI,CAAAI,MAAK,gBAAArD,EAACmC,GAAA,EAAgB,OAAOkB,GAAG,QAAA7D,EAAA,GAAb6D,CAA6B,CAAE,EAAA,CACnE;AAAA,UAIF,gBAAAtD,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,IAAI,UAAU,QAAQ,WAAW,KACzF,UAAA;AAAA,YAAA,gBAAAC,EAAC0B,GAAA,EAAW,QAAQuB,EAAK,QAAQ,MAAMA,EAAK,WAAW,QAAAzD,GAAgB,MAAK,KAAA,CAAK;AAAA,YACjF,gBAAAQ,EAACsD,KAAU,MAAK,MAAK,OAAOL,EAAK,YAAY,OAAM,WAAU,QAAAzD,EAAA,CAAgB;AAAA,YAC7E,gBAAAQ,EAACsD,KAAU,MAAK,MAAK,OAAOL,EAAK,WAAY,OAAM,SAAU,QAAAzD,EAAA,CAAgB;AAAA,UAAA,EAAA,CAC/E;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAS8D,EAAU,EAAE,MAAA/B,GAAM,OAAAgC,GAAO,OAAAnB,GAAO,QAAA5C,KAAU;AAEjD,SACE,gBAAAO,EAAC,QAAA,EAAK,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,GAAG,UAAU,WAAW,OAFvEP,IAAS,YAAY,aAG/B,UAAA;AAAA,IAAA,gBAAAQ,EAAC,UAAK,OAAO,EAAE,UAAU,GAAA,GAAO,UAAAuB,GAAK;AAAA,IACpCgC;AAAA,IAAM;AAAA,IAAEnB;AAAA,EAAA,GACX;AAEJ;AAIO,SAASoB,GAAS,EAAE,OAAAC,IAAQ,CAAA,GAAI,aAAAC,GAAa,QAAAR,GAAQ,WAAAS,IAAY,IAAO,QAAAnE,IAAS,MAAQ;AAC9F,SAAImE,IAEA,gBAAA3D,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAA,GAC1D,UAAA,MAAM,KAAK,EAAE,QAAQ,EAAA,CAAG,EAAE,IAAI,CAAC4D,GAAGC,MACjC,gBAAA7D,EAAC8D,IAAA,EAAqB,QAAAtE,EAAA,GAAHqE,CAAmB,CACvC,EAAA,CACH,IAIAJ,EAAM,WAAW,IACZ,gBAAAzD,EAAC+D,MAAc,QAAAvE,GAAgB,IAItC,gBAAAQ,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAA,GAC1D,UAAAyD,EAAM,IAAI,CAAAR,MACT,gBAAAjD;AAAA,IAACgD;AAAA,IAAA;AAAA,MAEC,MAAAC;AAAA,MACA,SAAS,MAAMS,KAAA,gBAAAA,EAAcT,EAAK;AAAA,MAClC,QAAAC;AAAA,MACA,QAAA1D;AAAA,IAAA;AAAA,IAJKyD,EAAK;AAAA,EAAA,CAMb,GACH;AAEJ;AAEO,SAASc,GAAc,EAAE,QAAAvE,IAAS,IAAM,SAAAwE,IAAU,gBAAgB,KAAAC,GAAK,OAAAC,KAAS;AAGrF,2BACG,OAAA,EAAI,OAAO,EAAE,WAAW,UAAU,SAAS,aAAa,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,KAAK,MAC5H,UAAA;AAAA,IAAA,gBAAAlE,EAAC,KAAA,EAAE,OAAO,EAAE,UAAU,IAAI,QAAQ,EAAA,GAAK,UAAA,KAAA,CAAE;AAAA,IACzC,gBAAAA,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,QAAQ,YAAY,KAAK,OAL9CR,IAAS,YAAY,UAKgC,GAAY,UAAAwE,GAAQ;AAAA,IACrF,gBAAAhE,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,YAAY,OALjCR,IAAS,YAAY,UAKmB,GAAW,UAAA,sCAAA,CAAmC;AAAA,IACjGyE,KACC,gBAAAjE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAASkE;AAAA,QACT,OAAO,EAAE,WAAW,GAAG,SAAS,YAAY,cAAc,+BAA+B,QAAQ,QAAQ,QAAQ,WAAW,iBAAiB,oCAAoC,OAAO,QAAQ,UAAU,YAAY,YAAY,KAAK,YAAY,UAAA;AAAA,QAElP,UAAAD;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GAEJ;AAEJ;AAEA,SAASH,GAAa,EAAE,QAAAtE,KAAU;AAChC,QAAMoD,IAAKpD,IAAS,2BAA2B,oBACzCI,IAASJ,IAAS,2BAA2B,oBAC7C2E,IAAI,CAACC,GAAGvB,IAAI,QAAQ,EAAE,OAAOuB,GAAG,QAAQvB,GAAG,cAAc,GAAG,iBAAiBD,GAAI,WAAW;AAClG,SACE,gBAAA7C,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,IAAI,SAAS,aAAa,cAAc,gCAAgC,iBAAiBP,IAAS,uCAAuC,uCAAuC,QAAQ,aAAaI,CAAM,MAC7O,UAAA;AAAA,IAAA,gBAAAG,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,KAAK,GAAG,YAAY,GAAG,YAAY,KAC/G,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,OAAOmE,EAAE,IAAI,EAAE,GAAG;AAAA,wBACtB,OAAA,EAAI,OAAOA,EAAE,IAAI,EAAE,EAAA,CAAG;AAAA,IAAA,GACzB;AAAA,IACA,gBAAApE,EAAC,OAAA,EAAI,OAAO,EAAE,MAAM,GAAG,SAAS,QAAQ,eAAe,UAAU,KAAK,EAAA,GACpE,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,OAAOmE,EAAE,OAAO,CAAC,GAAG;AAAA,wBACxB,OAAA,EAAI,OAAOA,EAAE,OAAO,EAAE,GAAG;AAAA,wBACzB,OAAA,EAAI,OAAOA,EAAE,OAAO,CAAC,GAAG;AAAA,wBACxB,OAAA,EAAI,OAAOA,EAAE,OAAO,CAAC,EAAA,CAAG;AAAA,IAAA,GAC3B;AAAA,IACA,gBAAAnE,EAAC,WAAO,UAAA,6DAAA,CAA6D;AAAA,EAAA,GACvE;AAEJ;ACpLY,MAACqE,IAAkB;AAAA,EAC7B,EAAE,IAAI,OAAiB,OAAO,aAAkB,MAAM,KAAK,OAAO,IAAG;AAAA,EACrE,EAAE,IAAI,iBAAiB,OAAO,iBAAkB,MAAM,MAAM,OAAO,GAAI,QAAQ,GAAI;AAAA,EACnF,EAAE,IAAI,WAAiB,OAAO,WAAkB,MAAM,MAAM,OAAO,GAAE;AAAA,EACrE,EAAE,IAAI,aAAiB,OAAO,aAAkB,MAAM,KAAK,OAAO,GAAE;AAAA,EACpE,EAAE,IAAI,SAAiB,OAAO,SAAkB,MAAM,MAAM,OAAO,GAAE;AAAA,EACrE,EAAE,IAAI,QAAiB,OAAO,eAAkB,MAAM,MAAM,OAAO,GAAE;AACvE,GAEaC,IAAa;AAAA,EACxB;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,UAAU,QAAQ,KAAI;AAAA,IAChD,UAAU,EAAE,IAAI,iBAAiB,OAAO,iBAAiB,MAAM,KAAI;AAAA,IACnE,MAAM,CAAC,iBAAiB,UAAU,WAAW;AAAA,IAC7C,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,CAAC,EAAE,YAAW;AAAA,IAChE,UAAU;AAAA,IACV,UAAU;AAAA,EACd;AAAA,EACE;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,YAAY,QAAQ,KAAI;AAAA,IAClD,UAAU,EAAE,IAAI,aAAa,OAAO,aAAa,MAAM,IAAG;AAAA,IAC1D,MAAM,CAAC,iBAAiB,YAAY;AAAA,IACpC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,CAAC,EAAE,YAAW;AAAA,IAChE,UAAU;AAAA,EACd;AAAA,EACE;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,gBAAgB,QAAQ,KAAI;AAAA,IACtD,UAAU,EAAE,IAAI,SAAS,OAAO,SAAS,MAAM,KAAI;AAAA,IACnD,MAAM,CAAC,YAAY,UAAU,SAAS;AAAA,IACtC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,EAAE,EAAE,YAAW;AAAA,EACrE;AAAA,EACE;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,WAAW,QAAQ,KAAI;AAAA,IACjD,UAAU,EAAE,IAAI,QAAQ,OAAO,eAAe,MAAM,KAAI;AAAA,IACxD,MAAM,CAAC,UAAU,OAAO,WAAW;AAAA,IACnC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,EAAE,EAAE,YAAW;AAAA,EACrE;AAAA,EACE;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,kBAAkB,QAAQ,KAAI;AAAA,IACxD,UAAU,EAAE,IAAI,WAAW,OAAO,WAAW,MAAM,KAAI;AAAA,IACvD,MAAM,CAAC,aAAa,gBAAgB,gBAAgB;AAAA,IACpD,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,EAAE,EAAE,YAAW;AAAA,EACrE;AAAA,EACE;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,UAAU,QAAQ,KAAI;AAAA,IAChD,UAAU,EAAE,IAAI,WAAW,OAAO,WAAW,MAAM,KAAI;AAAA,IACvD,MAAM,CAAC,OAAO,UAAU,SAAS;AAAA,IACjC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,EAAE,EAAE,YAAW;AAAA,EACrE;AACA,GAEaC,KAAe;AAAA,EAC1B;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,UAAU,QAAQ,KAAI;AAAA,IAChD,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,CAAC,EAAE,YAAW;AAAA,IAChE,YAAY;AAAA,EAChB;AAAA,EACE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,gBAAgB,QAAQ,KAAI;AAAA,IACtD,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,CAAC,EAAE,YAAW;AAAA,EACpE;AAAA,EACE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ,EAAE,IAAI,MAAM,MAAM,kBAAkB,QAAQ,KAAI;AAAA,IACxD,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW,IAAI,KAAK,KAAK,IAAG,IAAK,MAAO,KAAK,KAAK,CAAC,EAAE,YAAW;AAAA,EACpE;AACA,GC7FMC,KAAQ;AAAA,EACZ,EAAE,IAAI,UAAU,OAAO,SAAA;AAAA,EACvB,EAAE,IAAI,OAAU,OAAO,YAAA;AAAA,EACvB,EAAE,IAAI,cAAc,OAAO,aAAA;AAC7B;AAEO,SAASC,GAAU;AAAA,EACxB,YAAApF,IAAiBgF;AAAA,EACjB,OAAAZ,IAAiBa;AAAA,EACjB,gBAAAI,IAAiB;AAAA,EACjB,aAAAC,IAAiB;AAAA,EACjB,QAAAC,IAAiB;AAAA,EACjB,kBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAArB;AAAA,EACA,WAAAsB;AAAA,EACA,QAAA9B;AAAA,EACA,WAAAS,IAAiB;AAAA,EACjB,QAAAnE,IAAiB;AAAA,EACjB,QAAAyF;AAAA,EACA,OAAAxF,IAAiB;AAAA,EACjB,UAAAyF,IAAiB;AAAA,EACjB,OAAAxF;AACF,GAAG;AACD,QAAM,CAACyF,GAAaC,CAAc,IAAMzE,EAASgE,CAAW,GACtD,CAACU,GAAWC,CAAY,IAAU3E,EAASiE,CAAM,GACjD,CAACW,GAAeC,CAAgB,IAAI7E,EAAS+D,CAAc,GAE3D7E,IAAUL,IAAS,yCAA2C,yCAC9DM,IAAUN,IAAS,2CAA2C,2CAC9DI,IAAUJ,IAAS,2BAA4C,oBAC/DiG,IAAUjG,IAAS,2BAA4C;AAErE,WAASkG,EAAaC,GAAG;AACvB,IAAAP,EAAeO,CAAC,GAChBb,KAAA,QAAAA,EAAWa;AAAA,EACb;AAEA,WAASC,EAAWC,GAAG;AACrB,IAAAP,EAAaO,CAAC,GACdd,KAAA,QAAAA,EAAec;AAAA,EACjB;AAEA,WAASC,EAAeC,GAAI;AAC1B,IAAAP,EAAiBO,CAAE,GACnBlB,KAAA,QAAAA,EAAmBkB;AAAA,EACrB;AAGA,QAAMC,IAAYC,EAAQ,MAAM;AAC9B,QAAIC,IAAOzC;AAIX,QAHI8B,MAAkB,UACpBW,IAAOA,EAAK,OAAO,CAAAC,MAAA;;AAAK,eAAA/C,IAAA+C,EAAE,aAAF,gBAAA/C,EAAY,QAAOmC;AAAA,KAAa,IAEtDJ,EAAY,QAAQ;AACtB,YAAMQ,IAAIR,EAAY,YAAA;AACtB,MAAAe,IAAOA,EAAK,OAAO,CAAAC,MAAA;;AAAK,eAAAA,EAAE,MAAM,cAAc,SAASR,CAAC,OAAKvC,IAAA+C,EAAE,SAAF,gBAAA/C,EAAQ,cAAc,SAASuC;AAAA,OAAE;AAAA,IAChG;AACA,WAAIN,MAAc,UAAca,IAAO,CAAC,GAAGA,CAAI,EAAE,KAAK,CAACE,GAAGC,MAAMA,EAAE,QAAQD,EAAE,KAAK,IAC7Ef,MAAc,aAAca,IAAO,CAAC,GAAGA,CAAI,EAAE,KAAK,CAACE,GAAGC,MAAM,IAAI,KAAKA,EAAE,SAAS,IAAI,IAAI,KAAKD,EAAE,SAAS,CAAC,IACzGf,MAAc,iBAAca,IAAOA,EAAK,OAAO,CAAAC,MAAK,CAACA,EAAE,aAAaA,EAAE,cAAc,OAAO,CAAC,IAEzF,CAAC,GAAGD,CAAI,EAAE,KAAK,CAACE,GAAGC,OAAOA,EAAE,WAAW,IAAI,MAAMD,EAAE,WAAW,IAAI,EAAE;AAAA,EAC7E,GAAG,CAAC3C,GAAO8B,GAAeJ,GAAaE,CAAS,CAAC;AAEjD,SACE,gBAAAtF,EAAC,SAAI,OAAO;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IAAQ,eAAe;AAAA,IAAU,KAAK;AAAA,IAC/C,YAAY;AAAA,IACZ,GAAGL;AAAA,EAAA,GAGF,UAAA;AAAA,IAAAuF,KACC,gBAAAlF,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,gBAAgB,iBAAiB,YAAY,YAAY,UAAU,QAAQ,KAAK,MAC7G,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,QAAA,gBAAAC,EAAC,MAAA,EAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,mCAAmC,YAAY,KAAK,OAAOH,EAAA,GAAY,UAAAJ,GAAM;AAAA,QAC9GyF,KAAY,gBAAAlF,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,WAAW,UAAU,YAAY,OAAOF,EAAA,GAAY,UAAAoF,EAAA,CAAS;AAAA,MAAA,GAChG;AAAA,MACA,gBAAAlF;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAASgF;AAAA,UACT,OAAO,EAAE,SAAS,YAAY,cAAc,+BAA+B,QAAQ,QAAQ,QAAQ,WAAW,iBAAiB,oCAAoC,OAAO,QAAQ,UAAU,YAAY,YAAY,KAAK,YAAY,WAAW,SAAS,QAAQ,YAAY,UAAU,KAAK,EAAA;AAAA,UAC7R,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GACF;AAAA,IAIF,gBAAAjF,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,IAAI,YAAY,aAAA,GAElD,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,OAAO,EAAE,OAAO,KAAK,YAAY,GAAG,UAAU,UAAU,KAAK,GAAA,GAChE,UAAA,gBAAAA;AAAA,QAACZ;AAAA,QAAA;AAAA,UACC,YAAAC;AAAA,UACA,QAAQkG;AAAA,UACR,UAAUO;AAAA,UACV,QAAAtG;AAAA,QAAA;AAAA,MAAA,GAEJ;AAAA,MAGA,gBAAAO,EAAC,OAAA,EAAI,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,QAAQ,eAAe,UAAU,KAAK,MAEjF,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,IAAI,UAAU,QAAQ,YAAY,SAAA,GAEpE,UAAA;AAAA,UAAA,gBAAAA,EAAC,SAAI,OAAO,EAAE,UAAU,YAAY,MAAM,eACxC,UAAA;AAAA,YAAA,gBAAAC,EAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAM,IAAI,KAAK,OAAO,WAAW,oBAAoB,OAAOF,GAAS,eAAe,QAAQ,UAAU,GAAA,GAAM,UAAA,MAAE;AAAA,YACnJ,gBAAAE;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAOmF;AAAA,gBACP,UAAU,CAAAhF,MAAKuF,EAAavF,EAAE,OAAO,KAAK;AAAA,gBAC1C,aAAY;AAAA,gBACZ,OAAO,EAAE,OAAO,QAAQ,WAAW,cAAc,SAAS,qBAAqB,cAAc,+BAA+B,iBAAiBsF,GAAS,QAAQ,aAAa7F,CAAM,IAAI,OAAOC,GAAS,UAAU,YAAY,YAAY,WAAW,SAAS,OAAA;AAAA,gBAC3P,SAAS,CAAAM,MAAK;AAAE,kBAAAA,EAAE,OAAO,MAAM,cAAc;AAAA,gBAAoC;AAAA,gBACjF,QAAQ,CAAAA,MAAK;AAAE,kBAAAA,EAAE,OAAO,MAAM,cAAcP;AAAA,gBAAQ;AAAA,cAAA;AAAA,YAAA;AAAA,UACtD,GACF;AAAA,4BAGC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,iBAAiBJ,IAAS,2BAA2B,oBAAoB,SAAS,GAAG,cAAc,iCACvI,UAAAgF,GAAM,IAAI,CAAAqB,MAAK;AACd,kBAAM3F,IAAWmF,MAAcQ,EAAE;AACjC,mBACE,gBAAA7F;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,SAAS,MAAM4F,EAAWC,EAAE,EAAE;AAAA,gBAC9B,OAAO;AAAA,kBACL,SAAS;AAAA,kBAAY,cAAc;AAAA,kBAAG,QAAQ;AAAA,kBAAQ,QAAQ;AAAA,kBAC9D,iBAAiB3F,IAAYV,IAAS,2BAA2B,SAAU;AAAA,kBAC3E,OAAOU,IAAWL,IAAUC;AAAA,kBAC5B,UAAU;AAAA,kBAAa,YAAYI,IAAW,MAAM;AAAA,kBAAK,YAAY;AAAA,kBACrE,YAAY;AAAA,gBAAA;AAAA,gBAGb,UAAA2F,EAAE;AAAA,cAAA;AAAA,cAVEA,EAAE;AAAA,YAAA;AAAA,UAab,CAAC,EAAA,CACH;AAAA,QAAA,GACF;AAAA,QAGC,CAAClC,KACA,gBAAA5D,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,aAAa,OAAOD,EAAA,GAClD,UAAA;AAAA,UAAAkG,EAAU;AAAA,UAAO;AAAA,UAAEA,EAAU,WAAW,IAAI,SAAS;AAAA,UACrDb,IAAc,cAAcA,CAAW,MAAM;AAAA,QAAA,GAChD;AAAA,QAIF,gBAAAnF;AAAA,UAACwD;AAAA,UAAA;AAAA,YACC,OAAOwC;AAAA,YACP,aAAAtC;AAAA,YACA,QAAAR;AAAA,YACA,WAAAS;AAAA,YACA,QAAAnE;AAAA,UAAA;AAAA,QAAA;AAAA,MACF,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AClLO,SAAS8G,GAAW,EAAE,MAAArD,GAAM,QAAAC,GAAQ,QAAA1D,IAAS,MAAQ;;AAC1D,QAAMG,IAAUH,IAAS,uCAA2C,uCAC9DI,IAAUJ,IAAS,2BAA4C,oBAC/DK,IAAUL,IAAS,yCAA2C,yCAC9DM,IAAUN,IAAS,2CAA2C;AAEpE,SACE,gBAAAO,EAAC,OAAA,EAAI,OAAO,EAAE,cAAc,gCAAgC,iBAAiBJ,GAAM,QAAQ,aAAaC,CAAM,IAAI,UAAU,YAE1H,UAAA;AAAA,IAAA,gBAAAG,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,aAAa,cAAc,aAAaH,CAAM,GAAA,GAEnE,UAAA;AAAA,MAAA,gBAAAG,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,UAAU,QAAQ,cAAc,GAAA,GACpE,UAAA;AAAA,QAAAkD,EAAK,YAAY,gBAAAjD,EAACuG,GAAA,EAAY,OAAM,WAAU,UAAA,aAAS;AAAA,QACvDtD,EAAK,YAAY,gBAAAjD,EAACuG,GAAA,EAAY,OAAM,WAAU,UAAA,YAAQ;AAAA,QACtDtD,EAAK,YAAY,gBAAAjD,EAACuG,GAAA,EAAY,OAAM,SAAQ,UAAA,aAAS;AAAA,QACtD,gBAAAvG,EAACsC,GAAA,EAAc,UAAUW,EAAK,SAAA,CAAU;AAAA,MAAA,GAC1C;AAAA,wBAGC,MAAA,EAAG,OAAO,EAAE,QAAQ,YAAY,UAAU,mCAAmC,YAAY,KAAK,OAAOpD,GAAS,YAAY,IAAA,GACxH,YAAK,OACR;AAAA,MAGA,gBAAAE,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,IAAI,UAAU,OAAA,GACtE,UAAA;AAAA,QAAA,gBAAAC,EAAC0B,GAAA,EAAW,QAAQuB,EAAK,QAAQ,MAAMA,EAAK,WAAW,QAAO,UAAS,QAAAzD,EAAA,CAAgB;AAAA,QACvF,gBAAAO,EAAC,UAAK,OAAO,EAAE,UAAU,aAAa,OAAOD,KAAW,UAAA;AAAA,UAAA;AAAA,UAAImD,EAAK,aAAa;AAAA,UAAE;AAAA,QAAA,GAAM;AAAA,QACtF,gBAAAlD,EAAC,UAAK,OAAO,EAAE,UAAU,aAAa,OAAOD,KAAW,UAAA;AAAA,UAAA;AAAA,UAAImD,EAAK,cAAc;AAAA,UAAE;AAAA,QAAA,EAAA,CAAQ;AAAA,MAAA,EAAA,CAC3F;AAAA,IAAA,GACF;AAAA,IAGA,gBAAAlD,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,KAElC,UAAA;AAAA,MAAA,gBAAAC,EAAC,SAAI,OAAO,EAAE,SAAS,aAAa,aAAa,aAAaJ,CAAM,IAAI,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,KAAK,GAAG,YAAY,KAC1J,UAAA,gBAAAI;AAAA,QAACI;AAAA,QAAA;AAAA,UACC,OAAO6C,EAAK;AAAA,UACZ,UAAUA,EAAK,YAAY;AAAA,UAC3B,UAAU,CAAA7B,MAAK8B,KAAA,gBAAAA,EAASD,EAAK,IAAI7B;AAAA,UACjC,UAAQ;AAAA,UACR,QAAA5B;AAAA,QAAA;AAAA,MAAA,GAEJ;AAAA,MAGA,gBAAAO,EAAC,SAAI,OAAO,EAAE,MAAM,GAAG,SAAS,eAC9B,UAAA;AAAA,QAAA,gBAAAC,EAAC,OAAA,EAAI,OAAO,EAAE,UAAU,aAAa,OAAOH,GAAS,YAAY,KAAK,YAAY,YAAY,WAAW,aAAA,GACtG,YAAK,MACR;AAAA,UAGCuD,IAAAH,EAAK,SAAL,gBAAAG,EAAW,UAAS,KACnB,gBAAApD,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,UAAU,QAAQ,WAAW,GAAA,GACjE,UAAAiD,EAAK,KAAK,IAAI,CAAAI,MAAK,gBAAArD,EAACmC,GAAA,EAAgB,OAAOkB,GAAG,QAAA7D,EAAA,GAAb6D,CAA6B,CAAE,EAAA,CACnE;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,SAASkD,EAAY,EAAE,OAAA/E,GAAO,UAAAgF,KAAY;AACxC,QAAMC,IAAS;AAAA,IACb,SAAS,EAAE,IAAI,yBAAyB,MAAM,WAAW,QAAQ,wBAAA;AAAA,IACjE,SAAS,EAAE,IAAI,yBAA0B,MAAM,WAAW,QAAQ,wBAAA;AAAA,IAClE,OAAS,EAAE,IAAI,0BAA0B,MAAM,WAAW,QAAQ,wBAAA;AAAA,EAAwB,GAEtFjE,IAAIiE,EAAOjF,CAAK,KAAKiF,EAAO;AAClC,SACE,gBAAAzG,EAAC,QAAA,EAAK,OAAO,EAAE,UAAU,UAAU,YAAY,KAAK,SAAS,WAAW,cAAc,MAAM,iBAAiBwC,EAAE,IAAI,OAAOA,EAAE,MAAM,QAAQ,aAAaA,EAAE,MAAM,GAAA,GAC5J,UAAAgE,EAAA,CACH;AAEJ;AClEO,SAASE,GAAU,EAAE,OAAAC,GAAO,QAAAzD,GAAQ,UAAA0D,GAAU,WAAAC,IAAY,IAAO,QAAArH,IAAS,MAAQ;AACvF,QAAMG,IAAUH,IAAS,uCAA2C,uCAC9DI,IAAUJ,IAAS,2BAA4C,oBAC/DK,IAAUL,IAAS,yCAA2C,yCAC9DM,IAAUN,IAAS,2CAA2C,2CAE9DsH,IAAiBH,EAAM,aAAa,0BAA0B/G,GAC9DmH,IAAiBJ,EAAM,aACxBnH,IAAS,0BAA0B,0BACpCG;AAEJ,2BACG,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,cAAc,gCAAgC,iBAAiBoH,GAAY,QAAQ,aAAaD,CAAc,IAAI,UAAU,YAEzJ,UAAA;AAAA,IAAA,gBAAA/G,EAAC,SAAI,OAAO,EAAE,SAAS,aAAa,aAAa,aAAaH,CAAM,IAAI,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,KAAK,GAAG,YAAY,KAC1J,UAAA;AAAA,MAAA,gBAAAI;AAAA,QAACI;AAAA,QAAA;AAAA,UACC,OAAOuG,EAAM;AAAA,UACb,UAAUA,EAAM,YAAY;AAAA,UAC5B,UAAU,CAAAvF,MAAK8B,KAAA,gBAAAA,EAASyD,EAAM,IAAIvF;AAAA,UAClC,UAAQ;AAAA,UACR,QAAA5B;AAAA,UACA,MAAK;AAAA,QAAA;AAAA,MAAA;AAAA,OAGLmH,EAAM,cAAcE,MACpB,gBAAA7G;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS,MAAM4G,KAAA,gBAAAA,EAAWD,EAAM;AAAA,UAChC,OAAOA,EAAM,aAAa,oBAAoB;AAAA,UAC9C,OAAO;AAAA,YACL,WAAW;AAAA,YAAG,OAAO;AAAA,YAAI,QAAQ;AAAA,YAAI,cAAc;AAAA,YAAG,QAAQ;AAAA,YAAQ,QAAQE,IAAY,YAAY;AAAA,YACtG,iBAAiBF,EAAM,aAAa,0BAA0B;AAAA,YAC9D,OAAOA,EAAM,aAAa,YAAY7G;AAAA,YACtC,SAAS;AAAA,YAAQ,YAAY;AAAA,YAAU,gBAAgB;AAAA,YAAU,UAAU;AAAA,YAC3E,YAAY;AAAA,UAAA;AAAA,UAEd,cAAc,CAAAK,MAAK;AAAE,YAAI0G,KAAa,CAACF,EAAM,eAAYxG,EAAE,cAAc,MAAM,kBAAkB;AAAA,UAAwB;AAAA,UACzH,cAAc,CAAAA,MAAK;AAAE,YAAKwG,EAAM,eAAYxG,EAAE,cAAc,MAAM,kBAAkB;AAAA,UAAe;AAAA,UACpG,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GAEJ;AAAA,IAGA,gBAAAJ,EAAC,OAAA,EAAI,OAAO,EAAE,MAAM,GAAG,SAAS,aAAa,UAAU,EAAA,GACpD,UAAA;AAAA,MAAA4G,EAAM,cACL,gBAAA5G,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,eAAe,YAAY,UAAU,KAAK,GAAG,UAAU,WAAW,YAAY,KAAK,OAAO,WAAW,cAAc,MACxI,UAAA;AAAA,QAAA,gBAAAC,EAAC,UAAK,UAAA,IAAA,CAAC;AAAA,QAAO;AAAA,MAAA,GAChB;AAAA,wBAGD,OAAA,EAAI,OAAO,EAAE,UAAU,aAAa,OAAOH,GAAS,YAAY,MAAM,YAAY,YAAY,WAAW,aAAA,GACvG,YAAM,MACT;AAAA,MAEA,gBAAAG,EAAC,SAAI,OAAO,EAAE,WAAW,GAAA,GACvB,4BAAC0B,GAAA,EAAW,QAAQiF,EAAM,QAAQ,MAAMA,EAAM,WAAW,QAAO,WAAU,QAAAnH,GAAgB,MAAK,MAAK,EAAA,CACtG;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAeO,SAASwH,GAAY,EAAE,SAAAC,IAAU,CAAA,GAAI,QAAA/D,GAAQ,UAAA0D,GAAU,WAAAC,IAAY,IAAO,aAAAK,GAAa,UAAAC,GAAU,UAAAC,IAAW,IAAO,QAAA5H,IAAS,MAAQ;AACzI,QAAMK,IAAUL,IAAS,YAAY,WAC/BM,IAAUN,IAAS,YAAY,WAC/BI,IAAUJ,IAAS,2BAA2B,oBAG9C6H,IAAS,CAAC,GAAGJ,CAAO,EAAE,KAAK,CAACb,GAAGC,MAC/BD,EAAE,cAAc,CAACC,EAAE,aAAmB,KACtC,CAACD,EAAE,cAAcC,EAAE,aAAmB,IACnCA,EAAE,QAAQD,EAAE,KACpB;AAED,SACE,gBAAArG,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAA,GAE1D,UAAA;AAAA,IAAAkH,EAAQ,SAAS,KAChB,gBAAAjH,EAAC,OAAA,EAAI,OAAO,EAAE,eAAe,IAAI,cAAc,aAAaJ,CAAM,GAAA,GAChE,UAAA,gBAAAG,EAAC,MAAA,EAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,QAAQ,YAAY,KAAK,OAAOF,EAAA,GAC/D,UAAA;AAAA,MAAAoH,EAAQ;AAAA,MAAO;AAAA,MAAEA,EAAQ,WAAW,IAAI,UAAU;AAAA,IAAA,EAAA,CACrD,EAAA,CACF;AAAA,IAIDI,EAAO,SAAS,KACf,gBAAArH,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,MAC1D,UAAAqH,EAAO,IAAI,CAAAV,MACV,gBAAA3G;AAAA,MAAC0G;AAAA,MAAA;AAAA,QAEC,OAAAC;AAAA,QACA,QAAAzD;AAAA,QACA,UAAA0D;AAAA,QACA,WAAAC;AAAA,QACA,QAAArH;AAAA,MAAA;AAAA,MALKmH,EAAM;AAAA,IAAA,CAOd,GACH;AAAA,IAIDS,IACC,gBAAApH,EAAC,OAAA,EAAI,OAAO,EAAE,WAAW,UAAU,SAAS,QAAQ,OAAOF,GAAS,UAAU,YAAY,iBAAiBN,IAAS,2BAA2B,oBAAoB,cAAc,+BAA+B,QAAQ,aAAaI,CAAM,GAAA,GAAM,UAAA,qDAAA,CAEjP,IAEA,gBAAAI;AAAA,MAACsH;AAAA,MAAA;AAAA,QACC,aAAAJ;AAAA,QACA,UAAAC;AAAA,QACA,QAAA3H;AAAA,QACA,aAAayH,EAAQ,WAAW,IAAI,2BAA2B;AAAA,MAAA;AAAA,IAAA;AAAA,EACjE,GAEJ;AAEJ;AAWO,SAASK,GAAc,EAAE,aAAAJ,GAAa,UAAAC,GAAU,aAAAI,IAAc,kBAAkB,QAAA/H,IAAS,MAAQ;AACtG,QAAM,CAACgI,GAAMC,CAAO,IAAU9G,EAAS,EAAE,GACnC,CAAC+G,GAAYC,CAAM,IAAKhH,EAAS,EAAK,GACtC,CAACiH,GAAOC,CAAQ,IAAQlH,EAAS,EAAE,GAEnChB,IAAUH,IAAS,uCAA2C,uCAC9DI,IAAUJ,IAAS,2BAA4C,oBAC/DK,IAAUL,IAAS,YAAY,WAC/BM,IAAUN,IAAS,YAAY,WAC/BiG,IAAUjG,IAAS,2BAA2B;AAEpD,iBAAesI,IAAe;AAC5B,UAAMC,IAAUP,EAAK,KAAA;AACrB,QAAI,CAACO,GAAS;AAAE,MAAAF,EAAS,wBAAwB;AAAG;AAAA,IAAQ;AAC5D,IAAAA,EAAS,EAAE,GACXF,EAAO,EAAI;AACX,QAAI;AACF,aAAMR,KAAA,gBAAAA,EAAWY,KACjBN,EAAQ,EAAE;AAAA,IACZ,UAAA;AACE,MAAAE,EAAO,EAAK;AAAA,IACd;AAAA,EACF;AAEA,SACE,gBAAA5H,EAAC,SAAI,OAAO,EAAE,cAAc,gCAAgC,iBAAiBJ,GAAM,QAAQ,aAAaC,CAAM,IAAI,SAAS,aAAa,SAAS,QAAQ,eAAe,UAAU,KAAK,MAErL,UAAA;AAAA,IAAA,gBAAAG,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,GAAA,GACxD,UAAA;AAAA,MAAA,gBAAAC,EAACgC,GAAA,EAAO,OAAMkF,KAAA,gBAAAA,EAAa,SAAQ,KAAK,MAAM,IAAI,KAAKA,KAAA,gBAAAA,EAAa,OAAA,CAAQ;AAAA,MAC5E,gBAAAlH,EAAC,QAAA,EAAK,OAAO,EAAE,UAAU,aAAa,YAAY,KAAK,OAAOH,EAAA,GAC3D,UAAAqH,IAAcA,EAAY,OAAO,iBAAA,CACpC;AAAA,IAAA,GACF;AAAA,IAGA,gBAAAlH;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAOwH;AAAA,QACP,UAAU,CAAArH,MAAK;AAAE,UAAAsH,EAAQtH,EAAE,OAAO,KAAK,GAAOyH,OAAgB,EAAE;AAAA,QAAG;AAAA,QACnE,aAAAL;AAAA,QACA,MAAM;AAAA,QACN,OAAO;AAAA,UACL,OAAO;AAAA,UAAQ,WAAW;AAAA,UAC1B,SAAS;AAAA,UAAa,cAAc;AAAA,UACpC,iBAAiB9B;AAAA,UAAS,QAAQ,aAAamC,IAAQ,wBAAwBhI,CAAM;AAAA,UACrF,OAAOC;AAAA,UAAS,UAAU;AAAA,UAAa,YAAY;AAAA,UAAK,QAAQ;AAAA,UAChE,YAAY;AAAA,UAAgD,SAAS;AAAA,UACrE,YAAY;AAAA,QAAA;AAAA,QAEd,SAAS,CAAAM,MAAK;AAAE,UAAAA,EAAE,OAAO,MAAM,cAAc;AAAA,QAAoC;AAAA,QACjF,QAAQ,CAAAA,MAAK;AAAE,UAAAA,EAAE,OAAO,MAAM,cAAcyH,IAAQ,wBAAwBhI;AAAA,QAAQ;AAAA,MAAA;AAAA,IAAA;AAAA,IAGrFgI,KAAS,gBAAA5H,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,aAAa,OAAO,UAAA,GAAc,UAAA4H,EAAA,CAAM;AAAA,IAGnF,gBAAA7H,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,gBAAgB,iBAAiB,YAAY,SAAA,GAC1E,UAAA;AAAA,MAAA,gBAAAA,EAAC,UAAK,OAAO,EAAE,UAAU,WAAW,OAAOD,KAAY,UAAA;AAAA,QAAA0H,EAAK;AAAA,QAAO;AAAA,MAAA,GAAO;AAAA,MAC1E,gBAAAzH;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS+H;AAAA,UACT,UAAUJ,KAAc,CAACF,EAAK,KAAA;AAAA,UAC9B,OAAO;AAAA,YACL,SAAS;AAAA,YAAY,cAAc;AAAA,YAA+B,QAAQ;AAAA,YAC1E,QAAQE,KAAc,CAACF,EAAK,KAAA,IAAS,gBAAgB;AAAA,YACrD,iBAAiBE,KAAc,CAACF,EAAK,KAAA,IAAS,yBAAyB;AAAA,YACvE,OAAO;AAAA,YAAQ,UAAU;AAAA,YAAY,YAAY;AAAA,YAAK,YAAY;AAAA,YAClE,YAAY;AAAA,YAAoB,SAAS;AAAA,YAAQ,YAAY;AAAA,YAAU,KAAK;AAAA,UAAA;AAAA,UAG7E,UAAA;AAAA,YAAAE,uBAAeM,IAAA,EAAQ;AAAA,YACvBN,IAAa,aAAa;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAC7B,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,SAASM,KAAU;AACjB,SAAO,gBAAAhI,EAAC,UAAK,OAAO,EAAE,SAAS,gBAAgB,OAAO,IAAI,QAAQ,IAAI,QAAQ,mCAAmC,gBAAgB,QAAQ,cAAc,OAAO,WAAW,kCACvK,UAAA,gBAAAA,EAAC,SAAA,EAAO,UAAA,2DAAA,CAA2D,EAAA,CACrE;AACF;AC3NO,SAASiI,GAAS;AAAA,EACvB,MAAAhF,IAAeqB,EAAW,CAAC;AAAA,EAC3B,SAAA2C,IAAe1C;AAAA,EACf,aAAA2C,IAAe;AAAA,EACf,QAAAgB;AAAA,EACA,YAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAxB;AAAA,EACA,eAAAyB;AAAA,EACA,WAAA1E,IAAe;AAAA,EACf,QAAAnE,IAAe;AAAA,EACf,OAAAE;AACF,GAAG;;AACD,QAAMG,IAAUL,IAAS,yCAA2C,yCAC9DM,IAAUN,IAAS,2CAA2C,2CAG9DqH,IAAYK,OAAe9D,IAAAH,KAAA,gBAAAA,EAAM,WAAN,gBAAAG,EAAc,SAAO8D,KAAA,gBAAAA,EAAa;AAEnE,SAAIvD,IAEA,gBAAA3D,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,8BAA8B,YAAY,gDAAgD,GAAGN,EAAA,GAClH,UAAA,gBAAAM,EAACsI,IAAA,EAAa,QAAA9I,GAAgB,GAChC,IAICyD,IAUH,gBAAAlD,EAAC,SAAI,OAAO;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IAAQ,eAAe;AAAA,IAAU,KAAK;AAAA,IAAI,UAAU;AAAA,IAC7D,YAAY;AAAA,IACZ,GAAGL;AAAA,EAAA,GAGH,UAAA;AAAA,IAAA,gBAAAM;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAASkI;AAAA,QACT,OAAO;AAAA,UACL,WAAW;AAAA,UAAc,SAAS;AAAA,UAAQ,YAAY;AAAA,UAAU,KAAK;AAAA,UACrE,SAAS;AAAA,UAAY,cAAc;AAAA,UAA+B,QAAQ;AAAA,UAC1E,QAAQ;AAAA,UAAW,iBAAiB1I,IAAS,2BAA2B;AAAA,UACxE,OAAOM;AAAA,UAAS,UAAU;AAAA,UAAY,YAAY;AAAA,UAAW,YAAY;AAAA,QAAA;AAAA,QAE3E,cAAc,CAAAK,MAAK;AAAE,UAAAA,EAAE,cAAc,MAAM,kBAAkBX,IAAS,0BAA0B;AAAA,QAAmB;AAAA,QACnH,cAAc,CAAAW,MAAK;AAAE,UAAAA,EAAE,cAAc,MAAM,kBAAkBX,IAAS,2BAA2B;AAAA,QAAoB;AAAA,QACtH,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKD,gBAAAQ;AAAA,MAACsG;AAAA,MAAA;AAAA,QACC,MAAArD;AAAA,QACA,QAAQkF;AAAA,QACR,QAAA3I;AAAA,MAAA;AAAA,IAAA;AAAA,IAIF,gBAAAQ;AAAA,MAACgH;AAAA,MAAA;AAAA,QACC,SAAAC;AAAA,QACA,QAAQmB;AAAA,QACR,UAAAxB;AAAA,QACA,WAAAC;AAAA,QACA,aAAAK;AAAA,QACA,UAAUmB;AAAA,QACV,UAAUpF,EAAK;AAAA,QACf,QAAAzD;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF,IA/CE,gBAAAO,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,8BAA8B,WAAW,UAAU,OAAOD,GAAS,YAAY,gDAAgD,GAAGJ,KACvJ,UAAA;AAAA,IAAA,gBAAAM,EAAC,KAAA,EAAE,OAAO,EAAE,UAAU,IAAI,QAAQ,WAAA,GAAc,UAAA,KAAA,CAAE;AAAA,IAClD,gBAAAA,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,GAAG,YAAY,KAAK,OAAOH,KAAW,UAAA,iBAAA,CAAc;AAAA,EAAA,GAC1E;AA8CN;AAEA,SAASyI,GAAa,EAAE,QAAA9I,KAAU;AAChC,QAAMoD,IAAKpD,IAAS,2BAA2B,oBACzCI,IAASJ,IAAS,2BAA2B,oBAC7CG,IAAOH,IAAS,uCAAuC,uCACvD2E,IAAI,CAACC,GAAGvB,IAAI,QAAQ,EAAE,OAAOuB,GAAG,QAAQvB,GAAG,cAAc,GAAG,iBAAiBD,GAAI,WAAW;AAClG,SACE,gBAAA7C,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAA,GAC3D,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,OAAOmE,EAAE,EAAE,EAAA,CAAG;AAAA,IACnB,gBAAApE,EAAC,SAAI,OAAO,EAAE,cAAc,gCAAgC,iBAAiBJ,GAAM,QAAQ,aAAaC,CAAM,IAAI,SAAS,aAAa,SAAS,QAAQ,eAAe,UAAU,KAAK,MACrL,UAAA;AAAA,MAAA,gBAAAI,EAAC,OAAA,EAAI,OAAOmE,EAAE,OAAO,CAAC,GAAG;AAAA,wBACxB,OAAA,EAAI,OAAOA,EAAE,OAAO,EAAE,GAAG;AAAA,wBACzB,OAAA,EAAI,OAAOA,EAAE,OAAO,EAAE,GAAG;AAAA,MAC1B,gBAAAnE,EAAC,OAAA,EAAI,OAAO,EAAE,QAAQ,IAAI,cAAc,GAAG,iBAAiB4C,IAAG,CAAG;AAAA,IAAA,GACpE;AAAA,IACA,gBAAA5C,EAAC,WAAO,UAAA,6DAAA,CAA6D;AAAA,EAAA,GACvE;AAEJ;ACtGO,SAASuI,GAAe;AAAA,EAC7B,YAAAlJ,IAAegF,EAAgB,OAAO,CAAA7B,MAAKA,EAAE,OAAO,KAAK;AAAA,EACzD,UAAA2E;AAAA,EACA,UAAAqB;AAAA,EACA,aAAAtB,IAAe;AAAA,EACf,QAAA1H,IAAe;AAAA,EACf,OAAAE;AACF,GAAG;AACD,QAAM,CAACD,GAAYgJ,CAAQ,IAAO9H,EAAS,EAAE,GACvC,CAAC6G,GAAYC,CAAO,IAAQ9G,EAAS,EAAE,GACvC,CAAC+H,GAAYC,CAAW,IAAIhI,EAAS,EAAE,GACvC,CAACiI,GAAYC,CAAW,IAAIlI,EAAS,EAAE,GACvC,CAACmI,GAAYC,CAAO,IAAQpI,EAAS,CAAA,CAAE,GACvC,CAAC+G,GAAYC,CAAM,IAAShH,EAAS,EAAK,GAC1C,CAACqI,GAAYC,CAAS,IAAMtI,EAAS,CAAA,CAAE,GAEvChB,IAAUH,IAAS,uCAA2C,uCAC9DI,IAAUJ,IAAS,2BAA4C,oBAC/DK,IAAUL,IAAS,yCAA2C,yCAC9DM,IAAUN,IAAS,2CAA2C,2CAC9DiG,IAAUjG,IAAS,2BAA4C;AAErE,WAAS0J,IAAW;AAClB,UAAM/I,IAAI,CAAA;AACV,WAAKV,EAAM,KAAA,QAAa,QAAW,uBAC/BA,EAAM,SAAS,QAAKU,EAAE,QAAS,wCAC9BqH,EAAK,KAAA,QAAc,OAAW,sBAC9BkB,MAAiBvI,EAAE,WAAW,8BAC5BA;AAAA,EACT;AAEA,iBAAe2H,EAAa3H,GAAG;AAC7B,IAAAA,EAAE,eAAA;AACF,UAAMgJ,IAAOD,EAAA;AACb,QAAI,OAAO,KAAKC,CAAI,EAAE,QAAQ;AAAE,MAAAF,EAAUE,CAAI;AAAG;AAAA,IAAQ;AACzD,IAAAF,EAAU,CAAA,CAAE,GACZtB,EAAO,EAAI;AACX,QAAI;AACF,aAAMR,KAAA,gBAAAA,EAAW,EAAE,OAAO1H,EAAM,KAAA,GAAQ,MAAM+H,EAAK,KAAA,GAAQ,YAAAkB,GAAY,MAAAI,EAAA;AAAA,IACzE,UAAA;AACE,MAAAnB,EAAO,EAAK;AAAA,IACd;AAAA,EACF;AAEA,WAASyB,EAAiBjJ,GAAG;AAC3B,SAAKA,EAAE,QAAQ,WAAWA,EAAE,QAAQ,QAAQyI,EAAS,QAAQ;AAC3D,MAAAzI,EAAE,eAAA;AACF,YAAMkJ,IAAST,EAAS,KAAA,EAAO,cAAc,QAAQ,eAAe,GAAG;AACvE,MAAI,CAACE,EAAK,SAASO,CAAM,KAAKP,EAAK,SAAS,KAC1CC,EAAQ,CAAAO,MAAQ,CAAC,GAAGA,GAAMD,CAAM,CAAC,GAEnCR,EAAY,EAAE;AAAA,IAChB;AACA,IAAI1I,EAAE,QAAQ,eAAe,CAACyI,KAAYE,EAAK,UAC7CC,EAAQ,CAAAO,MAAQA,EAAK,MAAM,GAAG,EAAE,CAAC;AAAA,EAErC;AAEA,QAAMC,IAAa,CAACC,OAAc;AAAA,IAChC,OAAO;AAAA,IAAQ,WAAW;AAAA,IAAc,SAAS;AAAA,IACjD,cAAc;AAAA,IACd,iBAAiB/D;AAAA,IAAS,QAAQ,aAAa+D,IAAW,wBAAwB5J,CAAM;AAAA,IACxF,OAAOC;AAAA,IAAS,UAAU;AAAA,IAAa,YAAY;AAAA,IACnD,SAAS;AAAA,IAAQ,YAAY;AAAA,EAAA;AAG/B,SACE,gBAAAE,EAAC,SAAI,OAAO;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IAAQ,eAAe;AAAA,IAAU,KAAK;AAAA,IAC/C,UAAU;AAAA,IAAK,YAAY;AAAA,IAC3B,GAAGL;AAAA,EAAA,GAGH,UAAA;AAAA,IAAA,gBAAAK,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,gBAAgB,iBAAiB,YAAY,UAAU,UAAU,QAAQ,KAAK,MAC3G,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EACC,UAAA;AAAA,QAAA,gBAAAC,EAAC,MAAA,EAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,mCAAmC,YAAY,KAAK,OAAOH,EAAA,GAAW,UAAA,YAAQ;AAAA,QAChH,gBAAAG,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,WAAW,UAAU,YAAY,OAAOF,KAAW,UAAA,4DAAA,CAAyD;AAAA,MAAA,GAClI;AAAA,MACC0I,KACC,gBAAAxI;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAASwI;AAAA,UACT,OAAO,EAAE,SAAS,YAAY,cAAc,+BAA+B,QAAQ,aAAa5I,CAAM,IAAI,QAAQ,WAAW,iBAAiB,eAAe,OAAOE,GAAS,UAAU,YAAY,YAAY,UAAA;AAAA,UAChN,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GAEJ;AAAA,IAGA,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,UAAU+H;AAAA,QACV,OAAO,EAAE,cAAc,gCAAgC,iBAAiBnI,GAAM,QAAQ,aAAaC,CAAM,IAAI,SAAS,QAAQ,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAA;AAAA,QAG5K,UAAA;AAAA,UAAAsH,KACC,gBAAAnH,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,GAAG,SAAS,YAAY,cAAc,+BAA+B,iBAAiBP,IAAS,2BAA2B,oBAAoB,QAAQ,aAAaI,CAAM,GAAA,GACjO,UAAA;AAAA,YAAA,gBAAAI,EAACgC,GAAA,EAAO,MAAMkF,EAAY,MAAM,MAAM,IAAI,KAAKA,EAAY,OAAA,CAAQ;AAAA,YACnE,gBAAAnH,EAAC,UAAK,OAAO,EAAE,UAAU,YAAY,OAAOF,KAAW,UAAA;AAAA,cAAA;AAAA,cAAW,gBAAAG,EAAC,UAAA,EAAQ,UAAAkH,EAAY,KAAA,CAAK;AAAA,YAAA,EAAA,CAAS;AAAA,UAAA,GACvG;AAAA,UAIF,gBAAAnH,EAAC0J,KAAM,OAAM,SAAQ,OAAOT,EAAO,OAAO,UAAQ,IAChD,UAAA;AAAA,YAAA,gBAAAhJ;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAOP;AAAA,gBACP,UAAU,CAAAU,MAAK;AAAE,kBAAAsI,EAAStI,EAAE,OAAO,KAAK,GAAO6I,EAAO,SAAOC,EAAU,CAAA9C,OAAM,EAAE,GAAGA,GAAG,OAAO,GAAA,EAAK;AAAA,gBAAG;AAAA,gBACpG,aAAY;AAAA,gBACZ,OAAOoD,EAAWP,EAAO,KAAK;AAAA,gBAC9B,SAAS,CAAA7I,MAAK;AAAE,kBAAAA,EAAE,OAAO,MAAM,cAAc;AAAA,gBAAoC;AAAA,gBACjF,QAAQ,CAAAA,MAAK;AAAE,kBAAAA,EAAE,OAAO,MAAM,cAAc6I,EAAO,QAAQ,wBAAwBpJ;AAAA,gBAAQ;AAAA,cAAA;AAAA,YAAA;AAAA,YAE7F,gBAAAI,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,gBAAgB,YAAY,WAAW,EAAA,GACpE,4BAAC,QAAA,EAAK,OAAO,EAAE,UAAU,WAAW,OAAOP,EAAM,SAAS,MAAM,YAAYK,EAAA,GAAY,UAAA;AAAA,cAAAL,EAAM;AAAA,cAAO;AAAA,YAAA,EAAA,CAAI,EAAA,CAC3G;AAAA,UAAA,GACF;AAAA,UAGA,gBAAAO,EAACyJ,KAAM,OAAM,YAAW,OAAOT,EAAO,UAAU,UAAQ,IACtD,UAAA,gBAAAhJ,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,UAAU,OAAA,GAC9C,UAAAX,EAAW,IAAI,CAAAY,MAAO;AACrB,kBAAMyJ,IAAahB,MAAezI,EAAI;AACtC,mBACE,gBAAAF;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,SAAS,MAAM;AAAE,kBAAA4I,EAAY1I,EAAI,EAAE,GAAO+I,EAAO,YAAUC,EAAU,CAAA9C,OAAM,EAAE,GAAGA,GAAG,UAAU,GAAA,EAAK;AAAA,gBAAG;AAAA,gBACrG,OAAO;AAAA,kBACL,SAAS;AAAA,kBAAQ,YAAY;AAAA,kBAAU,KAAK;AAAA,kBAAG,SAAS;AAAA,kBACxD,cAAc;AAAA,kBAA+B,QAAQ,aAAauD,IAAa,qCAAqC9J,CAAM;AAAA,kBAC1H,QAAQ;AAAA,kBAAW,YAAY;AAAA,kBAAW,UAAU;AAAA,kBACpD,iBAAiB8J,IAAa,yBAAyBjE;AAAA,kBACvD,OAAOiE,IAAa,qCAAqC7J;AAAA,kBACzD,YAAY;AAAA,kBAAa,YAAY6J,IAAa,MAAM;AAAA,gBAAA;AAAA,gBAGzD,UAAA;AAAA,kBAAAzJ,EAAI,QAAQ,gBAAAD,EAAC,QAAA,EAAM,UAAAC,EAAI,MAAK;AAAA,kBAC5BA,EAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,cAbAA,EAAI;AAAA,YAAA;AAAA,UAgBf,CAAC,GACH,GACF;AAAA,UAGA,gBAAAD,EAACyJ,KAAM,OAAM,QAAO,OAAOT,EAAO,MAAM,UAAQ,IAC9C,UAAA,gBAAAhJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAOwH;AAAA,cACP,UAAU,CAAArH,MAAK;AAAE,gBAAAsH,EAAQtH,EAAE,OAAO,KAAK,GAAO6I,EAAO,QAAMC,EAAU,CAAA9C,OAAM,EAAE,GAAGA,GAAG,MAAM,GAAA,EAAK;AAAA,cAAG;AAAA,cACjG,aAAY;AAAA,cACZ,MAAM;AAAA,cACN,OAAO,EAAE,GAAGoD,EAAWP,EAAO,IAAI,GAAG,QAAQ,YAAY,YAAY,KAAA;AAAA,cACrE,SAAS,CAAA7I,MAAK;AAAE,gBAAAA,EAAE,OAAO,MAAM,cAAc;AAAA,cAAoC;AAAA,cACjF,QAAQ,CAAAA,MAAK;AAAE,gBAAAA,EAAE,OAAO,MAAM,cAAc6I,EAAO,OAAO,wBAAwBpJ;AAAA,cAAQ;AAAA,YAAA;AAAA,UAAA,GAE9F;AAAA,UAGA,gBAAAI,EAACyJ,GAAA,EAAM,OAAM,QAAO,MAAK,8CACvB,UAAA,gBAAA1J,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,UAAU,QAAQ,SAAS,YAAY,cAAc,+BAA+B,iBAAiB0F,GAAS,QAAQ,aAAa7F,CAAM,IAAI,WAAW,IAAI,YAAY,YAC5M,UAAA;AAAA,YAAAkJ,EAAK,IAAI,CAAAzF,MACR,gBAAAtD,EAAC,QAAA,EAAa,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,GAAG,UAAU,WAAW,SAAS,WAAW,cAAc,MAAM,iBAAiBP,IAAS,yBAAyB,yBAAyB,OAAO,WAAW,QAAQ,iCAAA,GAAoC,UAAA;AAAA,cAAA;AAAA,cACzQ6D;AAAA,gCACD,UAAA,EAAO,MAAK,UAAS,SAAS,MAAM0F,EAAQ,CAAAO,MAAQA,EAAK,OAAO,OAAKK,MAAMtG,CAAC,CAAC,GAAG,OAAO,EAAE,YAAY,QAAQ,QAAQ,QAAQ,QAAQ,WAAW,OAAO,WAAW,SAAS,GAAG,UAAU,IAAI,YAAY,GAAG,SAAS,QAAQ,YAAY,SAAA,GAAY,UAAA,IAAA,CAAC;AAAA,YAAA,EAAA,GAF7OA,CAGX,CACD;AAAA,YACAyF,EAAK,SAAS,KACb,gBAAA9I;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAO4I;AAAA,gBACP,UAAU,CAAAzI,MAAK0I,EAAY1I,EAAE,OAAO,KAAK;AAAA,gBACzC,WAAWiJ;AAAA,gBACX,aAAaN,EAAK,WAAW,IAAI,gCAAgC;AAAA,gBACjE,OAAO,EAAE,QAAQ,QAAQ,SAAS,QAAQ,iBAAiB,eAAe,OAAOjJ,GAAS,UAAU,YAAY,YAAY,WAAW,MAAM,GAAG,UAAU,IAAA;AAAA,cAAI;AAAA,YAAA;AAAA,UAChK,EAAA,CAEJ,EAAA,CACF;AAAA,4BAGC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,gBAAgB,YAAY,KAAK,IAAI,YAAY,GAAG,WAAW,aAAaD,CAAM,IAAI,WAAW,KAC7H,UAAA;AAAA,YAAA4I,KACC,gBAAAxI,EAAC,UAAA,EAAO,MAAK,UAAS,SAASwI,GAAU,OAAO,EAAE,SAAS,YAAY,cAAc,+BAA+B,QAAQ,aAAa5I,CAAM,IAAI,QAAQ,WAAW,iBAAiB,eAAe,OAAOE,GAAS,UAAU,YAAY,YAAY,UAAA,GAAa,UAAA,SAAA,CAErQ;AAAA,YAEF,gBAAAC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,UAAU2H;AAAA,gBACV,OAAO,EAAE,SAAS,YAAY,cAAc,+BAA+B,QAAQ,QAAQ,QAAQA,IAAa,SAAS,WAAW,iBAAiBA,IAAa,yBAAyB,oCAAoC,OAAO,QAAQ,UAAU,YAAY,YAAY,KAAK,YAAY,WAAW,SAAS,QAAQ,YAAY,UAAU,KAAK,EAAA;AAAA,gBAEvV,UAAA;AAAA,kBAAAA,uBAAeM,IAAA,EAAQ;AAAA,kBACvBN,IAAa,gBAAgB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UAChC,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEA,SAAS+B,EAAM,EAAE,OAAArH,GAAO,UAAAoE,GAAU,OAAAoB,GAAO,MAAAgC,GAAM,UAAAC,KAAY;AACzD,SACE,gBAAA9J,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,EAAA,GAC3D,UAAA;AAAA,IAAA,gBAAAA,EAAC,SAAA,EAAM,OAAO,EAAE,UAAU,YAAY,YAAY,KAAK,OAAO,wCAAwC,SAAS,QAAQ,KAAK,KACzH,UAAA;AAAA,MAAAqC;AAAA,MACAyH,uBAAa,QAAA,EAAK,OAAO,EAAE,OAAO,UAAA,GAAa,UAAA,IAAA,CAAC;AAAA,IAAA,GACnD;AAAA,IACCrD;AAAA,IACAoD,KAAQ,CAAChC,KAAS,gBAAA5H,EAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,WAAW,OAAO,yCAAA,GAA6C,UAAA4J,GAAK;AAAA,IACvHhC,KAAS,gBAAA5H,EAAC,KAAA,EAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,aAAa,OAAO,UAAA,GAAc,UAAA4H,EAAA,CAAM;AAAA,EAAA,GACrF;AAEJ;AAEA,SAASI,KAAU;AACjB,SAAO,gBAAAhI,EAAC,UAAK,OAAO,EAAE,SAAS,gBAAgB,OAAO,IAAI,QAAQ,IAAI,QAAQ,mCAAmC,gBAAgB,QAAQ,cAAc,OAAO,WAAW,kCACvK,UAAA,gBAAAA,EAAC,SAAA,EAAO,UAAA,2DAAA,CAA2D,EAAA,CACrE;AACF;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(u,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],e):(u=typeof globalThis<"u"?globalThis:u||self,e(u.MounajiForum={},u.jsxRuntime,u.React))})(this,(function(u,e,S){"use strict";function Y({categories:r=[],active:n="all",onChange:t,isDark:o=!0,title:a="Categories",style:l}){const i=o?"var(--mn-color-card-dark, #0B0F23)":"var(--mn-color-card-light, #FAFAF8)",p=o?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",g=o?"var(--mn-text-primary-dark, #F0F4FF)":"var(--mn-text-primary-light, #1A1A2E)",b=o?"var(--mn-text-secondary-dark, #94A3B8)":"var(--mn-text-secondary-light, #64748B)";return e.jsxs("div",{style:{borderRadius:"var(--mn-radius-lg, 0.75rem)",backgroundColor:i,border:`1px solid ${p}`,overflow:"hidden",...l},children:[a&&e.jsx("div",{style:{padding:"12px 16px",borderBottom:`1px solid ${p}`},children:e.jsx("p",{style:{margin:0,fontSize:"0.75rem",fontWeight:600,color:b,textTransform:"uppercase",letterSpacing:"0.07em"},children:a})}),e.jsx("div",{style:{padding:"8px 0"},children:r.map(y=>{const d=n===y.id;return e.jsxs("button",{onClick:()=>t==null?void 0:t(y.id),style:{width:"100%",display:"flex",alignItems:"center",justifyContent:"space-between",padding:"7px 16px",border:"none",cursor:"pointer",fontFamily:"inherit",backgroundColor:d?o?"rgba(59,130,246,0.1)":"rgba(59,130,246,0.07)":"transparent",borderLeft:`3px solid ${d?"var(--mn-color-primary, #3B82F6)":"transparent"}`,transition:"all 100ms",gap:8},onMouseEnter:f=>{d||(f.currentTarget.style.backgroundColor=o?"rgba(255,255,255,0.04)":"rgba(0,0,0,0.03)")},onMouseLeave:f=>{d||(f.currentTarget.style.backgroundColor="transparent")},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,minWidth:0},children:[y.icon&&e.jsx("span",{style:{fontSize:14,flexShrink:0},children:y.icon}),e.jsx("span",{style:{fontSize:"0.875rem",fontWeight:d?600:400,color:d?"var(--mn-color-primary, #3B82F6)":g,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:y.label})]}),y.count!=null&&e.jsx("span",{style:{fontSize:"0.7rem",fontWeight:500,padding:"1px 7px",borderRadius:9999,backgroundColor:d?"rgba(59,130,246,0.15)":o?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",color:d?"var(--mn-color-primary, #3B82F6)":b,flexShrink:0},children:y.count})]},y.id)})})]})}function W({count:r=0,userVote:n=0,onChange:t,vertical:o=!1,isDark:a=!0,size:l="md"}){const[i,p]=S.useState(null),g=i??n,b=i!==null?r+(i-n):r,y=g===1?"#10B981":a?"#64748B":"#94A3B8",d=g===-1?"#EF4444":a?"#64748B":"#94A3B8",f=g===1?"#10B981":g===-1?"#EF4444":a?"#F0F4FF":"#1A1A2E",F=l==="sm"?22:28,x=l==="sm"?11:13;function w(B){const C=g===B?0:B;p(C),t==null||t(C)}const m=o?{display:"flex",flexDirection:"column",alignItems:"center",gap:2}:{display:"flex",alignItems:"center",gap:4};return e.jsxs("div",{style:m,children:[e.jsx(K,{size:F,icon:"▲",color:y,iconSz:x,onClick:()=>w(1),title:"Upvote"}),e.jsx("span",{style:{fontSize:l==="sm"?"0.75rem":"0.875rem",fontWeight:700,color:f,minWidth:20,textAlign:"center"},children:b}),o&&e.jsx(K,{size:F,icon:"▼",color:d,iconSz:x,onClick:()=>w(-1),title:"Downvote"})]})}function K({size:r,icon:n,color:t,iconSz:o,onClick:a,title:l}){return e.jsx("button",{onClick:a,title:l,style:{width:r,height:r,borderRadius:4,border:"none",cursor:"pointer",backgroundColor:"transparent",color:t,fontSize:o,display:"flex",alignItems:"center",justifyContent:"center",transition:"background 100ms, color 100ms",padding:0,fontFamily:"inherit"},onMouseEnter:i=>{i.currentTarget.style.backgroundColor="rgba(255,255,255,0.07)"},onMouseLeave:i=>{i.currentTarget.style.backgroundColor="transparent"},children:n})}function E({author:r,date:n,prefix:t="",isDark:o=!0,size:a="md"}){const l=o?"#94A3B8":"#64748B",i=o?"#F0F4FF":"#1A1A2E",p=a==="sm"?18:22,g=a==="sm"?"0.75rem":"0.8125rem";return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx(q,{name:(r==null?void 0:r.name)??"?",size:p,src:r==null?void 0:r.avatar}),e.jsx("span",{style:{fontSize:g,color:i,fontWeight:500},children:(r==null?void 0:r.name)??"unknown"}),(t||n)&&e.jsxs("span",{style:{fontSize:g,color:l},children:[t&&e.jsxs(e.Fragment,{children:[t," "]}),n?ae(n):""]})]})}function M({label:r,onClick:n,isDark:t=!0}){const o=t?"rgba(255,255,255,0.05)":"rgba(0,0,0,0.05)",a=t?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.1)",l=t?"#94A3B8":"#64748B";return e.jsxs("span",{onClick:n,style:{fontSize:"0.7rem",padding:"2px 8px",borderRadius:9999,backgroundColor:o,color:l,border:`1px solid ${a}`,cursor:n?"pointer":"default",fontFamily:"inherit",transition:"background 100ms"},children:["#",r]})}const J={announcements:{bg:"rgba(239,68,68,0.12)",text:"#F87171",border:"rgba(239,68,68,0.25)"},general:{bg:"rgba(59,130,246,0.12)",text:"#60A5FA",border:"rgba(59,130,246,0.25)"},questions:{bg:"rgba(245,158,11,0.12)",text:"#FCD34D",border:"rgba(245,158,11,0.25)"},ideas:{bg:"rgba(139,92,246,0.12)",text:"#A78BFA",border:"rgba(139,92,246,0.25)"},bugs:{bg:"rgba(239,68,68,0.12)",text:"#FCA5A5",border:"rgba(239,68,68,0.2)"},default:{bg:"rgba(255,255,255,0.06)",text:"#94A3B8",border:"rgba(255,255,255,0.1)"}};function j({category:r}){const n=J[r==null?void 0:r.id]??J.default;return e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4,fontSize:"0.7rem",fontWeight:500,padding:"2px 8px",borderRadius:9999,backgroundColor:n.bg,color:n.text,border:`1px solid ${n.border}`},children:[(r==null?void 0:r.icon)&&e.jsx("span",{children:r.icon}),r==null?void 0:r.label]})}function q({name:r,size:n=24,src:t}){const o=(r??"?").slice(0,1).toUpperCase(),l=`hsl(${[...r??""].reduce((i,p)=>(i*31+p.charCodeAt(0))%360,0)}, 55%, 35%)`;return t?e.jsx("img",{src:t,alt:r,style:{width:n,height:n,borderRadius:"50%",objectFit:"cover"}}):e.jsx("div",{style:{width:n,height:n,borderRadius:"50%",backgroundColor:l,display:"flex",alignItems:"center",justifyContent:"center",fontSize:n*.45,fontWeight:700,color:"#fff",flexShrink:0,userSelect:"none"},children:o})}function ae(r){const n=typeof r=="string"?new Date(r):r,t=(Date.now()-n.getTime())/1e3;return t<60?"just now":t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:t<604800?`${Math.floor(t/86400)}d ago`:n.toLocaleDateString()}function X({post:r,onClick:n,onVote:t,isDark:o=!0,compact:a=!1,style:l}){var y;const i=o?"var(--mn-color-card-dark, #0B0F23)":"var(--mn-color-card-light, #FAFAF8)",p=o?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",g=o?"var(--mn-text-primary-dark, #F0F4FF)":"var(--mn-text-primary-light, #1A1A2E)",b=o?"var(--mn-text-secondary-dark, #94A3B8)":"var(--mn-text-secondary-light, #64748B)";return e.jsxs("div",{onClick:n,style:{display:"flex",gap:14,padding:a?"12px 16px":"16px 18px",borderRadius:"var(--mn-radius-lg, 0.75rem)",backgroundColor:i,border:`1px solid ${p}`,cursor:n?"pointer":"default",transition:"border-color 120ms, background 120ms",...l},onMouseEnter:d=>{n&&(d.currentTarget.style.borderColor=o?"rgba(255,255,255,0.14)":"rgba(0,0,0,0.16)")},onMouseLeave:d=>{d.currentTarget.style.borderColor=p},children:[e.jsx("div",{onClick:d=>d.stopPropagation(),style:{flexShrink:0,paddingTop:2},children:e.jsx(W,{count:r.votes,userVote:r.userVote??0,onChange:d=>t==null?void 0:t(r.id,d),vertical:!0,isDark:o,size:"sm"})}),e.jsxs("div",{style:{flex:1,minWidth:0,display:"flex",flexDirection:"column",gap:6},children:[e.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap",alignItems:"center"},children:[r.isPinned&&e.jsx("span",{style:{fontSize:"0.7rem",fontWeight:600,padding:"2px 7px",borderRadius:9999,backgroundColor:"rgba(245,158,11,0.12)",color:"#FCD34D",border:"1px solid rgba(245,158,11,0.25)"},children:"📌 Pinned"}),r.isSolved&&e.jsx("span",{style:{fontSize:"0.7rem",fontWeight:600,padding:"2px 7px",borderRadius:9999,backgroundColor:"rgba(16,185,129,0.12)",color:"#34D399",border:"1px solid rgba(16,185,129,0.25)"},children:"✓ Solved"}),e.jsx(j,{category:r.category})]}),e.jsx("h3",{style:{margin:0,fontSize:a?"0.9375rem":"1rem",fontWeight:600,color:g,lineHeight:1.4},children:r.title}),!a&&r.body&&e.jsx("p",{style:{margin:0,fontSize:"0.8125rem",color:b,lineHeight:1.55,display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden"},children:r.body}),((y=r.tags)==null?void 0:y.length)>0&&e.jsx("div",{style:{display:"flex",gap:5,flexWrap:"wrap"},children:r.tags.map(d=>e.jsx(M,{label:d,isDark:o},d))}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,flexWrap:"wrap",marginTop:2},children:[e.jsx(E,{author:r.author,date:r.createdAt,isDark:o,size:"sm"}),e.jsx(Z,{icon:"💬",value:r.replyCount,label:"replies",isDark:o}),e.jsx(Z,{icon:"👁",value:r.viewCount,label:"views",isDark:o})]})]})]})}function Z({icon:r,value:n,label:t,isDark:o}){const a=o?"#64748B":"#94A3B8";return e.jsxs("span",{style:{display:"flex",alignItems:"center",gap:4,fontSize:"0.75rem",color:a},children:[e.jsx("span",{style:{fontSize:12},children:r}),n," ",t]})}function D({posts:r=[],onPostClick:n,onVote:t,isLoading:o=!1,isDark:a=!0}){return o?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:Array.from({length:4}).map((l,i)=>e.jsx(ie,{isDark:a},i))}):r.length===0?e.jsx(U,{isDark:a}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:r.map(l=>e.jsx(X,{post:l,onClick:()=>n==null?void 0:n(l.id),onVote:t,isDark:a},l.id))})}function U({isDark:r=!0,message:n="No posts yet",cta:t,onCta:o}){const a=r?"#F0F4FF":"#1A1A2E",l=r?"#94A3B8":"#64748B";return e.jsxs("div",{style:{textAlign:"center",padding:"64px 24px",display:"flex",flexDirection:"column",alignItems:"center",gap:12},children:[e.jsx("p",{style:{fontSize:40,margin:0},children:"💬"}),e.jsx("p",{style:{margin:0,fontSize:"1rem",fontWeight:600,color:a},children:n}),e.jsx("p",{style:{margin:0,fontSize:"0.875rem",color:l},children:"Be the first to start a discussion."}),t&&e.jsx("button",{onClick:o,style:{marginTop:8,padding:"8px 20px",borderRadius:"var(--mn-radius-md, 0.5rem)",border:"none",cursor:"pointer",backgroundColor:"var(--mn-color-primary, #3B82F6)",color:"#fff",fontSize:"0.875rem",fontWeight:600,fontFamily:"inherit"},children:t})]})}function ie({isDark:r}){const n=r?"rgba(255,255,255,0.05)":"rgba(0,0,0,0.05)",t=r?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",o=(a,l=12)=>({width:a,height:l,borderRadius:6,backgroundColor:n,animation:"mn-pulse 1.4s ease infinite"});return e.jsxs("div",{style:{display:"flex",gap:14,padding:"16px 18px",borderRadius:"var(--mn-radius-lg, 0.75rem)",backgroundColor:r?"var(--mn-color-card-dark, #0B0F23)":"var(--mn-color-card-light, #FAFAF8)",border:`1px solid ${t}`},children:[e.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:6,paddingTop:2,flexShrink:0},children:[e.jsx("div",{style:o(22,10)}),e.jsx("div",{style:o(22,10)})]}),e.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",gap:9},children:[e.jsx("div",{style:o("60%",8)}),e.jsx("div",{style:o("85%",14)}),e.jsx("div",{style:o("50%",8)}),e.jsx("div",{style:o("40%",8)})]}),e.jsx("style",{children:"@keyframes mn-pulse { 0%,100%{opacity:.5} 50%{opacity:1} }"})]})}const _=[{id:"all",label:"All Posts",icon:"◉",count:124},{id:"announcements",label:"Announcements",icon:"📣",count:8,pinned:!0},{id:"general",label:"General",icon:"💬",count:32},{id:"questions",label:"Questions",icon:"❓",count:45},{id:"ideas",label:"Ideas",icon:"💡",count:27},{id:"bugs",label:"Bug Reports",icon:"🐛",count:12}],H=[{id:"1",title:"Introducing the new dark mode token system",body:"We have completely overhauled the design token system to support seamless dark/light mode switching. The new system uses CSS custom properties under a `data-mn-theme` attribute, which means zero-JavaScript theme switching in most cases.",author:{id:"u1",name:"alex_m",avatar:null},category:{id:"announcements",label:"Announcements",icon:"📣"},tags:["design-system","tokens","dark-mode"],votes:87,userVote:0,replyCount:14,viewCount:420,createdAt:new Date(Date.now()-1e3*60*60*3).toISOString(),isPinned:!0,isSolved:!1},{id:"2",title:"How do I add custom categories to my forum?",body:"I am setting up a community forum and want to add my own categories beyond the defaults. Is there a config option for this, or do I need to pass a custom categories array?",author:{id:"u2",name:"sara_dev",avatar:null},category:{id:"questions",label:"Questions",icon:"❓"},tags:["configuration","categories"],votes:12,userVote:0,replyCount:5,viewCount:98,createdAt:new Date(Date.now()-1e3*60*60*6).toISOString(),isSolved:!0},{id:"3",title:"Feature request: markdown support in replies",body:"It would be great to have rich text / markdown support in the reply composer. Being able to add code blocks, links, and bold/italic text would make the forum much more useful for technical discussions.",author:{id:"u3",name:"techwriter_k",avatar:null},category:{id:"ideas",label:"Ideas",icon:"💡"},tags:["markdown","editor","replies"],votes:34,userVote:1,replyCount:9,viewCount:203,createdAt:new Date(Date.now()-1e3*60*60*12).toISOString()},{id:"4",title:"Vote count not updating in real-time",body:"After clicking the upvote button, the vote count updates locally but does not sync back from the server on page refresh. Seems like the onVote callback is firing but the optimistic update is not being persisted.",author:{id:"u4",name:"james_d",avatar:null},category:{id:"bugs",label:"Bug Reports",icon:"🐛"},tags:["voting","bug","real-time"],votes:7,userVote:0,replyCount:3,viewCount:61,createdAt:new Date(Date.now()-1e3*60*60*18).toISOString()},{id:"5",title:"Best practices for organizing forum categories",body:"We are launching a developer community and are unsure how to structure our categories. Should we go broad (3-5 categories) or granular (10+ sub-categories)? Looking for advice from people who have run communities before.",author:{id:"u5",name:"community_lead",avatar:null},category:{id:"general",label:"General",icon:"💬"},tags:["community","organization","best-practices"],votes:22,userVote:0,replyCount:17,viewCount:312,createdAt:new Date(Date.now()-1e3*60*60*24).toISOString()},{id:"6",title:"Building a searchable FAQ from pinned posts",body:"One pattern I have found useful is using pinned posts as a structured FAQ. You can tag them with `faq` and surface them in a dedicated section. Here is how I set it up with the forum module.",author:{id:"u1",name:"alex_m",avatar:null},category:{id:"general",label:"General",icon:"💬"},tags:["faq","pinned","pattern"],votes:41,userVote:0,replyCount:6,viewCount:188,createdAt:new Date(Date.now()-1e3*60*60*36).toISOString()}],R=[{id:"r1",body:"You can pass a `categories` prop directly to `<ForumPage>`. The shape is `{ id, label, icon, count }`. If you want a global default, set it in your `mn-config.js` under the `forum` key.",author:{id:"u1",name:"alex_m",avatar:null},votes:15,userVote:1,createdAt:new Date(Date.now()-1e3*60*60*5).toISOString(),isAccepted:!0},{id:"r2",body:"Also worth noting — you can use the `CategoryNav` component standalone if you want to place it somewhere other than the default sidebar.",author:{id:"u3",name:"techwriter_k",avatar:null},votes:8,userVote:0,createdAt:new Date(Date.now()-1e3*60*60*4).toISOString()},{id:"r3",body:"Great question — I had the same issue when I first set up the forum. The docs example in the README shows the full config including custom categories.",author:{id:"u5",name:"community_lead",avatar:null},votes:3,userVote:0,createdAt:new Date(Date.now()-1e3*60*60*3).toISOString()}],le=[{id:"newest",label:"Newest"},{id:"top",label:"Top Voted"},{id:"unanswered",label:"Unanswered"}];function de({categories:r=_,posts:n=H,activeCategory:t="all",searchQuery:o="",sortBy:a="newest",onCategoryChange:l,onSearch:i,onSortChange:p,onPostClick:g,onNewPost:b,onVote:y,isLoading:d=!1,isDark:f=!0,header:F,title:x="Forum",subtitle:w="Discussions, questions, and ideas from the community.",style:m}){const[B,C]=S.useState(o),[k,G]=S.useState(a),[A,P]=S.useState(t),I=f?"var(--mn-text-primary-dark, #F0F4FF)":"var(--mn-text-primary-light, #1A1A2E)",T=f?"var(--mn-text-secondary-dark, #94A3B8)":"var(--mn-text-secondary-light, #64748B)",O=f?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",N=f?"rgba(255,255,255,0.05)":"rgba(0,0,0,0.04)";function Q(c){C(c),i==null||i(c)}function L(c){G(c),p==null||p(c)}function s(c){P(c),l==null||l(c)}const h=S.useMemo(()=>{let c=n;if(A!=="all"&&(c=c.filter(v=>{var z;return((z=v.category)==null?void 0:z.id)===A})),B.trim()){const v=B.toLowerCase();c=c.filter(z=>{var ne;return z.title.toLowerCase().includes(v)||((ne=z.body)==null?void 0:ne.toLowerCase().includes(v))})}return k==="top"&&(c=[...c].sort((v,z)=>z.votes-v.votes)),k==="newest"&&(c=[...c].sort((v,z)=>new Date(z.createdAt)-new Date(v.createdAt))),k==="unanswered"&&(c=c.filter(v=>!v.isSolved&&(v.replyCount??0)===0)),[...c].sort((v,z)=>(z.isPinned?1:0)-(v.isPinned?1:0))},[n,A,B,k]);return e.jsxs("div",{style:{padding:"var(--mn-spacing-xl, 32px)",display:"flex",flexDirection:"column",gap:24,fontFamily:"var(--mn-font-family, system-ui, sans-serif)",...m},children:[F??e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-end",flexWrap:"wrap",gap:12},children:[e.jsxs("div",{children:[e.jsx("h1",{style:{margin:0,fontSize:"var(--mn-font-size-2xl, 1.5rem)",fontWeight:700,color:I},children:x}),w&&e.jsx("p",{style:{margin:"4px 0 0",fontSize:"0.875rem",color:T},children:w})]}),e.jsx("button",{onClick:b,style:{padding:"8px 18px",borderRadius:"var(--mn-radius-md, 0.5rem)",border:"none",cursor:"pointer",backgroundColor:"var(--mn-color-primary, #3B82F6)",color:"#fff",fontSize:"0.875rem",fontWeight:600,fontFamily:"inherit",display:"flex",alignItems:"center",gap:6},children:"+ New Post"})]}),e.jsxs("div",{style:{display:"flex",gap:20,alignItems:"flex-start"},children:[e.jsx("div",{style:{width:200,flexShrink:0,position:"sticky",top:80},children:e.jsx(Y,{categories:r,active:A,onChange:s,isDark:f})}),e.jsxs("div",{style:{flex:1,minWidth:0,display:"flex",flexDirection:"column",gap:14},children:[e.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap",alignItems:"center"},children:[e.jsxs("div",{style:{position:"relative",flex:"1 1 200px"},children:[e.jsx("span",{style:{position:"absolute",left:10,top:"50%",transform:"translateY(-50%)",color:T,pointerEvents:"none",fontSize:14},children:"🔍"}),e.jsx("input",{value:B,onChange:c=>Q(c.target.value),placeholder:"Search posts…",style:{width:"100%",boxSizing:"border-box",padding:"8px 10px 8px 32px",borderRadius:"var(--mn-radius-md, 0.5rem)",backgroundColor:N,border:`1px solid ${O}`,color:I,fontSize:"0.875rem",fontFamily:"inherit",outline:"none"},onFocus:c=>{c.target.style.borderColor="var(--mn-color-primary, #3B82F6)"},onBlur:c=>{c.target.style.borderColor=O}})]}),e.jsx("div",{style:{display:"flex",gap:2,backgroundColor:f?"rgba(255,255,255,0.05)":"rgba(0,0,0,0.05)",padding:3,borderRadius:"var(--mn-radius-md, 0.5rem)"},children:le.map(c=>{const v=k===c.id;return e.jsx("button",{onClick:()=>L(c.id),style:{padding:"4px 12px",borderRadius:6,border:"none",cursor:"pointer",backgroundColor:v?f?"rgba(255,255,255,0.09)":"#fff":"transparent",color:v?I:T,fontSize:"0.8125rem",fontWeight:v?600:400,fontFamily:"inherit",transition:"all 100ms"},children:c.label},c.id)})})]}),!d&&e.jsxs("p",{style:{margin:0,fontSize:"0.8125rem",color:T},children:[h.length," ",h.length===1?"post":"posts",B?` matching "${B}"`:""]}),e.jsx(D,{posts:h,onPostClick:g,onVote:y,isLoading:d,isDark:f})]})]})]})}function ee({post:r,onVote:n,isDark:t=!0}){var p;const o=t?"var(--mn-color-card-dark, #0B0F23)":"var(--mn-color-card-light, #FAFAF8)",a=t?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",l=t?"var(--mn-text-primary-dark, #F0F4FF)":"var(--mn-text-primary-light, #1A1A2E)",i=t?"var(--mn-text-secondary-dark, #94A3B8)":"var(--mn-text-secondary-light, #64748B)";return e.jsxs("div",{style:{borderRadius:"var(--mn-radius-lg, 0.75rem)",backgroundColor:o,border:`1px solid ${a}`,overflow:"hidden"},children:[e.jsxs("div",{style:{padding:"20px 24px",borderBottom:`1px solid ${a}`},children:[e.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap",marginBottom:12},children:[r.isPinned&&e.jsx(V,{color:"warning",children:"📌 Pinned"}),r.isSolved&&e.jsx(V,{color:"success",children:"✓ Solved"}),r.isLocked&&e.jsx(V,{color:"muted",children:"🔒 Locked"}),e.jsx(j,{category:r.category})]}),e.jsx("h1",{style:{margin:"0 0 14px",fontSize:"var(--mn-font-size-xl, 1.25rem)",fontWeight:700,color:l,lineHeight:1.4},children:r.title}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:16,flexWrap:"wrap"},children:[e.jsx(E,{author:r.author,date:r.createdAt,prefix:"posted",isDark:t}),e.jsxs("span",{style:{fontSize:"0.8125rem",color:i},children:["👁 ",r.viewCount??0," views"]}),e.jsxs("span",{style:{fontSize:"0.8125rem",color:i},children:["💬 ",r.replyCount??0," replies"]})]})]}),e.jsxs("div",{style:{display:"flex",gap:0},children:[e.jsx("div",{style:{padding:"20px 16px",borderRight:`1px solid ${a}`,display:"flex",flexDirection:"column",alignItems:"center",gap:4,flexShrink:0},children:e.jsx(W,{count:r.votes,userVote:r.userVote??0,onChange:g=>n==null?void 0:n(r.id,g),vertical:!0,isDark:t})}),e.jsxs("div",{style:{flex:1,padding:"20px 24px"},children:[e.jsx("div",{style:{fontSize:"0.9375rem",color:l,lineHeight:1.7,whiteSpace:"pre-wrap",wordBreak:"break-word"},children:r.body}),((p=r.tags)==null?void 0:p.length)>0&&e.jsx("div",{style:{display:"flex",gap:6,flexWrap:"wrap",marginTop:18},children:r.tags.map(g=>e.jsx(M,{label:g,isDark:t},g))})]})]})]})}function V({color:r,children:n}){const t={warning:{bg:"rgba(245,158,11,0.12)",text:"#FCD34D",border:"rgba(245,158,11,0.25)"},success:{bg:"rgba(16,185,129,0.12)",text:"#34D399",border:"rgba(16,185,129,0.25)"},muted:{bg:"rgba(107,114,128,0.12)",text:"#9CA3AF",border:"rgba(107,114,128,0.2)"}},o=t[r]??t.muted;return e.jsx("span",{style:{fontSize:"0.7rem",fontWeight:600,padding:"2px 8px",borderRadius:9999,backgroundColor:o.bg,color:o.text,border:`1px solid ${o.border}`},children:n})}function re({reply:r,onVote:n,onAccept:t,canAccept:o=!1,isDark:a=!0}){const l=a?"var(--mn-color-card-dark, #0B0F23)":"var(--mn-color-card-light, #FAFAF8)",i=a?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",p=a?"var(--mn-text-primary-dark, #F0F4FF)":"var(--mn-text-primary-light, #1A1A2E)",g=a?"var(--mn-text-secondary-dark, #94A3B8)":"var(--mn-text-secondary-light, #64748B)",b=r.isAccepted?"rgba(16,185,129,0.35)":i,y=r.isAccepted?a?"rgba(16,185,129,0.05)":"rgba(16,185,129,0.04)":l;return e.jsxs("div",{style:{display:"flex",borderRadius:"var(--mn-radius-lg, 0.75rem)",backgroundColor:y,border:`1px solid ${b}`,overflow:"hidden"},children:[e.jsxs("div",{style:{padding:"16px 14px",borderRight:`1px solid ${i}`,display:"flex",flexDirection:"column",alignItems:"center",gap:4,flexShrink:0},children:[e.jsx(W,{count:r.votes,userVote:r.userVote??0,onChange:d=>n==null?void 0:n(r.id,d),vertical:!0,isDark:a,size:"sm"}),(r.isAccepted||o)&&e.jsx("button",{onClick:()=>t==null?void 0:t(r.id),title:r.isAccepted?"Accepted answer":"Mark as accepted",style:{marginTop:6,width:28,height:28,borderRadius:6,border:"none",cursor:o?"pointer":"default",backgroundColor:r.isAccepted?"rgba(16,185,129,0.15)":"transparent",color:r.isAccepted?"#10B981":g,display:"flex",alignItems:"center",justifyContent:"center",fontSize:14,transition:"background 100ms"},onMouseEnter:d=>{o&&!r.isAccepted&&(d.currentTarget.style.backgroundColor="rgba(16,185,129,0.1)")},onMouseLeave:d=>{r.isAccepted||(d.currentTarget.style.backgroundColor="transparent")},children:"✓"})]}),e.jsxs("div",{style:{flex:1,padding:"16px 18px",minWidth:0},children:[r.isAccepted&&e.jsxs("div",{style:{display:"inline-flex",alignItems:"center",gap:5,fontSize:"0.75rem",fontWeight:600,color:"#10B981",marginBottom:10},children:[e.jsx("span",{children:"✓"})," Accepted Answer"]}),e.jsx("div",{style:{fontSize:"0.9375rem",color:p,lineHeight:1.65,whiteSpace:"pre-wrap",wordBreak:"break-word"},children:r.body}),e.jsx("div",{style:{marginTop:12},children:e.jsx(E,{author:r.author,date:r.createdAt,prefix:"replied",isDark:a,size:"sm"})})]})]})}function te({replies:r=[],onVote:n,onAccept:t,canAccept:o=!1,currentUser:a,onSubmit:l,isLocked:i=!1,isDark:p=!0}){const g=p?"#F0F4FF":"#1A1A2E",b=p?"#94A3B8":"#64748B",y=p?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",d=[...r].sort((f,F)=>f.isAccepted&&!F.isAccepted?-1:!f.isAccepted&&F.isAccepted?1:F.votes-f.votes);return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:20},children:[r.length>0&&e.jsx("div",{style:{paddingBottom:12,borderBottom:`1px solid ${y}`},children:e.jsxs("h2",{style:{margin:0,fontSize:"1rem",fontWeight:600,color:g},children:[r.length," ",r.length===1?"Reply":"Replies"]})}),d.length>0&&e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:12},children:d.map(f=>e.jsx(re,{reply:f,onVote:n,onAccept:t,canAccept:o,isDark:p},f.id))}),i?e.jsx("div",{style:{textAlign:"center",padding:"20px",color:b,fontSize:"0.875rem",backgroundColor:p?"rgba(255,255,255,0.03)":"rgba(0,0,0,0.03)",borderRadius:"var(--mn-radius-md, 0.5rem)",border:`1px solid ${y}`},children:"🔒 This thread is locked — no new replies allowed."}):e.jsx(oe,{currentUser:a,onSubmit:l,isDark:p,placeholder:r.length===0?"Be the first to reply…":"Write a reply…"})]})}function oe({currentUser:r,onSubmit:n,placeholder:t="Write a reply…",isDark:o=!0}){const[a,l]=S.useState(""),[i,p]=S.useState(!1),[g,b]=S.useState(""),y=o?"var(--mn-color-card-dark, #0B0F23)":"var(--mn-color-card-light, #FAFAF8)",d=o?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",f=o?"#F0F4FF":"#1A1A2E",F=o?"#94A3B8":"#64748B",x=o?"rgba(255,255,255,0.04)":"rgba(0,0,0,0.03)";async function w(){const m=a.trim();if(!m){b("Reply cannot be empty.");return}b(""),p(!0);try{await(n==null?void 0:n(m)),l("")}finally{p(!1)}}return e.jsxs("div",{style:{borderRadius:"var(--mn-radius-lg, 0.75rem)",backgroundColor:y,border:`1px solid ${d}`,padding:"16px 18px",display:"flex",flexDirection:"column",gap:12},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10},children:[e.jsx(q,{name:(r==null?void 0:r.name)??"?",size:26,src:r==null?void 0:r.avatar}),e.jsx("span",{style:{fontSize:"0.8125rem",fontWeight:600,color:f},children:r?r.name:"Reply as Guest"})]}),e.jsx("textarea",{value:a,onChange:m=>{l(m.target.value),g&&b("")},placeholder:t,rows:4,style:{width:"100%",boxSizing:"border-box",padding:"10px 12px",borderRadius:"var(--mn-radius-md, 0.5rem)",backgroundColor:x,border:`1px solid ${g?"rgba(239,68,68,0.4)":d}`,color:f,fontSize:"0.9375rem",lineHeight:1.6,resize:"vertical",fontFamily:"var(--mn-font-family, system-ui, sans-serif)",outline:"none",transition:"border-color 120ms"},onFocus:m=>{m.target.style.borderColor="var(--mn-color-primary, #3B82F6)"},onBlur:m=>{m.target.style.borderColor=g?"rgba(239,68,68,0.4)":d}}),g&&e.jsx("p",{style:{margin:0,fontSize:"0.8125rem",color:"#F87171"},children:g}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[e.jsxs("span",{style:{fontSize:"0.75rem",color:F},children:[a.length," / 8000"]}),e.jsxs("button",{onClick:w,disabled:i||!a.trim(),style:{padding:"7px 18px",borderRadius:"var(--mn-radius-md, 0.5rem)",border:"none",cursor:i||!a.trim()?"not-allowed":"pointer",backgroundColor:i||!a.trim()?"rgba(59,130,246,0.4)":"var(--mn-color-primary, #3B82F6)",color:"#fff",fontSize:"0.875rem",fontWeight:600,fontFamily:"inherit",transition:"background 120ms",display:"flex",alignItems:"center",gap:7},children:[i&&e.jsx(se,{}),i?"Posting…":"Post Reply"]})]})]})}function se(){return e.jsx("span",{style:{display:"inline-block",width:12,height:12,border:"2px solid rgba(255,255,255,0.3)",borderTopColor:"#fff",borderRadius:"50%",animation:"mn-spin 0.6s linear infinite"},children:e.jsx("style",{children:"@keyframes mn-spin { to { transform: rotate(360deg); } }"})})}function ce({post:r=H[0],replies:n=R,currentUser:t=null,onBack:o,onVotePost:a,onVoteReply:l,onAccept:i,onSubmitReply:p,isLoading:g=!1,isDark:b=!0,style:y}){var x;const d=b?"var(--mn-text-primary-dark, #F0F4FF)":"var(--mn-text-primary-light, #1A1A2E)",f=b?"var(--mn-text-secondary-dark, #94A3B8)":"var(--mn-text-secondary-light, #64748B)",F=t&&((x=r==null?void 0:r.author)==null?void 0:x.id)===(t==null?void 0:t.id);return g?e.jsx("div",{style:{padding:"var(--mn-spacing-xl, 32px)",fontFamily:"var(--mn-font-family, system-ui, sans-serif)",...y},children:e.jsx(ge,{isDark:b})}):r?e.jsxs("div",{style:{padding:"var(--mn-spacing-xl, 32px)",display:"flex",flexDirection:"column",gap:20,maxWidth:860,fontFamily:"var(--mn-font-family, system-ui, sans-serif)",...y},children:[e.jsx("button",{onClick:o,style:{alignSelf:"flex-start",display:"flex",alignItems:"center",gap:6,padding:"6px 12px",borderRadius:"var(--mn-radius-md, 0.5rem)",border:"none",cursor:"pointer",backgroundColor:b?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",color:f,fontSize:"0.875rem",fontFamily:"inherit",transition:"background 100ms"},onMouseEnter:w=>{w.currentTarget.style.backgroundColor=b?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.1)"},onMouseLeave:w=>{w.currentTarget.style.backgroundColor=b?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)"},children:"← Back to Forum"}),e.jsx(ee,{post:r,onVote:a,isDark:b}),e.jsx(te,{replies:n,onVote:l,onAccept:i,canAccept:F,currentUser:t,onSubmit:p,isLocked:r.isLocked,isDark:b})]}):e.jsxs("div",{style:{padding:"var(--mn-spacing-xl, 32px)",textAlign:"center",color:f,fontFamily:"var(--mn-font-family, system-ui, sans-serif)",...y},children:[e.jsx("p",{style:{fontSize:32,margin:"0 0 12px"},children:"🔍"}),e.jsx("p",{style:{margin:0,fontWeight:600,color:d},children:"Post not found"})]})}function ge({isDark:r}){const n=r?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",t=r?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",o=r?"var(--mn-color-card-dark, #0B0F23)":"var(--mn-color-card-light, #FAFAF8)",a=(l,i=12)=>({width:l,height:i,borderRadius:6,backgroundColor:n,animation:"mn-pulse 1.4s ease infinite"});return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:16},children:[e.jsx("div",{style:a(80)}),e.jsxs("div",{style:{borderRadius:"var(--mn-radius-lg, 0.75rem)",backgroundColor:o,border:`1px solid ${t}`,padding:"20px 24px",display:"flex",flexDirection:"column",gap:14},children:[e.jsx("div",{style:a("30%",8)}),e.jsx("div",{style:a("70%",20)}),e.jsx("div",{style:a("45%",10)}),e.jsx("div",{style:{height:80,borderRadius:6,backgroundColor:n}})]}),e.jsx("style",{children:"@keyframes mn-pulse { 0%,100%{opacity:.5} 50%{opacity:1} }"})]})}function pe({categories:r=_.filter(i=>i.id!=="all"),onSubmit:n,onCancel:t,currentUser:o=null,isDark:a=!0,style:l}){const[i,p]=S.useState(""),[g,b]=S.useState(""),[y,d]=S.useState(""),[f,F]=S.useState(""),[x,w]=S.useState([]),[m,B]=S.useState(!1),[C,k]=S.useState({}),G=a?"var(--mn-color-card-dark, #0B0F23)":"var(--mn-color-card-light, #FAFAF8)",A=a?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",P=a?"var(--mn-text-primary-dark, #F0F4FF)":"var(--mn-text-primary-light, #1A1A2E)",I=a?"var(--mn-text-secondary-dark, #94A3B8)":"var(--mn-text-secondary-light, #64748B)",T=a?"rgba(255,255,255,0.04)":"rgba(0,0,0,0.03)";function O(){const s={};return i.trim()||(s.title="Title is required."),i.length>200&&(s.title="Title must be under 200 characters."),g.trim()||(s.body="Body is required."),y||(s.category="Please choose a category."),s}async function N(s){s.preventDefault();const h=O();if(Object.keys(h).length){k(h);return}k({}),B(!0);try{await(n==null?void 0:n({title:i.trim(),body:g.trim(),categoryId:y,tags:x}))}finally{B(!1)}}function Q(s){if((s.key==="Enter"||s.key===",")&&f.trim()){s.preventDefault();const h=f.trim().toLowerCase().replace(/[^a-z0-9-]/g,"-");!x.includes(h)&&x.length<5&&w(c=>[...c,h]),F("")}s.key==="Backspace"&&!f&&x.length&&w(h=>h.slice(0,-1))}const L=s=>({width:"100%",boxSizing:"border-box",padding:"10px 12px",borderRadius:"var(--mn-radius-md, 0.5rem)",backgroundColor:T,border:`1px solid ${s?"rgba(239,68,68,0.4)":A}`,color:P,fontSize:"0.9375rem",fontFamily:"var(--mn-font-family, system-ui, sans-serif)",outline:"none",transition:"border-color 120ms"});return e.jsxs("div",{style:{padding:"var(--mn-spacing-xl, 32px)",display:"flex",flexDirection:"column",gap:20,maxWidth:780,fontFamily:"var(--mn-font-family, system-ui, sans-serif)",...l},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:12},children:[e.jsxs("div",{children:[e.jsx("h1",{style:{margin:0,fontSize:"var(--mn-font-size-xl, 1.25rem)",fontWeight:700,color:P},children:"New Post"}),e.jsx("p",{style:{margin:"4px 0 0",fontSize:"0.875rem",color:I},children:"Share a question, idea, or discussion with the community."})]}),t&&e.jsx("button",{onClick:t,style:{padding:"6px 14px",borderRadius:"var(--mn-radius-md, 0.5rem)",border:`1px solid ${A}`,cursor:"pointer",backgroundColor:"transparent",color:I,fontSize:"0.875rem",fontFamily:"inherit"},children:"Cancel"})]}),e.jsxs("form",{onSubmit:N,style:{borderRadius:"var(--mn-radius-lg, 0.75rem)",backgroundColor:G,border:`1px solid ${A}`,padding:"24px",display:"flex",flexDirection:"column",gap:20},children:[o&&e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"8px 12px",borderRadius:"var(--mn-radius-md, 0.5rem)",backgroundColor:a?"rgba(255,255,255,0.04)":"rgba(0,0,0,0.03)",border:`1px solid ${A}`},children:[e.jsx(q,{name:o.name,size:24,src:o.avatar}),e.jsxs("span",{style:{fontSize:"0.875rem",color:P},children:["Posting as ",e.jsx("strong",{children:o.name})]})]}),e.jsxs($,{label:"Title",error:C.title,required:!0,children:[e.jsx("input",{value:i,onChange:s=>{p(s.target.value),C.title&&k(h=>({...h,title:""}))},placeholder:"What is your question or topic?",style:L(C.title),onFocus:s=>{s.target.style.borderColor="var(--mn-color-primary, #3B82F6)"},onBlur:s=>{s.target.style.borderColor=C.title?"rgba(239,68,68,0.4)":A}}),e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",marginTop:4},children:e.jsxs("span",{style:{fontSize:"0.75rem",color:i.length>180?"#F87171":I},children:[i.length,"/200"]})})]}),e.jsx($,{label:"Category",error:C.category,required:!0,children:e.jsx("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:r.map(s=>{const h=y===s.id;return e.jsxs("button",{type:"button",onClick:()=>{d(s.id),C.category&&k(c=>({...c,category:""}))},style:{display:"flex",alignItems:"center",gap:6,padding:"7px 14px",borderRadius:"var(--mn-radius-md, 0.5rem)",border:`1px solid ${h?"var(--mn-color-primary, #3B82F6)":A}`,cursor:"pointer",fontFamily:"inherit",fontSize:"0.875rem",backgroundColor:h?"rgba(59,130,246,0.1)":T,color:h?"var(--mn-color-primary, #3B82F6)":P,transition:"all 100ms",fontWeight:h?600:400},children:[s.icon&&e.jsx("span",{children:s.icon}),s.label]},s.id)})})}),e.jsx($,{label:"Body",error:C.body,required:!0,children:e.jsx("textarea",{value:g,onChange:s=>{b(s.target.value),C.body&&k(h=>({...h,body:""}))},placeholder:"Describe your question or topic in detail. The more context you provide, the better the community can help.",rows:8,style:{...L(C.body),resize:"vertical",lineHeight:1.65},onFocus:s=>{s.target.style.borderColor="var(--mn-color-primary, #3B82F6)"},onBlur:s=>{s.target.style.borderColor=C.body?"rgba(239,68,68,0.4)":A}})}),e.jsx($,{label:"Tags",hint:"Up to 5 tags. Press Enter or comma to add.",children:e.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap",padding:"8px 10px",borderRadius:"var(--mn-radius-md, 0.5rem)",backgroundColor:T,border:`1px solid ${A}`,minHeight:42,alignItems:"center"},children:[x.map(s=>e.jsxs("span",{style:{display:"flex",alignItems:"center",gap:4,fontSize:"0.75rem",padding:"2px 8px",borderRadius:9999,backgroundColor:a?"rgba(59,130,246,0.1)":"rgba(59,130,246,0.07)",color:"#60A5FA",border:"1px solid rgba(59,130,246,0.2)"},children:["#",s,e.jsx("button",{type:"button",onClick:()=>w(h=>h.filter(c=>c!==s)),style:{background:"none",border:"none",cursor:"pointer",color:"inherit",padding:0,fontSize:12,lineHeight:1,display:"flex",alignItems:"center"},children:"×"})]},s)),x.length<5&&e.jsx("input",{value:f,onChange:s=>F(s.target.value),onKeyDown:Q,placeholder:x.length===0?"e.g. bug, question, feature":"",style:{border:"none",outline:"none",backgroundColor:"transparent",color:P,fontSize:"0.875rem",fontFamily:"inherit",flex:1,minWidth:120}})]})}),e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10,paddingTop:4,borderTop:`1px solid ${A}`,marginTop:4},children:[t&&e.jsx("button",{type:"button",onClick:t,style:{padding:"9px 20px",borderRadius:"var(--mn-radius-md, 0.5rem)",border:`1px solid ${A}`,cursor:"pointer",backgroundColor:"transparent",color:I,fontSize:"0.875rem",fontFamily:"inherit"},children:"Cancel"}),e.jsxs("button",{type:"submit",disabled:m,style:{padding:"9px 24px",borderRadius:"var(--mn-radius-md, 0.5rem)",border:"none",cursor:m?"wait":"pointer",backgroundColor:m?"rgba(59,130,246,0.5)":"var(--mn-color-primary, #3B82F6)",color:"#fff",fontSize:"0.875rem",fontWeight:600,fontFamily:"inherit",display:"flex",alignItems:"center",gap:8},children:[m&&e.jsx(fe,{}),m?"Publishing…":"Publish Post"]})]})]})]})}function $({label:r,children:n,error:t,hint:o,required:a}){return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:7},children:[e.jsxs("label",{style:{fontSize:"0.875rem",fontWeight:600,color:"var(--mn-text-primary-dark, #F0F4FF)",display:"flex",gap:4},children:[r,a&&e.jsx("span",{style:{color:"#F87171"},children:"*"})]}),n,o&&!t&&e.jsx("p",{style:{margin:0,fontSize:"0.75rem",color:"var(--mn-text-secondary-dark, #94A3B8)"},children:o}),t&&e.jsx("p",{style:{margin:0,fontSize:"0.8125rem",color:"#F87171"},children:t})]})}function fe(){return e.jsx("span",{style:{display:"inline-block",width:12,height:12,border:"2px solid rgba(255,255,255,0.3)",borderTopColor:"#fff",borderRadius:"50%",animation:"mn-spin 0.6s linear infinite"},children:e.jsx("style",{children:"@keyframes mn-spin { to { transform: rotate(360deg); } }"})})}u.AuthorMeta=E,u.CategoryBadge=j,u.CategoryNav=Y,u.CreatePostPage=pe,u.DEMO_CATEGORIES=_,u.DEMO_POSTS=H,u.DEMO_REPLIES=R,u.EmptyPostList=U,u.ForumPage=de,u.PostCard=X,u.PostDetail=ee,u.PostList=D,u.PostPage=ce,u.ReplyCard=re,u.ReplyComposer=oe,u.ReplyThread=te,u.TagChip=M,u.VoteButton=W,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})}));
|
|
2
|
+
//# sourceMappingURL=mounajiforum.umd.cjs.map
|