feat(portfolio): add ze manual page at /ze
- Add ze-manual-html ConfigMap serving ze-manual.html at /ze/index.html - Mount ze-manual-html in nginx at /usr/share/nginx/html/ze - Add Projects section in portfolio index with ze card linking to /ze
This commit is contained in:
+143
-321
@@ -1,326 +1,148 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
data:
|
||||||
|
index.html: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\"
|
||||||
|
/>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"
|
||||||
|
/>\n <title>ChemaVX</title>\n <style>\n *, *::before, *::after { box-sizing:
|
||||||
|
border-box; margin: 0; padding: 0; }\n\n :root {\n --bg: #0d1117;\n
|
||||||
|
\ --surface: #161b22;\n --border: #30363d;\n --text: #e6edf3;\n
|
||||||
|
\ --muted: #8b949e;\n --accent: #58a6ff;\n --green: #3fb950;\n
|
||||||
|
\ --red: #f85149;\n --yellow: #d29922;\n --purple: #bc8cff;\n
|
||||||
|
\ }\n\n body {\n background: var(--bg);\n color: var(--text);\n
|
||||||
|
\ font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Helvetica,
|
||||||
|
Arial, sans-serif;\n min-height: 100vh;\n display: flex;\n flex-direction:
|
||||||
|
column;\n align-items: center;\n padding: 3rem 1.5rem 4rem;\n }\n\n
|
||||||
|
\ /* ── Header ─────────────────────────────────── */\n header {\n text-align:
|
||||||
|
center;\n margin-bottom: 3.5rem;\n }\n .avatar {\n width: 80px;
|
||||||
|
height: 80px;\n border-radius: 50%;\n background: linear-gradient(135deg,
|
||||||
|
#1f6feb 0%, #bc8cff 100%);\n display: flex; align-items: center; justify-content:
|
||||||
|
center;\n font-size: 2rem; font-weight: 700; color: #fff;\n margin:
|
||||||
|
0 auto 1.25rem;\n box-shadow: 0 0 0 3px var(--border);\n }\n h1 { font-size:
|
||||||
|
2rem; font-weight: 700; letter-spacing: -0.5px; }\n .tagline {\n color:
|
||||||
|
var(--muted); font-size: 0.95rem; margin-top: 0.4rem;\n }\n .dot { display:
|
||||||
|
inline-block; width: 8px; height: 8px;\n border-radius: 50%; background:
|
||||||
|
var(--green);\n margin-right: 6px; animation: pulse 2s infinite; }\n
|
||||||
|
\ @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity:
|
||||||
|
0.4; }\n }\n\n /* ── Section title ───────────────────────────── */\n .section-title
|
||||||
|
{\n font-size: 0.7rem; font-weight: 600; letter-spacing: 0.08em;\n text-transform:
|
||||||
|
uppercase; color: var(--muted);\n margin-bottom: 0.875rem;\n }\n\n /*
|
||||||
|
── Services grid ───────────────────────────── */\n .services-grid {\n display:
|
||||||
|
grid;\n grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));\n gap:
|
||||||
|
0.75rem;\n width: 100%; max-width: 720px;\n margin-bottom: 2.5rem;\n
|
||||||
|
\ }\n .service-card {\n background: var(--surface);\n border: 1px
|
||||||
|
solid var(--border);\n border-radius: 10px;\n padding: 1rem 1.1rem;\n
|
||||||
|
\ text-decoration: none;\n color: var(--text);\n transition: border-color
|
||||||
|
0.15s, transform 0.15s, box-shadow 0.15s;\n display: flex; align-items: center;
|
||||||
|
gap: 0.65rem;\n }\n .service-card:hover {\n border-color: var(--accent);\n
|
||||||
|
\ transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(88,166,255,0.1);\n
|
||||||
|
\ }\n .service-icon { font-size: 1.3rem; flex-shrink: 0; }\n .service-name
|
||||||
|
{ font-size: 0.9rem; font-weight: 500; }\n\n /* ── Polymarket card ───────────────────────────
|
||||||
|
*/\n .poly-wrapper { width: 100%; max-width: 720px; }\n .poly-card {\n background:
|
||||||
|
var(--surface);\n border: 1px solid var(--border);\n border-radius:
|
||||||
|
12px;\n padding: 1.5rem;\n margin-bottom: 2.5rem;\n }\n .poly-header
|
||||||
|
{\n display: flex; align-items: center; justify-content: space-between;\n
|
||||||
|
\ margin-bottom: 1.25rem;\n }\n .poly-title {\n display: flex;
|
||||||
|
align-items: center; gap: 0.5rem;\n font-size: 0.95rem; font-weight: 600;\n
|
||||||
|
\ }\n .poly-badge {\n font-size: 0.65rem; font-weight: 600; letter-spacing:
|
||||||
|
0.04em;\n padding: 2px 7px; border-radius: 20px;\n background: rgba(188,140,255,0.15);
|
||||||
|
color: var(--purple);\n border: 1px solid rgba(188,140,255,0.3);\n }\n
|
||||||
|
\ #poly-updated {\n font-size: 0.72rem; color: var(--muted);\n }\n\n
|
||||||
|
\ .metrics-grid {\n display: grid;\n grid-template-columns: repeat(2,
|
||||||
|
1fr);\n gap: 0.75rem;\n }\n @media (min-width: 480px) {\n .metrics-grid
|
||||||
|
{ grid-template-columns: repeat(4, 1fr); }\n }\n .metric {\n background:
|
||||||
|
var(--bg);\n border: 1px solid var(--border);\n border-radius: 8px;\n
|
||||||
|
\ padding: 0.875rem 1rem;\n }\n .metric-label {\n font-size: 0.68rem;
|
||||||
|
color: var(--muted);\n text-transform: uppercase; letter-spacing: 0.06em;\n
|
||||||
|
\ margin-bottom: 0.35rem;\n }\n .metric-value {\n font-size: 1.35rem;
|
||||||
|
font-weight: 700; font-variant-numeric: tabular-nums;\n transition: color
|
||||||
|
0.3s;\n }\n .metric-value.positive { color: var(--green); }\n .metric-value.negative
|
||||||
|
{ color: var(--red); }\n .metric-value.neutral { color: var(--text); }\n .metric-value.loading
|
||||||
|
\ { color: var(--muted); font-size: 1rem; }\n\n /* ── Footer ────────────────────────────────────
|
||||||
|
*/\n footer {\n color: var(--muted); font-size: 0.75rem; text-align: center;\n
|
||||||
|
\ width: 100%; max-width: 720px;\n border-top: 1px solid var(--border);\n
|
||||||
|
\ padding-top: 1.25rem;\n }\n footer a { color: var(--accent); text-decoration:
|
||||||
|
none; }\n footer a:hover { text-decoration: underline; }\n </style>\n</head>\n<body>\n\n
|
||||||
|
\ <header>\n <div class=\"avatar\">C</div>\n <h1>ChemaVX</h1>\n <p class=\"tagline\">\n
|
||||||
|
\ <span class=\"dot\"></span>Homelab · k3s · Self-hosted\n </p>\n </header>\n\n
|
||||||
|
\ <!-- Services -->\n <div style=\"width:100%;max-width:720px;margin-bottom:2.5rem;\">\n
|
||||||
|
\ <p class=\"section-title\">Services</p>\n <div class=\"services-grid\">\n
|
||||||
|
\ <a class=\"service-card\" href=\"https://grafana.chemavx.xyz\" target=\"_blank\"
|
||||||
|
rel=\"noopener\">\n <span class=\"service-icon\">\U0001F4CA</span>\n <span
|
||||||
|
class=\"service-name\">Grafana</span>\n </a>\n <a class=\"service-card\"
|
||||||
|
href=\"https://n8n.chemavx.xyz\" target=\"_blank\" rel=\"noopener\">\n <span
|
||||||
|
class=\"service-icon\">⚙️</span>\n <span class=\"service-name\">n8n</span>\n
|
||||||
|
\ </a>\n <a class=\"service-card\" href=\"https://home.chemavx.xyz\"
|
||||||
|
target=\"_blank\" rel=\"noopener\">\n <span class=\"service-icon\">\U0001F3E0</span>\n
|
||||||
|
\ <span class=\"service-name\">Homarr</span>\n </a>\n <a class=\"service-card\"
|
||||||
|
href=\"https://polymarket.chemavx.xyz\" target=\"_blank\" rel=\"noopener\">\n
|
||||||
|
\ <span class=\"service-icon\">\U0001F4C8</span>\n <span class=\"service-name\">Polymarket
|
||||||
|
Bot</span>\n </a>\n <a class=\"service-card\" href=\"https://chat.chemavx.xyz\"
|
||||||
|
target=\"_blank\" rel=\"noopener\">\n <span class=\"service-icon\">\U0001F916</span>\n
|
||||||
|
\ <span class=\"service-name\">Open WebUI</span>\n </a>\n <a class=\"service-card\"
|
||||||
|
href=\"https://git.chemavx.xyz\" target=\"_blank\" rel=\"noopener\">\n <span
|
||||||
|
class=\"service-icon\">\U0001F419</span>\n <span class=\"service-name\">Gitea</span>\n
|
||||||
|
\ </a>\n <a class=\"service-card\" href=\"https://argocd.chemavx.xyz\"
|
||||||
|
target=\"_blank\" rel=\"noopener\">\n <span class=\"service-icon\">\U0001F504</span>\n
|
||||||
|
\ <span class=\"service-name\">ArgoCD</span>\n </a>\n <a class=\"service-card\"
|
||||||
|
href=\"https://vaultwarden.chemavx.xyz\" target=\"_blank\" rel=\"noopener\">\n
|
||||||
|
\ <span class=\"service-icon\">\U0001F510</span>\n <span class=\"service-name\">Vaultwarden</span>\n
|
||||||
|
\ </a>\n </div>\n </div>\n\n <!-- Projects -->\n <div style=\"width:100%;max-width:720px;margin-bottom:2.5rem;\">\n
|
||||||
|
\ <p class=\"section-title\">Projects</p>\n <div class=\"services-grid\">\n
|
||||||
|
\ <a class=\"service-card\" href=\"/ze\">\n <span class=\"service-icon\">\U0001F6F8</span>\n
|
||||||
|
\ <span class=\"service-name\">ze</span>\n </a>\n </div>\n </div>\n\n
|
||||||
|
\ <!-- Polymarket live metrics -->\n <div class=\"poly-wrapper\">\n <p class=\"section-title\">Polymarket
|
||||||
|
Bot — Live</p>\n <div class=\"poly-card\">\n <div class=\"poly-header\">\n
|
||||||
|
\ <div class=\"poly-title\">\n <span>\U0001F4C8</span>\n <span>Portfolio
|
||||||
|
Summary</span>\n <span class=\"poly-badge\" id=\"poly-mode\">PAPER</span>\n
|
||||||
|
\ </div>\n <span id=\"poly-updated\">Loading…</span>\n </div>\n
|
||||||
|
\ <div class=\"metrics-grid\">\n <div class=\"metric\">\n <div
|
||||||
|
class=\"metric-label\">P&L</div>\n <div class=\"metric-value loading\"
|
||||||
|
id=\"m-pnl\">—</div>\n </div>\n <div class=\"metric\">\n <div
|
||||||
|
class=\"metric-label\">Win Rate</div>\n <div class=\"metric-value loading\"
|
||||||
|
id=\"m-winrate\">—</div>\n </div>\n <div class=\"metric\">\n <div
|
||||||
|
class=\"metric-label\">Deployed</div>\n <div class=\"metric-value loading\"
|
||||||
|
id=\"m-deployed\">—</div>\n </div>\n <div class=\"metric\">\n <div
|
||||||
|
class=\"metric-label\">Trades</div>\n <div class=\"metric-value loading\"
|
||||||
|
id=\"m-trades\">—</div>\n </div>\n <div class=\"metric\">\n <div
|
||||||
|
class=\"metric-label\">Bankroll</div>\n <div class=\"metric-value loading\"
|
||||||
|
id=\"m-bankroll\">—</div>\n </div>\n <div class=\"metric\">\n <div
|
||||||
|
class=\"metric-label\">Sharpe</div>\n <div class=\"metric-value loading\"
|
||||||
|
id=\"m-sharpe\">—</div>\n </div>\n <div class=\"metric\">\n <div
|
||||||
|
class=\"metric-label\">Calibration</div>\n <div class=\"metric-value
|
||||||
|
loading\" id=\"m-calibration\">—</div>\n </div>\n <div class=\"metric\">\n
|
||||||
|
\ <div class=\"metric-label\">Status</div>\n <div class=\"metric-value
|
||||||
|
loading\" id=\"m-status\">—</div>\n </div>\n </div>\n </div>\n
|
||||||
|
\ </div>\n\n <footer>\n <p>\n Hosted on <strong>k3s</strong> —\n
|
||||||
|
\ <a href=\"https://grafana.chemavx.xyz/d/chemavx-homelab-v1/chemavx-homelab-overview\"
|
||||||
|
target=\"_blank\">Cluster Dashboard</a>\n — <a href=\"https://git.chemavx.xyz\"
|
||||||
|
target=\"_blank\">Gitea</a>\n </p>\n </footer>\n\n <script>\n const API
|
||||||
|
= 'https://polymarket.chemavx.xyz/api/summary';\n const fmt$ = v => v == null
|
||||||
|
? '—' : '$' + v.toFixed(2);\n const fmtPct = v => v == null ? '—' : (v * 100).toFixed(1)
|
||||||
|
+ '%';\n const fmtN = v => v == null ? '—' : String(v);\n const fmtF =
|
||||||
|
(v, d=3) => v == null ? '—' : v.toFixed(d);\n\n function colorClass(id, val)
|
||||||
|
{\n const el = document.getElementById(id);\n el.classList.remove('positive','negative','neutral','loading');\n
|
||||||
|
\ if (val > 0) el.classList.add('positive');\n else if (val < 0) el.classList.add('negative');\n
|
||||||
|
\ else el.classList.add('neutral');\n }\n\n async function fetchMetrics()
|
||||||
|
{\n try {\n const r = await fetch(API, { cache: 'no-store' });\n if
|
||||||
|
(!r.ok) throw new Error(r.status);\n const d = await r.json();\n\n document.getElementById('m-pnl').textContent
|
||||||
|
\ = fmt$(d.total_pnl);\n document.getElementById('m-winrate').textContent
|
||||||
|
\ = fmtPct(d.win_rate);\n document.getElementById('m-deployed').textContent
|
||||||
|
\ = fmt$(d.total_deployed);\n document.getElementById('m-trades').textContent
|
||||||
|
\ = fmtN(d.total_trades);\n document.getElementById('m-bankroll').textContent
|
||||||
|
\ = fmt$(d.paper_bankroll);\n document.getElementById('m-sharpe').textContent
|
||||||
|
\ = fmtF(d.sharpe_ratio, 2);\n document.getElementById('m-calibration').textContent
|
||||||
|
= fmtF(d.calibration_score, 3);\n document.getElementById('m-status').textContent
|
||||||
|
\ = d.promotion_ready ? '\U0001F680 Ready' : '⏳ Training';\n\n colorClass('m-pnl',
|
||||||
|
d.total_pnl);\n colorClass('m-sharpe', d.sharpe_ratio);\n\n const
|
||||||
|
mode = d.paper_mode ? 'PAPER' : 'LIVE';\n const badge = document.getElementById('poly-mode');\n
|
||||||
|
\ badge.textContent = mode;\n badge.style.background = d.paper_mode\n
|
||||||
|
\ ? 'rgba(188,140,255,0.15)' : 'rgba(63,185,80,0.15)';\n badge.style.color
|
||||||
|
= d.paper_mode ? 'var(--purple)' : 'var(--green)';\n badge.style.borderColor
|
||||||
|
= d.paper_mode\n ? 'rgba(188,140,255,0.3)' : 'rgba(63,185,80,0.3)';\n\n
|
||||||
|
\ const now = new Date();\n document.getElementById('poly-updated').textContent
|
||||||
|
=\n 'Updated ' + now.toLocaleTimeString();\n } catch (e) {\n document.getElementById('poly-updated').textContent
|
||||||
|
= 'Error: ' + e.message;\n }\n }\n\n fetchMetrics();\n setInterval(fetchMetrics,
|
||||||
|
30000);\n </script>\n</body>\n</html>\n"
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: portfolio-html
|
name: portfolio-html
|
||||||
namespace: portfolio
|
namespace: portfolio
|
||||||
data:
|
|
||||||
index.html: |
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>ChemaVX</title>
|
|
||||||
<style>
|
|
||||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--bg: #0d1117;
|
|
||||||
--surface: #161b22;
|
|
||||||
--border: #30363d;
|
|
||||||
--text: #e6edf3;
|
|
||||||
--muted: #8b949e;
|
|
||||||
--accent: #58a6ff;
|
|
||||||
--green: #3fb950;
|
|
||||||
--red: #f85149;
|
|
||||||
--yellow: #d29922;
|
|
||||||
--purple: #bc8cff;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background: var(--bg);
|
|
||||||
color: var(--text);
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 3rem 1.5rem 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Header ─────────────────────────────────── */
|
|
||||||
header {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 3.5rem;
|
|
||||||
}
|
|
||||||
.avatar {
|
|
||||||
width: 80px; height: 80px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: linear-gradient(135deg, #1f6feb 0%, #bc8cff 100%);
|
|
||||||
display: flex; align-items: center; justify-content: center;
|
|
||||||
font-size: 2rem; font-weight: 700; color: #fff;
|
|
||||||
margin: 0 auto 1.25rem;
|
|
||||||
box-shadow: 0 0 0 3px var(--border);
|
|
||||||
}
|
|
||||||
h1 { font-size: 2rem; font-weight: 700; letter-spacing: -0.5px; }
|
|
||||||
.tagline {
|
|
||||||
color: var(--muted); font-size: 0.95rem; margin-top: 0.4rem;
|
|
||||||
}
|
|
||||||
.dot { display: inline-block; width: 8px; height: 8px;
|
|
||||||
border-radius: 50%; background: var(--green);
|
|
||||||
margin-right: 6px; animation: pulse 2s infinite; }
|
|
||||||
@keyframes pulse {
|
|
||||||
0%, 100% { opacity: 1; }
|
|
||||||
50% { opacity: 0.4; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Section title ───────────────────────────── */
|
|
||||||
.section-title {
|
|
||||||
font-size: 0.7rem; font-weight: 600; letter-spacing: 0.08em;
|
|
||||||
text-transform: uppercase; color: var(--muted);
|
|
||||||
margin-bottom: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Services grid ───────────────────────────── */
|
|
||||||
.services-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
|
||||||
gap: 0.75rem;
|
|
||||||
width: 100%; max-width: 720px;
|
|
||||||
margin-bottom: 2.5rem;
|
|
||||||
}
|
|
||||||
.service-card {
|
|
||||||
background: var(--surface);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 1rem 1.1rem;
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--text);
|
|
||||||
transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
|
|
||||||
display: flex; align-items: center; gap: 0.65rem;
|
|
||||||
}
|
|
||||||
.service-card:hover {
|
|
||||||
border-color: var(--accent);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 16px rgba(88,166,255,0.1);
|
|
||||||
}
|
|
||||||
.service-icon { font-size: 1.3rem; flex-shrink: 0; }
|
|
||||||
.service-name { font-size: 0.9rem; font-weight: 500; }
|
|
||||||
|
|
||||||
/* ── Polymarket card ─────────────────────────── */
|
|
||||||
.poly-wrapper { width: 100%; max-width: 720px; }
|
|
||||||
.poly-card {
|
|
||||||
background: var(--surface);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 1.5rem;
|
|
||||||
margin-bottom: 2.5rem;
|
|
||||||
}
|
|
||||||
.poly-header {
|
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
|
||||||
margin-bottom: 1.25rem;
|
|
||||||
}
|
|
||||||
.poly-title {
|
|
||||||
display: flex; align-items: center; gap: 0.5rem;
|
|
||||||
font-size: 0.95rem; font-weight: 600;
|
|
||||||
}
|
|
||||||
.poly-badge {
|
|
||||||
font-size: 0.65rem; font-weight: 600; letter-spacing: 0.04em;
|
|
||||||
padding: 2px 7px; border-radius: 20px;
|
|
||||||
background: rgba(188,140,255,0.15); color: var(--purple);
|
|
||||||
border: 1px solid rgba(188,140,255,0.3);
|
|
||||||
}
|
|
||||||
#poly-updated {
|
|
||||||
font-size: 0.72rem; color: var(--muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.metrics-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
gap: 0.75rem;
|
|
||||||
}
|
|
||||||
@media (min-width: 480px) {
|
|
||||||
.metrics-grid { grid-template-columns: repeat(4, 1fr); }
|
|
||||||
}
|
|
||||||
.metric {
|
|
||||||
background: var(--bg);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 0.875rem 1rem;
|
|
||||||
}
|
|
||||||
.metric-label {
|
|
||||||
font-size: 0.68rem; color: var(--muted);
|
|
||||||
text-transform: uppercase; letter-spacing: 0.06em;
|
|
||||||
margin-bottom: 0.35rem;
|
|
||||||
}
|
|
||||||
.metric-value {
|
|
||||||
font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums;
|
|
||||||
transition: color 0.3s;
|
|
||||||
}
|
|
||||||
.metric-value.positive { color: var(--green); }
|
|
||||||
.metric-value.negative { color: var(--red); }
|
|
||||||
.metric-value.neutral { color: var(--text); }
|
|
||||||
.metric-value.loading { color: var(--muted); font-size: 1rem; }
|
|
||||||
|
|
||||||
/* ── Footer ──────────────────────────────────── */
|
|
||||||
footer {
|
|
||||||
color: var(--muted); font-size: 0.75rem; text-align: center;
|
|
||||||
width: 100%; max-width: 720px;
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
padding-top: 1.25rem;
|
|
||||||
}
|
|
||||||
footer a { color: var(--accent); text-decoration: none; }
|
|
||||||
footer a:hover { text-decoration: underline; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<div class="avatar">C</div>
|
|
||||||
<h1>ChemaVX</h1>
|
|
||||||
<p class="tagline">
|
|
||||||
<span class="dot"></span>Homelab · k3s · Self-hosted
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<!-- Services -->
|
|
||||||
<div style="width:100%;max-width:720px;margin-bottom:2.5rem;">
|
|
||||||
<p class="section-title">Services</p>
|
|
||||||
<div class="services-grid">
|
|
||||||
<a class="service-card" href="https://grafana.chemavx.xyz" target="_blank" rel="noopener">
|
|
||||||
<span class="service-icon">📊</span>
|
|
||||||
<span class="service-name">Grafana</span>
|
|
||||||
</a>
|
|
||||||
<a class="service-card" href="https://n8n.chemavx.xyz" target="_blank" rel="noopener">
|
|
||||||
<span class="service-icon">⚙️</span>
|
|
||||||
<span class="service-name">n8n</span>
|
|
||||||
</a>
|
|
||||||
<a class="service-card" href="https://home.chemavx.xyz" target="_blank" rel="noopener">
|
|
||||||
<span class="service-icon">🏠</span>
|
|
||||||
<span class="service-name">Homarr</span>
|
|
||||||
</a>
|
|
||||||
<a class="service-card" href="https://polymarket.chemavx.xyz" target="_blank" rel="noopener">
|
|
||||||
<span class="service-icon">📈</span>
|
|
||||||
<span class="service-name">Polymarket Bot</span>
|
|
||||||
</a>
|
|
||||||
<a class="service-card" href="https://chat.chemavx.xyz" target="_blank" rel="noopener">
|
|
||||||
<span class="service-icon">🤖</span>
|
|
||||||
<span class="service-name">Open WebUI</span>
|
|
||||||
</a>
|
|
||||||
<a class="service-card" href="https://git.chemavx.xyz" target="_blank" rel="noopener">
|
|
||||||
<span class="service-icon">🐙</span>
|
|
||||||
<span class="service-name">Gitea</span>
|
|
||||||
</a>
|
|
||||||
<a class="service-card" href="https://argocd.chemavx.xyz" target="_blank" rel="noopener">
|
|
||||||
<span class="service-icon">🔄</span>
|
|
||||||
<span class="service-name">ArgoCD</span>
|
|
||||||
</a>
|
|
||||||
<a class="service-card" href="https://vaultwarden.chemavx.xyz" target="_blank" rel="noopener">
|
|
||||||
<span class="service-icon">🔐</span>
|
|
||||||
<span class="service-name">Vaultwarden</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Polymarket live metrics -->
|
|
||||||
<div class="poly-wrapper">
|
|
||||||
<p class="section-title">Polymarket Bot — Live</p>
|
|
||||||
<div class="poly-card">
|
|
||||||
<div class="poly-header">
|
|
||||||
<div class="poly-title">
|
|
||||||
<span>📈</span>
|
|
||||||
<span>Portfolio Summary</span>
|
|
||||||
<span class="poly-badge" id="poly-mode">PAPER</span>
|
|
||||||
</div>
|
|
||||||
<span id="poly-updated">Loading…</span>
|
|
||||||
</div>
|
|
||||||
<div class="metrics-grid">
|
|
||||||
<div class="metric">
|
|
||||||
<div class="metric-label">P&L</div>
|
|
||||||
<div class="metric-value loading" id="m-pnl">—</div>
|
|
||||||
</div>
|
|
||||||
<div class="metric">
|
|
||||||
<div class="metric-label">Win Rate</div>
|
|
||||||
<div class="metric-value loading" id="m-winrate">—</div>
|
|
||||||
</div>
|
|
||||||
<div class="metric">
|
|
||||||
<div class="metric-label">Deployed</div>
|
|
||||||
<div class="metric-value loading" id="m-deployed">—</div>
|
|
||||||
</div>
|
|
||||||
<div class="metric">
|
|
||||||
<div class="metric-label">Trades</div>
|
|
||||||
<div class="metric-value loading" id="m-trades">—</div>
|
|
||||||
</div>
|
|
||||||
<div class="metric">
|
|
||||||
<div class="metric-label">Bankroll</div>
|
|
||||||
<div class="metric-value loading" id="m-bankroll">—</div>
|
|
||||||
</div>
|
|
||||||
<div class="metric">
|
|
||||||
<div class="metric-label">Sharpe</div>
|
|
||||||
<div class="metric-value loading" id="m-sharpe">—</div>
|
|
||||||
</div>
|
|
||||||
<div class="metric">
|
|
||||||
<div class="metric-label">Calibration</div>
|
|
||||||
<div class="metric-value loading" id="m-calibration">—</div>
|
|
||||||
</div>
|
|
||||||
<div class="metric">
|
|
||||||
<div class="metric-label">Status</div>
|
|
||||||
<div class="metric-value loading" id="m-status">—</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<p>
|
|
||||||
Hosted on <strong>k3s</strong> —
|
|
||||||
<a href="https://grafana.chemavx.xyz/d/chemavx-homelab-v1/chemavx-homelab-overview" target="_blank">Cluster Dashboard</a>
|
|
||||||
— <a href="https://git.chemavx.xyz" target="_blank">Gitea</a>
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const API = 'https://polymarket.chemavx.xyz/api/summary';
|
|
||||||
const fmt$ = v => v == null ? '—' : '$' + v.toFixed(2);
|
|
||||||
const fmtPct = v => v == null ? '—' : (v * 100).toFixed(1) + '%';
|
|
||||||
const fmtN = v => v == null ? '—' : String(v);
|
|
||||||
const fmtF = (v, d=3) => v == null ? '—' : v.toFixed(d);
|
|
||||||
|
|
||||||
function colorClass(id, val) {
|
|
||||||
const el = document.getElementById(id);
|
|
||||||
el.classList.remove('positive','negative','neutral','loading');
|
|
||||||
if (val > 0) el.classList.add('positive');
|
|
||||||
else if (val < 0) el.classList.add('negative');
|
|
||||||
else el.classList.add('neutral');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchMetrics() {
|
|
||||||
try {
|
|
||||||
const r = await fetch(API, { cache: 'no-store' });
|
|
||||||
if (!r.ok) throw new Error(r.status);
|
|
||||||
const d = await r.json();
|
|
||||||
|
|
||||||
document.getElementById('m-pnl').textContent = fmt$(d.total_pnl);
|
|
||||||
document.getElementById('m-winrate').textContent = fmtPct(d.win_rate);
|
|
||||||
document.getElementById('m-deployed').textContent = fmt$(d.total_deployed);
|
|
||||||
document.getElementById('m-trades').textContent = fmtN(d.total_trades);
|
|
||||||
document.getElementById('m-bankroll').textContent = fmt$(d.paper_bankroll);
|
|
||||||
document.getElementById('m-sharpe').textContent = fmtF(d.sharpe_ratio, 2);
|
|
||||||
document.getElementById('m-calibration').textContent = fmtF(d.calibration_score, 3);
|
|
||||||
document.getElementById('m-status').textContent = d.promotion_ready ? '🚀 Ready' : '⏳ Training';
|
|
||||||
|
|
||||||
colorClass('m-pnl', d.total_pnl);
|
|
||||||
colorClass('m-sharpe', d.sharpe_ratio);
|
|
||||||
|
|
||||||
const mode = d.paper_mode ? 'PAPER' : 'LIVE';
|
|
||||||
const badge = document.getElementById('poly-mode');
|
|
||||||
badge.textContent = mode;
|
|
||||||
badge.style.background = d.paper_mode
|
|
||||||
? 'rgba(188,140,255,0.15)' : 'rgba(63,185,80,0.15)';
|
|
||||||
badge.style.color = d.paper_mode ? 'var(--purple)' : 'var(--green)';
|
|
||||||
badge.style.borderColor = d.paper_mode
|
|
||||||
? 'rgba(188,140,255,0.3)' : 'rgba(63,185,80,0.3)';
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
document.getElementById('poly-updated').textContent =
|
|
||||||
'Updated ' + now.toLocaleTimeString();
|
|
||||||
} catch (e) {
|
|
||||||
document.getElementById('poly-updated').textContent = 'Error: ' + e.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchMetrics();
|
|
||||||
setInterval(fetchMetrics, 30000);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|||||||
@@ -0,0 +1,341 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
data:
|
||||||
|
index.html: "<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n<meta charset=\"UTF-8\">\n<meta
|
||||||
|
name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>ze
|
||||||
|
— Manual · Zona de Exclusión</title>\n<link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;700&family=Syne:wght@400;700;800&display=swap\"
|
||||||
|
rel=\"stylesheet\">\n<style>\n *, *::before, *::after { box-sizing: border-box;
|
||||||
|
margin: 0; padding: 0; }\n\n :root {\n --bg: #080c10;\n --bg2: #0d1219;\n
|
||||||
|
\ --bg3: #111923;\n --border: #1e2d3d;\n --border2: #00B4D8;\n --text:
|
||||||
|
#c9d8e8;\n --muted: #4a6070;\n --accent: #00B4D8;\n --accent2: #0077a0;\n
|
||||||
|
\ --green: #39d98a;\n --amber: #f5a623;\n --red: #f05252;\n --mono:
|
||||||
|
'JetBrains Mono', monospace;\n --sans: 'Syne', sans-serif;\n }\n\n html {
|
||||||
|
scroll-behavior: smooth; }\n\n body {\n background: var(--bg);\n color:
|
||||||
|
var(--text);\n font-family: var(--mono);\n font-size: 14px;\n line-height:
|
||||||
|
1.7;\n min-height: 100vh;\n }\n\n /* Noise overlay */\n body::before {\n
|
||||||
|
\ content: '';\n position: fixed;\n inset: 0;\n background-image: url(\"data:image/svg+xml,%3Csvg
|
||||||
|
viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence
|
||||||
|
type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect
|
||||||
|
width='100%25' height='100%25' filter='url(%23noise)' opacity='0.03'/%3E%3C/svg%3E\");\n
|
||||||
|
\ pointer-events: none;\n z-index: 0;\n opacity: 0.4;\n }\n\n .container
|
||||||
|
{\n max-width: 860px;\n margin: 0 auto;\n padding: 0 24px 80px;\n position:
|
||||||
|
relative;\n z-index: 1;\n }\n\n /* Header */\n header {\n padding: 60px
|
||||||
|
0 48px;\n border-bottom: 1px solid var(--border);\n margin-bottom: 48px;\n
|
||||||
|
\ position: relative;\n }\n\n .logo-line {\n display: flex;\n align-items:
|
||||||
|
center;\n gap: 16px;\n margin-bottom: 20px;\n }\n\n .ze-badge {\n font-family:
|
||||||
|
var(--sans);\n font-size: 13px;\n font-weight: 700;\n letter-spacing:
|
||||||
|
0.15em;\n color: var(--accent);\n background: rgba(0,180,216,0.08);\n border:
|
||||||
|
1px solid rgba(0,180,216,0.3);\n padding: 4px 12px;\n text-transform: uppercase;\n
|
||||||
|
\ }\n\n .version {\n font-size: 12px;\n color: var(--muted);\n }\n\n h1
|
||||||
|
{\n font-family: var(--sans);\n font-size: clamp(32px, 5vw, 52px);\n font-weight:
|
||||||
|
800;\n color: #fff;\n line-height: 1.05;\n letter-spacing: -0.02em;\n
|
||||||
|
\ margin-bottom: 16px;\n }\n\n h1 span { color: var(--accent); }\n\n .subtitle
|
||||||
|
{\n color: var(--muted);\n font-size: 14px;\n max-width: 500px;\n }\n\n
|
||||||
|
\ .scanline {\n position: absolute;\n top: 0; right: 0;\n width: 200px;
|
||||||
|
height: 100%;\n background: linear-gradient(90deg, transparent, rgba(0,180,216,0.02));\n
|
||||||
|
\ pointer-events: none;\n }\n\n /* Nav */\n nav {\n display: flex;\n gap:
|
||||||
|
4px;\n flex-wrap: wrap;\n margin-bottom: 48px;\n padding-bottom: 24px;\n
|
||||||
|
\ border-bottom: 1px solid var(--border);\n }\n\n nav a {\n color: var(--muted);\n
|
||||||
|
\ text-decoration: none;\n font-size: 12px;\n padding: 6px 12px;\n border:
|
||||||
|
1px solid transparent;\n transition: all 0.15s;\n letter-spacing: 0.05em;\n
|
||||||
|
\ }\n\n nav a:hover {\n color: var(--accent);\n border-color: var(--border);\n
|
||||||
|
\ background: var(--bg2);\n }\n\n /* Sections */\n section {\n margin-bottom:
|
||||||
|
56px;\n animation: fadeIn 0.4s ease both;\n }\n\n @keyframes fadeIn {\n from
|
||||||
|
{ opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0);
|
||||||
|
}\n }\n\n .section-header {\n display: flex;\n align-items: center;\n
|
||||||
|
\ gap: 12px;\n margin-bottom: 28px;\n }\n\n .section-num {\n font-size:
|
||||||
|
11px;\n color: var(--accent);\n letter-spacing: 0.1em;\n opacity: 0.7;\n
|
||||||
|
\ }\n\n h2 {\n font-family: var(--sans);\n font-size: 22px;\n font-weight:
|
||||||
|
700;\n color: #fff;\n letter-spacing: -0.01em;\n }\n\n h3 {\n font-family:
|
||||||
|
var(--sans);\n font-size: 15px;\n font-weight: 700;\n color: var(--accent);\n
|
||||||
|
\ margin-bottom: 12px;\n margin-top: 28px;\n letter-spacing: 0.05em;\n
|
||||||
|
\ text-transform: uppercase;\n font-size: 12px;\n }\n\n p {\n color:
|
||||||
|
var(--text);\n margin-bottom: 16px;\n max-width: 680px;\n }\n\n /* Code
|
||||||
|
blocks */\n pre {\n background: var(--bg2);\n border: 1px solid var(--border);\n
|
||||||
|
\ border-left: 3px solid var(--accent);\n padding: 20px 24px;\n overflow-x:
|
||||||
|
auto;\n margin: 16px 0 24px;\n position: relative;\n }\n\n pre::before
|
||||||
|
{\n content: attr(data-label);\n position: absolute;\n top: 8px; right:
|
||||||
|
12px;\n font-size: 10px;\n color: var(--muted);\n letter-spacing: 0.1em;\n
|
||||||
|
\ text-transform: uppercase;\n }\n\n code {\n font-family: var(--mono);\n
|
||||||
|
\ font-size: 13px;\n color: #e2f0f8;\n }\n\n p code, li code {\n background:
|
||||||
|
rgba(0,180,216,0.08);\n border: 1px solid rgba(0,180,216,0.15);\n padding:
|
||||||
|
1px 6px;\n color: var(--accent);\n font-size: 12px;\n }\n\n /* Terminal
|
||||||
|
mockup */\n .terminal {\n background: #05080b;\n border: 1px solid var(--border);\n
|
||||||
|
\ margin: 20px 0 28px;\n }\n\n .terminal-bar {\n background: var(--bg3);\n
|
||||||
|
\ border-bottom: 1px solid var(--border);\n padding: 10px 16px;\n display:
|
||||||
|
flex;\n align-items: center;\n gap: 8px;\n }\n\n .dot { width: 10px; height:
|
||||||
|
10px; border-radius: 50%; }\n .dot-r { background: #f05252; }\n .dot-y { background:
|
||||||
|
#f5a623; }\n .dot-g { background: #39d98a; }\n\n .terminal-title {\n font-size:
|
||||||
|
11px;\n color: var(--muted);\n margin-left: 8px;\n letter-spacing: 0.05em;\n
|
||||||
|
\ }\n\n .terminal-body {\n padding: 20px 24px;\n font-size: 13px;\n line-height:
|
||||||
|
1.8;\n }\n\n .prompt { color: var(--accent); }\n .cmd { color: #fff; }\n .out-green
|
||||||
|
{ color: var(--green); }\n .out-muted { color: var(--muted); }\n .out-amber
|
||||||
|
{ color: var(--amber); }\n .out-red { color: var(--red); }\n .out-blue { color:
|
||||||
|
#60a5fa; }\n .out-white { color: #e2f0f8; }\n\n /* Tables */\n table {\n width:
|
||||||
|
100%;\n border-collapse: collapse;\n margin: 16px 0 28px;\n font-size:
|
||||||
|
13px;\n }\n\n th {\n text-align: left;\n padding: 10px 16px;\n background:
|
||||||
|
var(--bg3);\n border: 1px solid var(--border);\n color: var(--accent);\n
|
||||||
|
\ font-size: 11px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n
|
||||||
|
\ font-weight: 500;\n }\n\n td {\n padding: 10px 16px;\n border: 1px
|
||||||
|
solid var(--border);\n color: var(--text);\n vertical-align: top;\n }\n\n
|
||||||
|
\ tr:nth-child(even) td { background: rgba(255,255,255,0.01); }\n\n td:first-child
|
||||||
|
{ color: var(--accent); font-weight: 500; }\n\n /* Badges */\n .badge {\n display:
|
||||||
|
inline-block;\n padding: 2px 8px;\n font-size: 11px;\n font-weight: 700;\n
|
||||||
|
\ letter-spacing: 0.05em;\n border-radius: 2px;\n }\n\n .badge-green {
|
||||||
|
background: rgba(57,217,138,0.12); color: var(--green); border: 1px solid rgba(57,217,138,0.25);
|
||||||
|
}\n .badge-amber { background: rgba(245,166,35,0.12); color: var(--amber); border:
|
||||||
|
1px solid rgba(245,166,35,0.25); }\n .badge-red { background: rgba(240,82,82,0.12);
|
||||||
|
\ color: var(--red); border: 1px solid rgba(240,82,82,0.25); }\n\n /* Cards
|
||||||
|
*/\n .card-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit,
|
||||||
|
minmax(240px, 1fr));\n gap: 16px;\n margin: 20px 0 32px;\n }\n\n .card
|
||||||
|
{\n background: var(--bg2);\n border: 1px solid var(--border);\n padding:
|
||||||
|
20px;\n transition: border-color 0.15s;\n }\n\n .card:hover { border-color:
|
||||||
|
var(--accent2); }\n\n .card-icon {\n font-size: 20px;\n margin-bottom:
|
||||||
|
12px;\n display: block;\n }\n\n .card-title {\n font-family: var(--sans);\n
|
||||||
|
\ font-weight: 700;\n color: #fff;\n font-size: 14px;\n margin-bottom:
|
||||||
|
8px;\n }\n\n .card-desc {\n color: var(--muted);\n font-size: 12px;\n
|
||||||
|
\ line-height: 1.6;\n }\n\n /* Divider */\n .divider {\n border: none;\n
|
||||||
|
\ border-top: 1px solid var(--border);\n margin: 48px 0;\n }\n\n /* Keys
|
||||||
|
*/\n kbd {\n display: inline-block;\n background: var(--bg3);\n border:
|
||||||
|
1px solid var(--border);\n border-bottom: 2px solid var(--muted);\n padding:
|
||||||
|
2px 8px;\n font-family: var(--mono);\n font-size: 12px;\n color: #fff;\n
|
||||||
|
\ border-radius: 3px;\n }\n\n /* Scoring bars */\n .score-row {\n display:
|
||||||
|
flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 12px;\n }\n\n
|
||||||
|
\ .score-label { color: var(--text); min-width: 140px; font-size: 13px; }\n .score-pts
|
||||||
|
{ color: var(--accent); min-width: 48px; font-size: 12px; }\n\n .score-bar-bg
|
||||||
|
{\n flex: 1;\n height: 4px;\n background: var(--bg3);\n border-radius:
|
||||||
|
2px;\n overflow: hidden;\n }\n\n .score-bar {\n height: 100%;\n background:
|
||||||
|
var(--accent);\n border-radius: 2px;\n animation: grow 0.8s ease both;\n
|
||||||
|
\ }\n\n @keyframes grow { from { width: 0 !important; } }\n\n /* Footer */\n
|
||||||
|
\ footer {\n border-top: 1px solid var(--border);\n padding-top: 24px;\n
|
||||||
|
\ margin-top: 48px;\n color: var(--muted);\n font-size: 12px;\n display:
|
||||||
|
flex;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 8px;\n
|
||||||
|
\ }\n\n footer a { color: var(--accent); text-decoration: none; }\n\n /* Blinking
|
||||||
|
cursor */\n .cursor::after {\n content: '█';\n color: var(--accent);\n
|
||||||
|
\ animation: blink 1s step-end infinite;\n }\n\n @keyframes blink { 0%,100%{opacity:1}
|
||||||
|
50%{opacity:0} }\n</style>\n</head>\n<body>\n<div class=\"container\">\n\n <header>\n
|
||||||
|
\ <div class=\"scanline\"></div>\n <div class=\"logo-line\">\n <span
|
||||||
|
class=\"ze-badge\">Zona de Exclusión</span>\n <span class=\"version\">v1.0
|
||||||
|
· @ZonaDeExclusion</span>\n </div>\n <h1><span>ze</span> — Manual de instrucciones</h1>\n
|
||||||
|
\ <p class=\"subtitle\">Herramienta CLI para gestionar la presencia en X y Reddit.
|
||||||
|
Busca, puntúa y genera respuestas con IA usando el contenido del blog.</p>\n </header>\n\n
|
||||||
|
\ <nav>\n <a href=\"#instalacion\">Instalación</a>\n <a href=\"#uso-rapido\">Uso
|
||||||
|
rápido</a>\n <a href=\"#busqueda\">Modo búsqueda</a>\n <a href=\"#respuestas\">Respuestas</a>\n
|
||||||
|
\ <a href=\"#manual\">Modo manual</a>\n <a href=\"#opciones\">Opciones CLI</a>\n
|
||||||
|
\ <a href=\"#scoring\">Scoring</a>\n <a href=\"#personalizar\">Personalizar</a>\n
|
||||||
|
\ </nav>\n\n <!-- INSTALACIÓN -->\n <section id=\"instalacion\">\n <div class=\"section-header\">\n
|
||||||
|
\ <span class=\"section-num\">01</span>\n <h2>Instalación</h2>\n </div>\n\n
|
||||||
|
\ <h3>Dependencias del sistema</h3>\n <pre data-label=\"bash\"><code># Linux
|
||||||
|
X11\nsudo apt install xclip\n\n# Linux Wayland\nsudo apt install wl-clipboard</code></pre>\n\n
|
||||||
|
\ <h3>Dependencias Python</h3>\n <pre data-label=\"bash\"><code>cd ze-promote\npip
|
||||||
|
install -r requirements.txt</code></pre>\n\n <h3>Variables de entorno</h3>\n
|
||||||
|
\ <pre data-label=\"bash\"><code>cp .env.example .env\n# Edita .env con tus
|
||||||
|
claves</code></pre>\n\n <table>\n <tr><th>Variable</th><th>Necesaria</th><th>Para
|
||||||
|
qué</th></tr>\n <tr><td>ANTHROPIC_API_KEY</td><td>Sí</td><td>Generar respuestas
|
||||||
|
con Claude</td></tr>\n <tr><td>GETX_API_KEY</td><td>No</td><td>Búsquedas
|
||||||
|
en X/Twitter. Sin ella solo funciona Reddit</td></tr>\n </table>\n\n <h3>Instalar
|
||||||
|
el comando ze</h3>\n <pre data-label=\"bash\"><code>bash install.sh\nsource
|
||||||
|
~/.bashrc # o ~/.zshrc si usas zsh</code></pre>\n <p>Crea el alias <code>ze</code>
|
||||||
|
en tu shell y el ejecutable <code>/usr/local/bin/ze</code>. Después puedes usar
|
||||||
|
<code>ze</code> desde cualquier directorio.</p>\n </section>\n\n <hr class=\"divider\">\n\n
|
||||||
|
\ <!-- USO RÁPIDO -->\n <section id=\"uso-rapido\">\n <div class=\"section-header\">\n
|
||||||
|
\ <span class=\"section-num\">02</span>\n <h2>Uso rápido</h2>\n </div>\n\n
|
||||||
|
\ <div class=\"card-grid\">\n <div class=\"card\">\n <span class=\"card-icon\">\U0001F50D</span>\n
|
||||||
|
\ <div class=\"card-title\">Búsqueda automática</div>\n <div class=\"card-desc\">Busca
|
||||||
|
en X y Reddit, puntúa resultados y genera respuestas.</div>\n </div>\n <div
|
||||||
|
class=\"card\">\n <span class=\"card-icon\">✍️</span>\n <div class=\"card-title\">Modo
|
||||||
|
manual</div>\n <div class=\"card-desc\">Pega cualquier tweet o post para
|
||||||
|
generar una respuesta directamente.</div>\n </div>\n <div class=\"card\">\n
|
||||||
|
\ <span class=\"card-icon\">⚙️</span>\n <div class=\"card-title\">Flexible</div>\n
|
||||||
|
\ <div class=\"card-desc\">Filtra por fuente, limita resultados o desactiva
|
||||||
|
Twitter si no tienes clave.</div>\n </div>\n </div>\n\n <div class=\"terminal\">\n
|
||||||
|
\ <div class=\"terminal-bar\">\n <div class=\"dot dot-r\"></div><div
|
||||||
|
class=\"dot dot-y\"></div><div class=\"dot dot-g\"></div>\n <span class=\"terminal-title\">chemavx@chemavx-k8</span>\n
|
||||||
|
\ </div>\n <div class=\"terminal-body\">\n <div><span class=\"prompt\">$
|
||||||
|
</span><span class=\"cmd\">ze</span></div>\n <div><span class=\"prompt\">$
|
||||||
|
</span><span class=\"cmd\">ze --manual</span></div>\n <div><span class=\"prompt\">$
|
||||||
|
</span><span class=\"cmd\">ze --no-twitter</span></div>\n <div><span class=\"prompt\">$
|
||||||
|
</span><span class=\"cmd\">ze --limit 10</span></div>\n <div><span class=\"prompt\">$
|
||||||
|
</span><span class=\"cmd\">ze --help</span><span class=\"cursor\"></span></div>\n
|
||||||
|
\ </div>\n </div>\n </section>\n\n <hr class=\"divider\">\n\n <!-- MODO
|
||||||
|
BÚSQUEDA -->\n <section id=\"busqueda\">\n <div class=\"section-header\">\n
|
||||||
|
\ <span class=\"section-num\">03</span>\n <h2>Modo búsqueda</h2>\n </div>\n\n
|
||||||
|
\ <p>Al arrancar sin flags, el programa hace tres cosas automáticamente:</p>\n\n
|
||||||
|
\ <div class=\"terminal\">\n <div class=\"terminal-bar\">\n <div
|
||||||
|
class=\"dot dot-r\"></div><div class=\"dot dot-y\"></div><div class=\"dot dot-g\"></div>\n
|
||||||
|
\ <span class=\"terminal-title\">ze — arranque</span>\n </div>\n <div
|
||||||
|
class=\"terminal-body\">\n <div><span class=\"prompt\">$ </span><span class=\"cmd\">ze</span></div>\n
|
||||||
|
\ <br>\n <div><span class=\"out-muted\">── Zona de Exclusión — Promotion
|
||||||
|
Tool ──</span></div>\n <br>\n <div><span class=\"out-green\">✓</span>
|
||||||
|
<span class=\"out-white\">9 artículos del blog cargados</span> <span class=\"out-muted\">|</span>
|
||||||
|
\ <span class=\"out-white\">68 resultados encontrados</span></div>\n </div>\n
|
||||||
|
\ </div>\n\n <h3>La tabla de resultados</h3>\n <p>Cada resultado muestra:
|
||||||
|
score, recomendación automática, fuente, autor, preview del contenido, estadísticas
|
||||||
|
y fecha.</p>\n\n <div class=\"terminal\">\n <div class=\"terminal-bar\">\n
|
||||||
|
\ <div class=\"dot dot-r\"></div><div class=\"dot dot-y\"></div><div class=\"dot
|
||||||
|
dot-g\"></div>\n <span class=\"terminal-title\">tabla de resultados</span>\n
|
||||||
|
\ </div>\n <div class=\"terminal-body\" style=\"overflow-x:auto\">\n
|
||||||
|
\ <div><span class=\"out-muted\"># Score Acción Src Autor
|
||||||
|
\ Stats Fecha</span></div>\n <div><span class=\"out-white\">1
|
||||||
|
\ 78 </span><span class=\"out-green\">✅ Responder</span><span class=\"out-white\">
|
||||||
|
\ r/UFOs u/uap_tracker ↑312 \U0001F4AC7 16/05 09:00</span></div>\n
|
||||||
|
\ <div><span class=\"out-white\">2 53 </span><span class=\"out-green\">✅
|
||||||
|
Responder</span><span class=\"out-white\"> \U0001D54F @DocAlienista ♥5.5K
|
||||||
|
\U0001F4AC8 \U0001F501589 13/05 18:57</span></div>\n <div><span class=\"out-white\">3
|
||||||
|
\ 45 </span><span class=\"out-amber\">⚠️ Opcional</span><span class=\"out-white\">
|
||||||
|
\ r/UFOs u/someone ↑60 \U0001F4AC24 15/05 19:11</span></div>\n
|
||||||
|
\ <div><span class=\"out-white\">4 22 </span><span class=\"out-red\">❌
|
||||||
|
Saltar </span><span class=\"out-white\"> r/UFOs u/another ↑5 \U0001F4AC199
|
||||||
|
\ 15/05 16:08</span></div>\n </div>\n </div>\n\n <h3>Recomendación
|
||||||
|
automática</h3>\n <table>\n <tr><th>Indicador</th><th>Condición</th><th>Por
|
||||||
|
qué</th></tr>\n <tr>\n <td><span class=\"badge badge-green\">✅ Responder</span></td>\n
|
||||||
|
\ <td>Score ≥ 40 y < 15 comentarios</td>\n <td>Poca competencia,
|
||||||
|
buena visibilidad garantizada</td>\n </tr>\n <tr>\n <td><span
|
||||||
|
class=\"badge badge-amber\">⚠️ Opcional</span></td>\n <td>Score ≥ 40 y
|
||||||
|
15-80 comentarios</td>\n <td>Puede merecer la pena si el contenido encaja
|
||||||
|
muy bien</td>\n </tr>\n <tr>\n <td><span class=\"badge badge-red\">❌
|
||||||
|
Saltar</span></td>\n <td>Score < 40, >80 comentarios o post de opinión</td>\n
|
||||||
|
\ <td>Demasiado ruido o sin contexto factual para responder</td>\n </tr>\n
|
||||||
|
\ </table>\n\n <p style=\"color: var(--muted); font-size: 12px;\">Los posts
|
||||||
|
de opinión (\"what do you think\", \"¿qué pensáis?\", \"debate\", \"CMV\"…) se
|
||||||
|
descartan automáticamente.</p>\n\n <h3>Navegar por los resultados</h3>\n <p>Tras
|
||||||
|
la tabla, el programa muestra cada post con su panel de detalle:</p>\n\n <div
|
||||||
|
class=\"terminal\">\n <div class=\"terminal-bar\">\n <div class=\"dot
|
||||||
|
dot-r\"></div><div class=\"dot dot-y\"></div><div class=\"dot dot-g\"></div>\n
|
||||||
|
\ <span class=\"terminal-title\">panel de detalle</span>\n </div>\n
|
||||||
|
\ <div class=\"terminal-body\">\n <div><span class=\"out-muted\">╭──
|
||||||
|
Reddit r/UFOs ● 78 pts u/uap_tracker 1/15 ──╮</span></div>\n <div><span
|
||||||
|
class=\"out-muted\">│ </span><span class=\"out-white\">Pentagon releases new UAP
|
||||||
|
footage from 2023 </span><span class=\"out-muted\">│</span></div>\n <div><span
|
||||||
|
class=\"out-muted\">│ │</span></div>\n
|
||||||
|
\ <div><span class=\"out-muted\">│ </span><span class=\"out-muted\">↑ 312
|
||||||
|
upvotes | \U0001F4AC 7 comentarios · 16/05 09:00 </span><span class=\"out-muted\">│</span></div>\n
|
||||||
|
\ <div><span class=\"out-muted\">│ </span><span class=\"out-blue\">https://reddit.com/r/UFOs/comments/abc123/
|
||||||
|
\ </span><span class=\"out-muted\">│</span></div>\n <div><span class=\"out-muted\">│
|
||||||
|
\ │</span></div>\n <div><span
|
||||||
|
class=\"out-muted\">│ </span><span class=\"out-white\">Recomendación: </span><span
|
||||||
|
class=\"out-green\">✅ Responder </span><span class=\"out-muted\">│</span></div>\n
|
||||||
|
\ <div><span class=\"out-muted\">╰───────────────────────────────────────────────────╯</span></div>\n
|
||||||
|
\ <div><span class=\"out-white\">Acción (R/S/Q): </span><span class=\"cursor\"></span></div>\n
|
||||||
|
\ </div>\n </div>\n\n <table>\n <tr><th>Tecla</th><th>Acción</th></tr>\n
|
||||||
|
\ <tr><td><kbd>r</kbd></td><td>Generar respuesta con Claude</td></tr>\n <tr><td><kbd>s</kbd></td><td>Saltar
|
||||||
|
al siguiente resultado</td></tr>\n <tr><td><kbd>q</kbd></td><td>Salir</td></tr>\n
|
||||||
|
\ </table>\n </section>\n\n <hr class=\"divider\">\n\n <!-- RESPUESTAS -->\n
|
||||||
|
\ <section id=\"respuestas\">\n <div class=\"section-header\">\n <span
|
||||||
|
class=\"section-num\">04</span>\n <h2>Generación de respuestas</h2>\n </div>\n\n
|
||||||
|
\ <p>Al pulsar <kbd>r</kbd>, Claude genera una respuesta teniendo en cuenta:</p>\n
|
||||||
|
\ <ul style=\"margin: 0 0 20px 20px; color: var(--text); line-height: 2;\">\n
|
||||||
|
\ <li>El texto del post o tweet completo</li>\n <li>Los artículos publicados
|
||||||
|
en el blog (busca si alguno es relevante para incluir su link)</li>\n <li>El
|
||||||
|
idioma del post — responde en inglés si el post es en inglés, en español si es
|
||||||
|
en español</li>\n <li>El límite de 240 caracteres para X</li>\n </ul>\n\n
|
||||||
|
\ <div class=\"terminal\">\n <div class=\"terminal-bar\">\n <div
|
||||||
|
class=\"dot dot-r\"></div><div class=\"dot dot-y\"></div><div class=\"dot dot-g\"></div>\n
|
||||||
|
\ <span class=\"terminal-title\">respuesta generada</span>\n </div>\n
|
||||||
|
\ <div class=\"terminal-body\">\n <div><span class=\"out-muted\">╭───
|
||||||
|
Respuesta generada ──────────────────────────────╮</span></div>\n <div><span
|
||||||
|
class=\"out-muted\">│ </span><span class=\"out-white\">Ruppelt dirigió Blue Book
|
||||||
|
1951-53, su etapa más </span><span class=\"out-muted\">│</span></div>\n <div><span
|
||||||
|
class=\"out-muted\">│ </span><span class=\"out-white\">activa. Un briefing clasificado
|
||||||
|
del 52 sería </span><span class=\"out-muted\">│</span></div>\n <div><span
|
||||||
|
class=\"out-muted\">│ </span><span class=\"out-white\">historia UAP fundamental.
|
||||||
|
30 días para saberlo. </span><span class=\"out-muted\">│</span></div>\n <div><span
|
||||||
|
class=\"out-muted\">│ │</span></div>\n
|
||||||
|
\ <div><span class=\"out-muted\">│ </span><span class=\"out-green\">187/240
|
||||||
|
caracteres ✓ </span><span class=\"out-muted\">│</span></div>\n
|
||||||
|
\ <div><span class=\"out-muted\">╰─────────────────────────────────────────────────────╯</span></div>\n
|
||||||
|
\ <div><span class=\"out-white\">Respuesta (C/E/S): </span><span class=\"cursor\"></span></div>\n
|
||||||
|
\ </div>\n </div>\n\n <table>\n <tr><th>Tecla</th><th>Acción</th></tr>\n
|
||||||
|
\ <tr><td><kbd>c</kbd></td><td>Copiar al portapapeles</td></tr>\n <tr><td><kbd>e</kbd></td><td>Editar
|
||||||
|
inline antes de copiar</td></tr>\n <tr><td><kbd>s</kbd></td><td>Descartar
|
||||||
|
y pasar al siguiente</td></tr>\n </table>\n\n <h3>URL de destino</h3>\n
|
||||||
|
\ <p>Tras copiar, el programa muestra exactamente dónde pegar la respuesta:</p>\n\n
|
||||||
|
\ <div class=\"terminal\">\n <div class=\"terminal-bar\">\n <div
|
||||||
|
class=\"dot dot-r\"></div><div class=\"dot dot-y\"></div><div class=\"dot dot-g\"></div>\n
|
||||||
|
\ <span class=\"terminal-title\">url de destino</span>\n </div>\n <div
|
||||||
|
class=\"terminal-body\">\n <div><span class=\"out-green\">✓ Copiado al
|
||||||
|
portapapeles</span></div>\n <br>\n <div><span class=\"out-muted\">╭──────────────────────────────────────────────────╮</span></div>\n
|
||||||
|
\ <div><span class=\"out-muted\">│ </span><span class=\"out-white\">→ Pega
|
||||||
|
tu respuesta aquí: </span><span class=\"out-muted\">│</span></div>\n
|
||||||
|
\ <div><span class=\"out-muted\">│ </span><span class=\"out-blue\">https://reddit.com/r/UFOs/comments/abc123/
|
||||||
|
\ </span><span class=\"out-muted\">│</span></div>\n <div><span class=\"out-muted\">╰──────────────────────────────────────────────────╯</span></div>\n
|
||||||
|
\ </div>\n </div>\n\n <h3>Links automáticos del blog</h3>\n <p>Claude
|
||||||
|
compara el tema concreto del post con los artículos publicados. Si hay solapamiento
|
||||||
|
real, incluye la URL del artículo de forma natural. Si no hay coincidencia precisa,
|
||||||
|
no incluye ningún link — una respuesta sin link es mejor que un link forzado.</p>\n
|
||||||
|
\ </section>\n\n <hr class=\"divider\">\n\n <!-- MODO MANUAL -->\n <section
|
||||||
|
id=\"manual\">\n <div class=\"section-header\">\n <span class=\"section-num\">05</span>\n
|
||||||
|
\ <h2>Modo manual</h2>\n </div>\n\n <p>Para cuando encuentras algo interesante
|
||||||
|
navegando manualmente — como cuando alguien te manda una captura de pantalla.</p>\n\n
|
||||||
|
\ <pre data-label=\"bash\"><code>ze --manual\n# o\nze -m</code></pre>\n\n <div
|
||||||
|
class=\"terminal\">\n <div class=\"terminal-bar\">\n <div class=\"dot
|
||||||
|
dot-r\"></div><div class=\"dot dot-y\"></div><div class=\"dot dot-g\"></div>\n
|
||||||
|
\ <span class=\"terminal-title\">flujo manual</span>\n </div>\n <div
|
||||||
|
class=\"terminal-body\">\n <div><span class=\"prompt\">$ </span><span class=\"cmd\">ze
|
||||||
|
--manual</span></div>\n <br>\n <div><span class=\"out-muted\">Pega
|
||||||
|
el texto del tweet o post (línea vacía para terminar):</span></div>\n <div><span
|
||||||
|
class=\"out-white\">Estados Unidos desclasifica 162 archivos UAP...</span></div>\n
|
||||||
|
\ <div><span class=\"out-white\">[línea vacía]</span></div>\n <br>\n
|
||||||
|
\ <div><span class=\"out-muted\">Fuente (t=Twitter, r=Reddit): </span><span
|
||||||
|
class=\"out-white\">t</span></div>\n <br>\n <div><span class=\"out-muted\">Generando
|
||||||
|
respuesta…</span></div>\n </div>\n </div>\n </section>\n\n <hr class=\"divider\">\n\n
|
||||||
|
\ <!-- OPCIONES CLI -->\n <section id=\"opciones\">\n <div class=\"section-header\">\n
|
||||||
|
\ <span class=\"section-num\">06</span>\n <h2>Opciones de línea de comandos</h2>\n
|
||||||
|
\ </div>\n\n <table>\n <tr><th>Flag</th><th>Descripción</th><th>Ejemplo</th></tr>\n
|
||||||
|
\ <tr><td>(sin flags)</td><td>Búsqueda completa en X y Reddit</td><td><code>ze</code></td></tr>\n
|
||||||
|
\ <tr><td><code>--manual, -m</code></td><td>Pega texto directamente para generar
|
||||||
|
respuesta</td><td><code>ze -m</code></td></tr>\n <tr><td><code>--no-twitter</code></td><td>Omitir
|
||||||
|
búsquedas en X/Twitter</td><td><code>ze --no-twitter</code></td></tr>\n <tr><td><code>--no-reddit</code></td><td>Omitir
|
||||||
|
búsquedas en Reddit</td><td><code>ze --no-reddit</code></td></tr>\n <tr><td><code>--limit
|
||||||
|
N, -n N</code></td><td>Mostrar solo los N mejores resultados</td><td><code>ze
|
||||||
|
-n 10</code></td></tr>\n <tr><td><code>--help</code></td><td>Mostrar ayuda</td><td><code>ze
|
||||||
|
--help</code></td></tr>\n </table>\n\n <pre data-label=\"ejemplos\"><code>ze
|
||||||
|
--no-twitter # solo Reddit, útil sin GETX_API_KEY\nze --limit 15 #
|
||||||
|
ver solo el top 15\nze -m # modo manual\nze --no-reddit --limit
|
||||||
|
5 # solo los 5 mejores tweets</code></pre>\n </section>\n\n <hr class=\"divider\">\n\n
|
||||||
|
\ <!-- SCORING -->\n <section id=\"scoring\">\n <div class=\"section-header\">\n
|
||||||
|
\ <span class=\"section-num\">07</span>\n <h2>Algoritmo de scoring</h2>\n
|
||||||
|
\ </div>\n\n <p>Cada resultado recibe una puntuación de 0 a 100 basada en
|
||||||
|
cuatro criterios:</p>\n\n <div style=\"margin: 24px 0 32px;\">\n <div
|
||||||
|
class=\"score-row\">\n <span class=\"score-label\">Engagement</span>\n
|
||||||
|
\ <span class=\"score-pts\">0–40 pts</span>\n <div class=\"score-bar-bg\"><div
|
||||||
|
class=\"score-bar\" style=\"width:40%\"></div></div>\n </div>\n <div
|
||||||
|
class=\"score-row\">\n <span class=\"score-label\">Recencia</span>\n <span
|
||||||
|
class=\"score-pts\">0–30 pts</span>\n <div class=\"score-bar-bg\"><div
|
||||||
|
class=\"score-bar\" style=\"width:30%; animation-delay:0.1s\"></div></div>\n </div>\n
|
||||||
|
\ <div class=\"score-row\">\n <span class=\"score-label\">Idioma español</span>\n
|
||||||
|
\ <span class=\"score-pts\">0–20 pts</span>\n <div class=\"score-bar-bg\"><div
|
||||||
|
class=\"score-bar\" style=\"width:20%; animation-delay:0.2s\"></div></div>\n </div>\n
|
||||||
|
\ <div class=\"score-row\">\n <span class=\"score-label\">Competencia
|
||||||
|
baja</span>\n <span class=\"score-pts\">0–10 pts</span>\n <div class=\"score-bar-bg\"><div
|
||||||
|
class=\"score-bar\" style=\"width:10%; animation-delay:0.3s\"></div></div>\n </div>\n
|
||||||
|
\ </div>\n\n <table>\n <tr><th>Criterio</th><th>Puntos</th><th>Detalle</th></tr>\n
|
||||||
|
\ <tr><td>Engagement</td><td>0–40</td><td>Likes + upvotes en escala logarítmica</td></tr>\n
|
||||||
|
\ <tr><td>Recencia</td><td>0–30</td><td><6h → 30 · <24h → 22 · <48h
|
||||||
|
→ 12 · <72h → 5</td></tr>\n <tr><td>Idioma español</td><td>0–20</td><td>Detectado
|
||||||
|
por palabras clave en el texto</td></tr>\n <tr><td>Competencia baja</td><td>0–10</td><td>0
|
||||||
|
replies → 10 · <5 → 7 · <15 → 4 · <40 → 1</td></tr>\n </table>\n\n
|
||||||
|
\ <p style=\"color: var(--muted); font-size: 12px;\">Tweets con cero engagement
|
||||||
|
en las tres métricas (likes, replies y retweets todos por debajo del umbral mínimo)
|
||||||
|
se descartan antes de puntuar.</p>\n </section>\n\n <hr class=\"divider\">\n\n
|
||||||
|
\ <!-- PERSONALIZAR -->\n <section id=\"personalizar\">\n <div class=\"section-header\">\n
|
||||||
|
\ <span class=\"section-num\">08</span>\n <h2>Personalizar búsquedas</h2>\n
|
||||||
|
\ </div>\n\n <p>Edita <code>ze_promote/sources.py</code> para cambiar las
|
||||||
|
queries y subreddits:</p>\n\n <pre data-label=\"sources.py\"><code># Queries
|
||||||
|
para X/Twitter (texto plano, sin operadores avanzados)\nTWITTER_QUERIES = [\n
|
||||||
|
\ \"UAP OVNI desclasificacion 2026\",\n \"OVNI España avistamiento\",\n \"UAP
|
||||||
|
disclosure Pentagon\",\n]\n\n# Subreddits y queries para Reddit\nREDDIT_SEARCHES
|
||||||
|
= [\n (\"UFOs\", \"UAP\"),\n (\"HighStrangeness\", \"UAP\"),\n (\"conspiracyespanol\",
|
||||||
|
\"OVNI\"),\n (\"es\", \"OVNI avistamiento\"),\n # añade más: (\"subreddit\",
|
||||||
|
\"query\")\n]</code></pre>\n\n <h3>Estructura del proyecto</h3>\n <pre data-label=\"árbol\"><code>ze-promote/\n├──
|
||||||
|
install.sh # Instalador del comando ze\n├── main.py # Punto
|
||||||
|
de entrada CLI\n├── ze_promote/\n│ ├── scraper.py # Scraping de zonadeexclusion.com\n│
|
||||||
|
\ ├── sources.py # Búsqueda en X y Reddit\n│ ├── scorer.py # Algoritmo
|
||||||
|
de scoring 0-100\n│ ├── responder.py # Generación de respuestas con Claude\n│
|
||||||
|
\ └── ui.py # Interfaz Rich (tabla, paneles, prompts)\n├── requirements.txt\n├──
|
||||||
|
.env.example\n└── README.md</code></pre>\n </section>\n\n <footer>\n <span>ze
|
||||||
|
· Zona de Exclusión · <a href=\"https://zonadeexclusion.com\">zonadeexclusion.com</a></span>\n
|
||||||
|
\ <span>@ZonaDeExclusion · v1.0</span>\n </footer>\n\n</div>\n</body>\n</html>\n"
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: ze-manual-html
|
||||||
|
namespace: portfolio
|
||||||
@@ -21,6 +21,8 @@ spec:
|
|||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: html
|
- name: html
|
||||||
mountPath: /usr/share/nginx/html
|
mountPath: /usr/share/nginx/html
|
||||||
|
- name: ze-html
|
||||||
|
mountPath: /usr/share/nginx/html/ze
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /
|
path: /
|
||||||
@@ -38,3 +40,6 @@ spec:
|
|||||||
- name: html
|
- name: html
|
||||||
configMap:
|
configMap:
|
||||||
name: portfolio-html
|
name: portfolio-html
|
||||||
|
- name: ze-html
|
||||||
|
configMap:
|
||||||
|
name: ze-manual-html
|
||||||
|
|||||||
Reference in New Issue
Block a user