From d0d4a9cc46225c5f76d89eac88c32ff9afe796d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Thu, 4 Jun 2026 20:19:58 +0700 Subject: [PATCH 01/34] Fix static app smoke checks and chat escaping --- .github/workflows/hadolint.yml | 2 +- .github/workflows/static.yml | 3 +++ README.md | 24 ++++++++++++++------ index.html | 2 +- scripts/smoke-test-static.mjs | 41 ++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 scripts/smoke-test-static.mjs diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml index dc73566..a264df3 100644 --- a/.github/workflows/hadolint.yml +++ b/.github/workflows/hadolint.yml @@ -2,7 +2,7 @@ # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. -# hadoint is a Dockerfile linter written in Haskell +# hadolint is a Dockerfile linter written in Haskell # that helps you build best practice Docker images. # More details at https://github.com/hadolint/hadolint diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 09631a2..8e55f57 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -22,6 +22,9 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Smoke test static app + run: node scripts/smoke-test-static.mjs + - name: Prepare static site shell: bash run: | diff --git a/README.md b/README.md index 91f1766..704c5d9 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ RKIX3/ ├─ index.html # Single-file AI Studio UI ├─ README.md # Trang giới thiệu chuyên nghiệp trên GitHub +├─ scripts/smoke-test-static.mjs # Smoke test HTML/JS trước khi deploy ├─ 1780136894650-Photoroom.png # Logo chính └─ .github/workflows/static.yml # Build _site + deploy GitHub Pages ``` @@ -66,17 +67,26 @@ python3 -m http.server 4173 # mở http://127.0.0.1:4173 ``` +## 🧪 Kiểm thử + +```bash +node scripts/smoke-test-static.mjs +``` + +Smoke test sẽ kiểm tra cấu trúc route chính, sự tồn tại của chat input/send button, cú pháp JavaScript inline và guard chống render raw user message vào `innerHTML`. + ## 🚀 Deploy GitHub Pages -Workflow `.github/workflows/static.yml` sẽ: +Workflow chính `.github/workflows/static.yml` sẽ: 1. Checkout source. -2. Setup GitHub Pages. -3. Tạo `_site` chứa `index.html`, ảnh và file đánh dấu static site. -4. Upload artifact Pages. -5. Deploy bằng `actions/deploy-pages`. +2. Chạy smoke test static app bằng `node scripts/smoke-test-static.mjs`. +3. Setup GitHub Pages. +4. Tạo `_site` chứa `index.html`, ảnh và file đánh dấu static site. +5. Upload artifact Pages. +6. Deploy bằng `actions/deploy-pages`. -> Nếu GitHub vẫn báo lỗi deploy, hãy vào **Settings → Pages → Build and deployment** và chọn **Source: GitHub Actions** cho repository. +> Nếu GitHub vẫn báo lỗi deploy, hãy vào **Settings → Pages → Build and deployment** và chọn **Source: GitHub Actions** cho repository. Các workflow mẫu khác trong `.github/workflows/` chỉ nên được bật khi dự án thật sự dùng stack tương ứng. ## 🏅 Huy hiệu dự án @@ -121,7 +131,7 @@ Workflow `.github/workflows/static.yml` sẽ: ## ✅ Ba xung đột đã được chốt -- **Workflow Pages**: chỉ giữ một pipeline static ở `.github/workflows/static.yml`, dùng `_site` làm artifact triển khai. +- **Workflow Pages**: `.github/workflows/static.yml` là pipeline deploy chính, chạy smoke test rồi dùng `_site` làm artifact triển khai. - **Tài liệu GitHub**: README là trang giới thiệu chính thức của RKIX3, không còn nội dung cũ trùng lặp. - **Web app RKIX3**: `index.html` tiếp tục là nguồn giao diện single-file được workflow copy trực tiếp khi deploy. diff --git a/index.html b/index.html index 12bb580..af17760 100644 --- a/index.html +++ b/index.html @@ -103,7 +103,7 @@ function taskCard(t){return `
${t.id}${t.priority}

${t.title}

${t.project}

`} function renderHome(){$('#home').innerHTML=`

Developer Workspace Platform

Build faster with AI, projects, code, docs, and deploys in one command deck.

RKIX3 combines an AI workspace, project roadmap, code studio, build center, library hub, integrations, and profile controls in a sleek dark-first developer UI.

${card(`

Live agent stream

${badge('AI Online')}

✓ Indexed 3 snippets into Code Studio

→ Generated deploy plan for Vercel + GitHub

● Monitoring 4 active projects

`)}
${metric('Active projects',entities.projects.length)}${metric('Open tasks',entities.tasks.filter(t=>t.status!=='done').length)}${metric('Code snippets',entities.snippets.length)}${metric('Integrations','8')}
${card(`

Project pulse

Roadmap-ready entities with progress, owners, and delivery status.

${entities.projects.map(projectCard).join('')}
`)}`} function renderAI(){$('#ai').innerHTML=`

AI Workspace

Chat interface with an AI agent, mode switcher, and prompt accelerators.

${badge('Agent Ready')}
${['Generate code','Debug issue','Plan sprint','Write docs'].map(x=>``).join('')}
${card(`

AI Tools

${['Code generator','Task decomposer','Release note writer','Security reviewer','API schema planner'].map((x,i)=>``).join('')}
`)}
`; renderChat()} -function renderChat(){$('#chatLog').innerHTML=entities.messages.map(m=>`
${m.role==='user'?'YOU':'RKIX3 AGENT'}

${m.text}

`).join('')} +function renderChat(){$('#chatLog').innerHTML=entities.messages.map(m=>`
${m.role==='user'?'YOU':'RKIX3 AGENT'}

${esc(m.text)}

`).join('')} function renderWorkspace(){const cols=[['todo','Todo'],['doing','In progress'],['review','Review'],['done','Done']];$('#workspace').innerHTML=`${card(`

Project & Task Management

Kanban board, project list, and roadmap planning view.

${badge('6 tasks')}
${cols.map(([k,l])=>`

${l}

${entities.tasks.filter(t=>t.status===k).map(taskCard).join('')}
`).join('')}
`)}
${card(`

Projects List

${entities.projects.map(p=>`
${p.name}

${p.owner} · ${p.stack} · ${p.due}

`).join('')}
`)}${card(`

Roadmap View

${entities.projects.map(p=>`
${p.name}
${p.due}
`).join('')}`)}
`} function renderCode(){$('#code').innerHTML=`

Code Studio

Editor surface with snippets, templates, and AI coding actions.

${esc(entities.snippets[0].code)}
${card(`

Snippets Manager

${entities.snippets.map(s=>``).join('')}

AI Coding

${['Explain','Refactor','Test','Optimize'].map(x=>``).join('')}
`)}
${card(`

Code Templates

${['Next.js API route','Express worker','Astro docs site'].map(x=>`

${x}

Starter files, env notes, and test checklist.

`).join('')}
`)}`} function renderBuild(){const f=['Next.js','Vite React','Astro','SvelteKit','Node API','Static HTML'];$('#build').innerHTML=card(`

Build Center

Create, configure, and queue builds across common frameworks.

${f.map((x,i)=>`
${badge(i%2?'Template':'Ready')}

${x}

Includes scripts, env schema, CI hints, and deployment presets.

`).join('')}
`)} diff --git a/scripts/smoke-test-static.mjs b/scripts/smoke-test-static.mjs new file mode 100644 index 0000000..6b82bd4 --- /dev/null +++ b/scripts/smoke-test-static.mjs @@ -0,0 +1,41 @@ +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { spawnSync } from 'node:child_process'; + +const html = readFileSync('index.html', 'utf8'); +const failures = []; + +function assert(condition, message) { + if (!condition) failures.push(message); +} + +assert(html.includes(''), 'index.html must declare an HTML doctype.'); +assert(html.includes('
${m.text}

'), 'Chat messages must not render raw user text into innerHTML.'); + +const scripts = [...html.matchAll(/]*)?>([\s\S]*?)<\/script>/gi)].map((match) => match[1]); +assert(scripts.length > 0, 'index.html must include an inline script to validate.'); + +if (scripts.length > 0) { + const workDir = mkdtempSync(join(tmpdir(), 'rkix3-smoke-')); + const scriptPath = join(workDir, 'index-inline-script.js'); + writeFileSync(scriptPath, scripts.join('\n'), 'utf8'); + const result = spawnSync(process.execPath, ['--check', scriptPath], { encoding: 'utf8' }); + if (result.status !== 0) { + failures.push(`Inline JavaScript failed syntax check:\n${result.stderr || result.stdout}`); + } + rmSync(workDir, { recursive: true, force: true }); +} + +if (failures.length > 0) { + console.error('Static smoke test failed:'); + for (const failure of failures) console.error(`- ${failure}`); + process.exit(1); +} + +console.log('Static smoke test passed.'); From 3a00a9782d11c0a1d686c64aa5c0e105a70753e1 Mon Sep 17 00:00:00 2001 From: v0agent Date: Thu, 4 Jun 2026 14:42:36 +0000 Subject: [PATCH 02/34] feat: adjust sidebar width and nav button styles; update header padding and h1 font size; reduce shell max-width and card padding; modify hero layout and button hover effect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- index.html | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/index.html b/index.html index af17760..3d54c44 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,8 @@ --line: rgba(255,255,255,.11); --line-strong: rgba(0,210,255,.38); --text: #f7fbff; --muted: #a5afc2; --faint: #657189; --cyan: #00d2ff; --blue: #4f7cff; --violet: #8b5cf6; --lime: #9cff6e; --amber: #fbbf24; - --shadow: 0 24px 80px rgba(0,0,0,.36); --radius: 28px; + --ai: #00d2ff; --ai-dark: #0088aa; + --shadow: 0 24px 80px rgba(0,0,0,.36); --radius: 16px; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } * { box-sizing: border-box; } @@ -28,40 +29,40 @@ button, input { font: inherit; } button { cursor: pointer; } .app { position: relative; min-height: 100vh; } - .sidebar { position: fixed; inset: 0 auto 0 0; width: 280px; z-index: 20; padding: 20px; display: flex; flex-direction: column; justify-content: space-between; border-right: 1px solid var(--line); background: rgba(8,13,27,.86); backdrop-filter: blur(20px); } + .sidebar { position: fixed; inset: 0 auto 0 0; width: 240px; z-index: 20; padding: 16px; display: flex; flex-direction: column; justify-content: space-between; border-right: 1px solid var(--line); background: rgba(8,13,27,.86); backdrop-filter: blur(20px); } .brand { border: 0; background: transparent; padding: 0; display: flex; align-items: center; margin-bottom: 28px; } .brand img { height: 52px; filter: drop-shadow(0 0 22px rgba(0,210,255,.45)); } .new-session { width: 100%; padding: 14px; margin-bottom: 18px; border: 1px solid rgba(0,210,255,.24); border-radius: 20px; color: var(--text); background: rgba(0,210,255,.09); text-align: left; font-weight: 800; } .nav { display: grid; gap: 8px; } - .nav-btn { width: 100%; display: flex; align-items: center; gap: 12px; padding: 12px 13px; color: var(--muted); background: transparent; border: 1px solid transparent; border-radius: 18px; transition: .2s ease; text-align: left; } - .nav-btn:hover, .nav-btn.active { color: white; border-color: var(--line-strong); background: linear-gradient(90deg, rgba(79,124,255,.22), rgba(0,210,255,.08)); } + .nav-btn { width: 100%; display: flex; align-items: center; gap: 10px; padding: 10px 12px; color: var(--muted); background: transparent; border: 1px solid transparent; border-radius: 24px; transition: .2s ease; text-align: left; font-size: 14px; } + .nav-btn:hover, .nav-btn.active { color: white; border-color: var(--ai); background: linear-gradient(90deg, rgba(0,210,255,.15), rgba(0,210,255,.05)); box-shadow: inset 0 0 24px rgba(0,210,255,.1); } .capacity { border: 1px solid var(--line); border-radius: 24px; padding: 16px; background: rgba(255,255,255,.04); color: var(--muted); font-size: 12px; } .bar { height: 8px; border-radius: 99px; overflow: hidden; background: rgba(255,255,255,.1); margin: 10px 0; } .bar > span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--cyan), var(--violet)); } - main { margin-left: 280px; min-height: 100vh; padding-bottom: 40px; } - header { position: relative; z-index: 10; padding: 18px 32px; border-bottom: 1px solid var(--line); background: rgba(8,13,27,.78); backdrop-filter: blur(18px); display: flex; align-items: center; justify-content: space-between; gap: 18px; } + main { margin-left: 240px; min-height: 100vh; padding-bottom: 40px; } + header { position: relative; z-index: 10; padding: 14px 24px; border-bottom: 1px solid var(--line); background: rgba(8,13,27,.78); backdrop-filter: blur(18px); display: flex; align-items: center; justify-content: space-between; gap: 14px; } .eyebrow { margin: 0 0 4px; color: var(--cyan); font-size: 11px; font-weight: 900; letter-spacing: .32em; text-transform: uppercase; } h1, h2, h3, h4, p { margin-top: 0; } - h1 { margin: 0; font-size: clamp(24px, 3vw, 34px); letter-spacing: -.04em; } + h1 { margin: 0; font-size: clamp(20px, 2.5vw, 28px); letter-spacing: -.04em; } .top-actions { display: flex; gap: 12px; align-items: center; } .branch { border: 1px solid var(--line); border-radius: 16px; background: rgba(0,0,0,.22); color: var(--muted); padding: 10px 12px; font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 12px; } - .shell { max-width: 1500px; padding: 28px 32px; margin: 0 auto; display: grid; gap: 22px; } + .shell { max-width: 1400px; padding: 20px 24px; margin: 0 auto; display: grid; gap: 18px; } .page { display: none; animation: rise .28s ease-out both; } .page.active { display: grid; gap: 22px; } @keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } - .card { border: 1px solid var(--line); border-radius: var(--radius); background: linear-gradient(145deg, var(--panel), rgba(10,16,32,.66)); box-shadow: var(--shadow); backdrop-filter: blur(18px); padding: 24px; } - .hero { min-height: 560px; display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(320px, .8fr); gap: 22px; } - .hero-copy { position: relative; overflow: hidden; padding: 56px 36px 36px; display: flex; flex-direction: column; justify-content: flex-start; } + .card { border: 1px solid var(--line); border-radius: 20px; background: linear-gradient(145deg, var(--panel), rgba(10,16,32,.66)); box-shadow: var(--shadow); backdrop-filter: blur(18px); padding: 20px; } + .hero { min-height: 480px; display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(280px, .8fr); gap: 18px; } + .hero-copy { position: relative; overflow: hidden; padding: 40px 28px 28px; display: flex; flex-direction: column; justify-content: flex-start; } .hero-copy::after { content: ""; position: absolute; right: -80px; top: -80px; width: 280px; height: 280px; border-radius: 999px; background: rgba(0,210,255,.13); filter: blur(14px); } .hero h2 { position: relative; z-index: 1; margin: 14px 0 18px; font-size: clamp(38px, 5.4vw, 66px); line-height: 1.02; letter-spacing: -.07em; } .lead { color: var(--muted); font-size: 18px; line-height: 1.65; max-width: 760px; } .row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; } - .btn { border: 1px solid var(--line); border-radius: 17px; background: rgba(255,255,255,.05); color: var(--text); padding: 12px 16px; font-weight: 900; transition: .2s ease; } - .btn:hover { transform: translateY(-1px); border-color: var(--line-strong); } - .btn.primary { color: #06111c; background: var(--cyan); border-color: var(--cyan); } + .btn { border: 1px solid var(--line); border-radius: 20px; background: rgba(255,255,255,.05); color: var(--text); padding: 10px 14px; font-weight: 900; transition: .2s ease; font-size: 13px; } + .btn:hover { transform: translateY(-1px); border-color: var(--ai); background: rgba(0,210,255,.08); } + .btn.primary { color: #06111c; background: linear-gradient(135deg, var(--ai), #00a8cc); border-color: var(--ai); box-shadow: 0 8px 24px rgba(0,210,255,.25); } .badge { display: inline-flex; align-items: center; gap: 6px; border: 1px solid rgba(0,210,255,.25); border-radius: 999px; background: rgba(0,210,255,.1); color: var(--cyan); padding: 6px 10px; font-size: 11px; font-weight: 900; } .grid { display: grid; gap: 16px; } .cols-2 { grid-template-columns: repeat(2, minmax(0,1fr)); } .cols-3 { grid-template-columns: repeat(3, minmax(0,1fr)); } .cols-4 { grid-template-columns: repeat(4, minmax(0,1fr)); } .metric strong { display: block; margin-top: 8px; font-size: 34px; letter-spacing: -.05em; } .muted { color: var(--muted); } .faint { color: var(--faint); } - .project, .mini-card, .task { border: 1px solid var(--line); border-radius: 22px; background: rgba(255,255,255,.04); padding: 18px; transition: .2s ease; } + .project, .mini-card, .task { border: 1px solid var(--line); border-radius: 20px; background: rgba(255,255,255,.04); padding: 16px; transition: .2s ease; } .project:hover, .mini-card:hover, .task:hover { border-color: var(--line-strong); transform: translateY(-1px); } .code { font-family: "JetBrains Mono", ui-monospace, monospace; white-space: pre-wrap; color: #c8d7ff; background: #050813; border-radius: 0 0 var(--radius) var(--radius); padding: 22px; min-height: 520px; overflow: auto; line-height: 1.7; } .window-head { border-bottom: 1px solid var(--line); padding: 18px 22px; display: flex; align-items: center; justify-content: space-between; } @@ -73,7 +74,8 @@ .roadmap-row { display: grid; grid-template-columns: 170px 1fr 80px; gap: 14px; align-items: center; margin: 12px 0; } .bottom-nav, .drawer, .mobile-menu { display: none; } @media (max-width: 1100px) { .cols-4 { grid-template-columns: repeat(2,1fr); } .cols-3 { grid-template-columns: repeat(2,1fr); } .hero { grid-template-columns: 1fr; } } - @media (max-width: 860px) { .sidebar { display:none; } main { margin-left:0; } header { padding: 15px; } .shell { padding: 16px; } .top-actions { display:none; } .mobile-menu { display:block; } .cols-2,.cols-3,.cols-4 { grid-template-columns: 1fr; } .hero-copy { padding: 24px; } .bottom-nav { display:grid; position:fixed; bottom:0; inset-inline:0; z-index:30; grid-template-columns:repeat(5,1fr); gap:4px; padding:8px; border-top:1px solid var(--line); background:rgba(8,13,27,.92); backdrop-filter:blur(18px); } .bottom-nav .nav-btn { justify-content:center; font-size:11px; padding:10px 4px; } .drawer.open { display:block; position:fixed; inset:0; z-index:40; background:rgba(0,0,0,.68); } .drawer-panel { width:min(84vw,320px); height:100%; padding:20px; background:rgba(8,13,27,.95); border-right:1px solid var(--line); } } + @media (max-width: 1100px) { .sidebar { width: 200px; } main { margin-left: 200px; } } + @media (max-width: 860px) { .sidebar { display:none; } main { margin-left:0; } header { padding: 12px 16px; } .shell { padding: 14px 16px; } .top-actions { display:none; } .mobile-menu { display:block; } .cols-2,.cols-3,.cols-4 { grid-template-columns: 1fr; } .hero { grid-template-columns: 1fr; min-height: 320px; } .hero-copy { padding: 20px 18px 18px; } .hero h2 { font-size: clamp(28px, 4vw, 40px); } .card { padding: 16px; border-radius: 18px; } .bottom-nav { display:grid; position:fixed; bottom:0; inset-inline:0; z-index:30; grid-template-columns:repeat(5,1fr); gap:3px; padding:6px; border-top:1px solid var(--line); background:rgba(8,13,27,.92); backdrop-filter:blur(18px); } .bottom-nav .nav-btn { justify-content:center; font-size:10px; padding:8px 3px; border-radius: 18px; } .drawer.open { display:block; position:fixed; inset:0; z-index:40; background:rgba(0,0,0,.68); } .drawer-panel { width:min(84vw,280px); height:100%; padding:16px; background:rgba(8,13,27,.95); border-right:1px solid var(--line); } } @@ -94,7 +96,7 @@ status text default 'planning', created_at timestamptz default now() );`}],messages:[{role:'agent',text:'RKIX3 Agent online. I can turn goals into code, tasks, docs, deploy plans, and reusable snippets.'},{role:'user',text:'Create a typed API route for generating release notes.'},{role:'agent',text:'I drafted the route, validation schema, test plan, and deployment checklist. Want a Next.js or Express version?'}]}; -const routes=[['home','Dashboard','⌘'],['ai','AI Workspace','✦'],['workspace','Projects','▦'],['code','Code Studio','{}'],['build','Build Center','▲'],['library','Library Hub','▤'],['integrations','Integrations','⚡'],['profile','Profile','◉']]; +const routes=[['home','Dashboard','🏠'],['ai','AI Workspace','🤖'],['workspace','Projects','📊'],['code','Code Studio','document.querySelector(s), $$=s=>[...document.querySelectorAll(s)], esc=s=>String(s).replace(/[&<>'"]/g,c=>({'&':'&','<':'<','>':'>',"'":''','"':'"'}[c])); const card=(inner,cls='')=>`
${inner}
`, badge=t=>`${t}`; function navHTML(short=false){return routes.filter(r=>!short||['home','ai','workspace','code','profile'].includes(r[0])).map(r=>``).join('')} From 5303b38d567ee0f079fb9321e3b3457e5154ffdb Mon Sep 17 00:00:00 2001 From: v0agent Date: Thu, 4 Jun 2026 14:47:49 +0000 Subject: [PATCH 03/34] feat: adjust sidebar width, padding, and main margin; update button styles and hero section layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- index.html | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/index.html b/index.html index 3d54c44..84b6d08 100644 --- a/index.html +++ b/index.html @@ -12,8 +12,7 @@ --line: rgba(255,255,255,.11); --line-strong: rgba(0,210,255,.38); --text: #f7fbff; --muted: #a5afc2; --faint: #657189; --cyan: #00d2ff; --blue: #4f7cff; --violet: #8b5cf6; --lime: #9cff6e; --amber: #fbbf24; - --ai: #00d2ff; --ai-dark: #0088aa; - --shadow: 0 24px 80px rgba(0,0,0,.36); --radius: 16px; + --shadow: 0 24px 80px rgba(0,0,0,.36); --radius: 28px; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } * { box-sizing: border-box; } @@ -29,40 +28,40 @@ button, input { font: inherit; } button { cursor: pointer; } .app { position: relative; min-height: 100vh; } - .sidebar { position: fixed; inset: 0 auto 0 0; width: 240px; z-index: 20; padding: 16px; display: flex; flex-direction: column; justify-content: space-between; border-right: 1px solid var(--line); background: rgba(8,13,27,.86); backdrop-filter: blur(20px); } + .sidebar { position: fixed; inset: 0 auto 0 0; width: 280px; z-index: 20; padding: 20px; display: flex; flex-direction: column; justify-content: space-between; border-right: 1px solid var(--line); background: rgba(8,13,27,.86); backdrop-filter: blur(20px); } .brand { border: 0; background: transparent; padding: 0; display: flex; align-items: center; margin-bottom: 28px; } .brand img { height: 52px; filter: drop-shadow(0 0 22px rgba(0,210,255,.45)); } .new-session { width: 100%; padding: 14px; margin-bottom: 18px; border: 1px solid rgba(0,210,255,.24); border-radius: 20px; color: var(--text); background: rgba(0,210,255,.09); text-align: left; font-weight: 800; } .nav { display: grid; gap: 8px; } - .nav-btn { width: 100%; display: flex; align-items: center; gap: 10px; padding: 10px 12px; color: var(--muted); background: transparent; border: 1px solid transparent; border-radius: 24px; transition: .2s ease; text-align: left; font-size: 14px; } - .nav-btn:hover, .nav-btn.active { color: white; border-color: var(--ai); background: linear-gradient(90deg, rgba(0,210,255,.15), rgba(0,210,255,.05)); box-shadow: inset 0 0 24px rgba(0,210,255,.1); } + .nav-btn { width: 100%; display: flex; align-items: center; gap: 12px; padding: 12px 13px; color: var(--muted); background: transparent; border: 1px solid transparent; border-radius: 18px; transition: .2s ease; text-align: left; } + .nav-btn:hover, .nav-btn.active { color: white; border-color: var(--line-strong); background: linear-gradient(90deg, rgba(79,124,255,.22), rgba(0,210,255,.08)); } .capacity { border: 1px solid var(--line); border-radius: 24px; padding: 16px; background: rgba(255,255,255,.04); color: var(--muted); font-size: 12px; } .bar { height: 8px; border-radius: 99px; overflow: hidden; background: rgba(255,255,255,.1); margin: 10px 0; } .bar > span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--cyan), var(--violet)); } - main { margin-left: 240px; min-height: 100vh; padding-bottom: 40px; } - header { position: relative; z-index: 10; padding: 14px 24px; border-bottom: 1px solid var(--line); background: rgba(8,13,27,.78); backdrop-filter: blur(18px); display: flex; align-items: center; justify-content: space-between; gap: 14px; } + main { margin-left: 280px; min-height: 100vh; padding-bottom: 40px; } + header { position: relative; z-index: 10; padding: 18px 32px; border-bottom: 1px solid var(--line); background: rgba(8,13,27,.78); backdrop-filter: blur(18px); display: flex; align-items: center; justify-content: space-between; gap: 18px; } .eyebrow { margin: 0 0 4px; color: var(--cyan); font-size: 11px; font-weight: 900; letter-spacing: .32em; text-transform: uppercase; } h1, h2, h3, h4, p { margin-top: 0; } - h1 { margin: 0; font-size: clamp(20px, 2.5vw, 28px); letter-spacing: -.04em; } + h1 { margin: 0; font-size: clamp(24px, 3vw, 34px); letter-spacing: -.04em; } .top-actions { display: flex; gap: 12px; align-items: center; } .branch { border: 1px solid var(--line); border-radius: 16px; background: rgba(0,0,0,.22); color: var(--muted); padding: 10px 12px; font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 12px; } - .shell { max-width: 1400px; padding: 20px 24px; margin: 0 auto; display: grid; gap: 18px; } + .shell { max-width: 1500px; padding: 28px 32px; margin: 0 auto; display: grid; gap: 22px; } .page { display: none; animation: rise .28s ease-out both; } .page.active { display: grid; gap: 22px; } @keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } - .card { border: 1px solid var(--line); border-radius: 20px; background: linear-gradient(145deg, var(--panel), rgba(10,16,32,.66)); box-shadow: var(--shadow); backdrop-filter: blur(18px); padding: 20px; } - .hero { min-height: 480px; display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(280px, .8fr); gap: 18px; } - .hero-copy { position: relative; overflow: hidden; padding: 40px 28px 28px; display: flex; flex-direction: column; justify-content: flex-start; } + .card { border: 1px solid var(--line); border-radius: var(--radius); background: linear-gradient(145deg, var(--panel), rgba(10,16,32,.66)); box-shadow: var(--shadow); backdrop-filter: blur(18px); padding: 24px; } + .hero { min-height: 560px; display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(320px, .8fr); gap: 22px; } + .hero-copy { position: relative; overflow: hidden; padding: 56px 36px 36px; display: flex; flex-direction: column; justify-content: flex-start; } .hero-copy::after { content: ""; position: absolute; right: -80px; top: -80px; width: 280px; height: 280px; border-radius: 999px; background: rgba(0,210,255,.13); filter: blur(14px); } .hero h2 { position: relative; z-index: 1; margin: 14px 0 18px; font-size: clamp(38px, 5.4vw, 66px); line-height: 1.02; letter-spacing: -.07em; } .lead { color: var(--muted); font-size: 18px; line-height: 1.65; max-width: 760px; } .row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; } - .btn { border: 1px solid var(--line); border-radius: 20px; background: rgba(255,255,255,.05); color: var(--text); padding: 10px 14px; font-weight: 900; transition: .2s ease; font-size: 13px; } - .btn:hover { transform: translateY(-1px); border-color: var(--ai); background: rgba(0,210,255,.08); } - .btn.primary { color: #06111c; background: linear-gradient(135deg, var(--ai), #00a8cc); border-color: var(--ai); box-shadow: 0 8px 24px rgba(0,210,255,.25); } + .btn { border: 1px solid var(--line); border-radius: 17px; background: rgba(255,255,255,.05); color: var(--text); padding: 12px 16px; font-weight: 900; transition: .2s ease; } + .btn:hover { transform: translateY(-1px); border-color: var(--line-strong); } + .btn.primary { color: #06111c; background: var(--cyan); border-color: var(--cyan); } .badge { display: inline-flex; align-items: center; gap: 6px; border: 1px solid rgba(0,210,255,.25); border-radius: 999px; background: rgba(0,210,255,.1); color: var(--cyan); padding: 6px 10px; font-size: 11px; font-weight: 900; } .grid { display: grid; gap: 16px; } .cols-2 { grid-template-columns: repeat(2, minmax(0,1fr)); } .cols-3 { grid-template-columns: repeat(3, minmax(0,1fr)); } .cols-4 { grid-template-columns: repeat(4, minmax(0,1fr)); } .metric strong { display: block; margin-top: 8px; font-size: 34px; letter-spacing: -.05em; } .muted { color: var(--muted); } .faint { color: var(--faint); } - .project, .mini-card, .task { border: 1px solid var(--line); border-radius: 20px; background: rgba(255,255,255,.04); padding: 16px; transition: .2s ease; } + .project, .mini-card, .task { border: 1px solid var(--line); border-radius: 22px; background: rgba(255,255,255,.04); padding: 18px; transition: .2s ease; } .project:hover, .mini-card:hover, .task:hover { border-color: var(--line-strong); transform: translateY(-1px); } .code { font-family: "JetBrains Mono", ui-monospace, monospace; white-space: pre-wrap; color: #c8d7ff; background: #050813; border-radius: 0 0 var(--radius) var(--radius); padding: 22px; min-height: 520px; overflow: auto; line-height: 1.7; } .window-head { border-bottom: 1px solid var(--line); padding: 18px 22px; display: flex; align-items: center; justify-content: space-between; } @@ -73,9 +72,7 @@ .kanban { grid-template-columns: repeat(4, minmax(220px,1fr)); align-items: start; overflow-x: auto; } .lane { border: 1px solid var(--line); border-radius: 24px; background: rgba(0,0,0,.18); padding: 14px; min-height: 360px; } .roadmap-row { display: grid; grid-template-columns: 170px 1fr 80px; gap: 14px; align-items: center; margin: 12px 0; } .bottom-nav, .drawer, .mobile-menu { display: none; } - @media (max-width: 1100px) { .cols-4 { grid-template-columns: repeat(2,1fr); } .cols-3 { grid-template-columns: repeat(2,1fr); } .hero { grid-template-columns: 1fr; } } - @media (max-width: 1100px) { .sidebar { width: 200px; } main { margin-left: 200px; } } - @media (max-width: 860px) { .sidebar { display:none; } main { margin-left:0; } header { padding: 12px 16px; } .shell { padding: 14px 16px; } .top-actions { display:none; } .mobile-menu { display:block; } .cols-2,.cols-3,.cols-4 { grid-template-columns: 1fr; } .hero { grid-template-columns: 1fr; min-height: 320px; } .hero-copy { padding: 20px 18px 18px; } .hero h2 { font-size: clamp(28px, 4vw, 40px); } .card { padding: 16px; border-radius: 18px; } .bottom-nav { display:grid; position:fixed; bottom:0; inset-inline:0; z-index:30; grid-template-columns:repeat(5,1fr); gap:3px; padding:6px; border-top:1px solid var(--line); background:rgba(8,13,27,.92); backdrop-filter:blur(18px); } .bottom-nav .nav-btn { justify-content:center; font-size:10px; padding:8px 3px; border-radius: 18px; } .drawer.open { display:block; position:fixed; inset:0; z-index:40; background:rgba(0,0,0,.68); } .drawer-panel { width:min(84vw,280px); height:100%; padding:16px; background:rgba(8,13,27,.95); border-right:1px solid var(--line); } } + @media (max-width: 860px) { .sidebar { display:none; } main { margin-left:0; } header { padding: 15px; } .shell { padding: 16px; } .top-actions { display:none; } .mobile-menu { display:block; } .cols-2,.cols-3,.cols-4 { grid-template-columns: 1fr; } .hero-copy { padding: 24px; } .bottom-nav { display:grid; position:fixed; bottom:0; inset-inline:0; z-index:30; grid-template-columns:repeat(5,1fr); gap:4px; padding:8px; border-top:1px solid var(--line); background:rgba(8,13,27,.92); backdrop-filter:blur(18px); } .bottom-nav .nav-btn { justify-content:center; font-size:11px; padding:10px 4px; } .drawer.open { display:block; position:fixed; inset:0; z-index:40; background:rgba(0,0,0,.68); } .drawer-panel { width:min(84vw,320px); height:100%; padding:20px; background:rgba(8,13,27,.95); border-right:1px solid var(--line); } } @@ -96,7 +93,7 @@ status text default 'planning', created_at timestamptz default now() );`}],messages:[{role:'agent',text:'RKIX3 Agent online. I can turn goals into code, tasks, docs, deploy plans, and reusable snippets.'},{role:'user',text:'Create a typed API route for generating release notes.'},{role:'agent',text:'I drafted the route, validation schema, test plan, and deployment checklist. Want a Next.js or Express version?'}]}; -const routes=[['home','Dashboard','🏠'],['ai','AI Workspace','🤖'],['workspace','Projects','📊'],['code','Code Studio','document.querySelector(s), $$=s=>[...document.querySelectorAll(s)], esc=s=>String(s).replace(/[&<>'"]/g,c=>({'&':'&','<':'<','>':'>',"'":''','"':'"'}[c])); const card=(inner,cls='')=>`
${inner}
`, badge=t=>`${t}`; function navHTML(short=false){return routes.filter(r=>!short||['home','ai','workspace','code','profile'].includes(r[0])).map(r=>``).join('')} From 91df86d07b08da3949c1122022a847dea5143a31 Mon Sep 17 00:00:00 2001 From: v0agent Date: Thu, 4 Jun 2026 15:17:29 +0000 Subject: [PATCH 04/34] feat: update index.html for Vietnamese language and dark mode support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- index.html | 723 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 610 insertions(+), 113 deletions(-) diff --git a/index.html b/index.html index 84b6d08..0eecbd1 100644 --- a/index.html +++ b/index.html @@ -1,118 +1,615 @@ - + - - - RKIX3 — Developer Workspace Platform - - + + + RKIX3 AI - Lập trình, Code, Build, Tự động hoá + + + + + + - -
- -

RKIX3 Command Layer

Dashboard

main · healthy
-
RKIX3
-
- + + + + + + +
+ + + + + + + + + + + + +
+ + +
+
+ + +
+ +
+ + +
+
+ + +
+ + +
+
+ RKIX3 Logo +
+ +

+ Chúng ta nên bắt đầu từ đâu? +

+
+ + +
+
+ + +
+ + +
+ + +
+
+
+
+ + + + + +
+
+
+ +
+

Lập trình

+

Viết code, debug và tối ưu hóa hệ thống

+
+ +
+
+ +
+

Build

+

Xây dựng sản phẩm nhanh chóng

+
+ +
+
+ +
+

Tự động hoá

+

Tự động hoá quy trình và công việc

+
+ +
+
+ +
+

AI thông minh

+

Hỗ trợ bởi AI thế hệ mới

+
+
+ +
+ +
+ + + + + + +
+ + + + + + + + + +
+ + Hệ thống thông báo! +
+ + + + + From 92dc466d86d3adb0ca7f2e89cad9166211a40352 Mon Sep 17 00:00:00 2001 From: v0agent Date: Thu, 4 Jun 2026 15:27:11 +0000 Subject: [PATCH 05/34] feat: enhance mobile navigation bar styling and padding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- index.html | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/index.html b/index.html index 0eecbd1..71fbb17 100644 --- a/index.html +++ b/index.html @@ -150,7 +150,7 @@ -
+
@@ -259,26 +259,26 @@

AI thông minh

- From 424e6fa41e588a90c9d6f30ea2e6af623fc60757 Mon Sep 17 00:00:00 2001 From: "anthropic-code-agent[bot]" <242468646+Claude@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:33:37 +0000 Subject: [PATCH 06/34] Initial plan From 188fc313f02b7ac3747bdbeaa304cc935cd74d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Thu, 4 Jun 2026 23:36:25 +0700 Subject: [PATCH 07/34] Delete CNAME --- CNAME | 1 - 1 file changed, 1 deletion(-) delete mode 100644 CNAME diff --git a/CNAME b/CNAME deleted file mode 100644 index 2037010..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -app.github.rkix \ No newline at end of file From 9403f84220854fb6bd8bc0f916600649628123f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Thu, 4 Jun 2026 23:44:09 +0700 Subject: [PATCH 08/34] updete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5990d9c..a3ea994 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ version: 2 updates: - - package-ecosystem: "" # See documentation for possible values + - package-ecosystem: "github-actions" directory: "/" # Location of package manifests schedule: interval: "weekly" From 543de9e2056f7e5dc034ed92d1125bcdbc8158e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Thu, 4 Jun 2026 23:44:49 +0700 Subject: [PATCH 09/34] Update .github/workflows/terraform.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 540e804..714064a 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -89,5 +89,5 @@ jobs: # On push to "main", build or change infrastructure according to Terraform configuration files # Note: It is recommended to set up a required "strict" status check in your repository for "Terraform Cloud". See the documentation on "strict" required status checks for more information: https://help.github.com/en/github/administering-a-repository/types-of-required-status-checks - name: Terraform Apply - if: github.ref == 'refs/heads/"main"' && github.event_name == 'push' + if: github.ref == 'refs/heads/main' && github.event_name == 'push' run: terraform apply -auto-approve -input=false From 833ae3e0820471af2076c67001d2f89cd7a8dae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Thu, 4 Jun 2026 23:45:01 +0700 Subject: [PATCH 10/34] Update .github/workflows/jscrambler-code-integrity.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- .github/workflows/jscrambler-code-integrity.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/jscrambler-code-integrity.yml b/.github/workflows/jscrambler-code-integrity.yml index 893d5bf..a646cd3 100644 --- a/.github/workflows/jscrambler-code-integrity.yml +++ b/.github/workflows/jscrambler-code-integrity.yml @@ -31,8 +31,13 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 20 - - run: npm ci - - run: npm run build + - run: | + if [ -f package.json ]; then + npm ci + npm run build + else + echo "Skipping npm build: package.json not found" + fi - name: Jscrambler Code Integrity id: jscrambler # the complete list of inputs can be found here: https://github.com/marketplace/actions/jscrambler#inputs From e7ee1f302705cebb1c0e6bb5ab10de6ac34eb5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Thu, 4 Jun 2026 23:45:17 +0700 Subject: [PATCH 11/34] Update .github/workflows/google.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- .github/workflows/google.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/google.yml b/.github/workflows/google.yml index 0b5c7d1..508e9fd 100644 --- a/.github/workflows/google.yml +++ b/.github/workflows/google.yml @@ -103,7 +103,8 @@ jobs: # Set up kustomize - name: 'Set up Kustomize' run: |- - curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.4.3/kustomize_v5.4.3_linux_amd64.tar.gz + curl -sfL https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.4.3/kustomize_v5.4.3_linux_amd64.tar.gz | tar -xz + chmod u+x ./kustomize chmod u+x ./kustomize # Deploy the Docker image to the GKE cluster From cca38a8420fc2a8d04b8ebb939bbee3c4747ba47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Thu, 4 Jun 2026 23:45:48 +0700 Subject: [PATCH 12/34] Update CNAME MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- CNAME | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CNAME b/CNAME index 2037010..c1536c0 100644 --- a/CNAME +++ b/CNAME @@ -1 +1 @@ -app.github.rkix \ No newline at end of file +app.github.io \ No newline at end of file From f7fa8180825bf265c6017349356d96e622b0527f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Thu, 4 Jun 2026 23:46:02 +0700 Subject: [PATCH 13/34] Update index.html MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 71fbb17..f81f91a 100644 --- a/index.html +++ b/index.html @@ -474,7 +474,7 @@

Date: Sat, 6 Jun 2026 08:41:05 +0000 Subject: [PATCH 14/34] Initial plan From ca90042016a2f61a7a48d0d0d59e1fe861dfd6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=E1=BB=B3nh=20Th=C6=B0=C6=A1ng?= <252359928+Huynhthuongg@users.noreply.github.com> Date: Sat, 6 Jun 2026 17:44:28 +0700 Subject: [PATCH 15/34] Rename sonarcloud.yml to sonarcloud.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> From 85e6ecf2759f6ba88ce5e727b594bacc5e7c6c06 Mon Sep 17 00:00:00 2001 From: v0agent Date: Sat, 6 Jun 2026 18:21:23 +0000 Subject: [PATCH 16/34] feat: update dependabot, streamline kustomize setup, enhance jscrambler workflow, fix terraform apply condition, rename CNAME, add miniRkx floating button styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- .github/dependabot.yml | 2 +- .github/workflows/google.yml | 3 +- .../workflows/jscrambler-code-integrity.yml | 9 +- .github/workflows/terraform.yml | 2 +- CNAME | 2 +- index.html | 328 +++++++++++++++++- 6 files changed, 333 insertions(+), 13 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a3ea994..5990d9c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ version: 2 updates: - - package-ecosystem: "github-actions" + - package-ecosystem: "" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" diff --git a/.github/workflows/google.yml b/.github/workflows/google.yml index 508e9fd..0b5c7d1 100644 --- a/.github/workflows/google.yml +++ b/.github/workflows/google.yml @@ -103,8 +103,7 @@ jobs: # Set up kustomize - name: 'Set up Kustomize' run: |- - curl -sfL https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.4.3/kustomize_v5.4.3_linux_amd64.tar.gz | tar -xz - chmod u+x ./kustomize + curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.4.3/kustomize_v5.4.3_linux_amd64.tar.gz chmod u+x ./kustomize # Deploy the Docker image to the GKE cluster diff --git a/.github/workflows/jscrambler-code-integrity.yml b/.github/workflows/jscrambler-code-integrity.yml index a646cd3..893d5bf 100644 --- a/.github/workflows/jscrambler-code-integrity.yml +++ b/.github/workflows/jscrambler-code-integrity.yml @@ -31,13 +31,8 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 20 - - run: | - if [ -f package.json ]; then - npm ci - npm run build - else - echo "Skipping npm build: package.json not found" - fi + - run: npm ci + - run: npm run build - name: Jscrambler Code Integrity id: jscrambler # the complete list of inputs can be found here: https://github.com/marketplace/actions/jscrambler#inputs diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 714064a..540e804 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -89,5 +89,5 @@ jobs: # On push to "main", build or change infrastructure according to Terraform configuration files # Note: It is recommended to set up a required "strict" status check in your repository for "Terraform Cloud". See the documentation on "strict" required status checks for more information: https://help.github.com/en/github/administering-a-repository/types-of-required-status-checks - name: Terraform Apply - if: github.ref == 'refs/heads/main' && github.event_name == 'push' + if: github.ref == 'refs/heads/"main"' && github.event_name == 'push' run: terraform apply -auto-approve -input=false diff --git a/CNAME b/CNAME index c1536c0..2037010 100644 --- a/CNAME +++ b/CNAME @@ -1 +1 @@ -app.github.io \ No newline at end of file +app.github.rkix \ No newline at end of file diff --git a/index.html b/index.html index f81f91a..ebfec66 100644 --- a/index.html +++ b/index.html @@ -46,6 +46,206 @@ -ms-overflow-style: none; scrollbar-width: none; } + + /* ========== MiniRkx Floating Button Styles ========== */ + .minirkx-button { + position: fixed; + bottom: 32px; + right: 32px; + width: 72px; + height: 72px; + border-radius: 18px; + background: linear-gradient(135deg, #0052cc 0%, #00d2ff 100%); + border: 2px solid rgba(0, 210, 255, 0.4); + z-index: 35; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 0 24px rgba(0, 210, 255, 0.3), 0 8px 32px rgba(0, 82, 204, 0.2); + user-select: none; + -webkit-user-select: none; + } + + .minirkx-button:hover { + transform: scale(1.08); + box-shadow: 0 0 32px rgba(0, 210, 255, 0.5), 0 12px 48px rgba(0, 82, 204, 0.3); + border-color: rgba(0, 210, 255, 0.6); + } + + .minirkx-button:active { + transform: scale(0.95); + } + + .minirkx-button.open { + transform: rotate(45deg); + } + + .minirkx-logo { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + } + + .minirkx-logo svg { + width: 100%; + height: 100%; + filter: drop-shadow(0 0 8px rgba(0, 210, 255, 0.4)); + } + + /* Pulsing glow animation */ + @keyframes minirkx-pulse-glow { + 0%, 100% { + box-shadow: 0 0 24px rgba(0, 210, 255, 0.3), 0 8px 32px rgba(0, 82, 204, 0.2); + } + 50% { + box-shadow: 0 0 36px rgba(0, 210, 255, 0.5), 0 12px 48px rgba(0, 82, 204, 0.35); + } + } + + .minirkx-button.pulse { + animation: minirkx-pulse-glow 2s ease-in-out infinite; + } + + /* ========== Honeycomb Menu ========== */ + .minirkx-menu { + position: fixed; + inset: 0; + z-index: 30; + pointer-events: none; + opacity: 0; + transition: opacity 0.3s ease; + } + + .minirkx-menu.open { + pointer-events: auto; + opacity: 1; + } + + .minirkx-menu-backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0); + transition: background 0.3s ease; + cursor: pointer; + } + + .minirkx-menu.open .minirkx-menu-backdrop { + background: rgba(0, 0, 0, 0.4); + } + + .minirkx-honeycomb { + position: absolute; + bottom: 32px; + right: 32px; + width: 360px; + height: 360px; + display: flex; + align-items: center; + justify-content: center; + } + + .minirkx-hex-item { + position: absolute; + width: 80px; + height: 80px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + opacity: 0; + transform: scale(0) translate(0, 0); + transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); + } + + .minirkx-menu.open .minirkx-hex-item { + opacity: 1; + transform: scale(1) translate(var(--tx), var(--ty)); + } + + .minirkx-hex-item:nth-child(1) { --tx: 0px; --ty: -90px; transition-delay: 0.05s; } + .minirkx-hex-item:nth-child(2) { --tx: 78px; --ty: -45px; transition-delay: 0.1s; } + .minirkx-hex-item:nth-child(3) { --tx: 78px; --ty: 45px; transition-delay: 0.15s; } + .minirkx-hex-item:nth-child(4) { --tx: 0px; --ty: 90px; transition-delay: 0.2s; } + .minirkx-hex-item:nth-child(5) { --tx: -78px; --ty: 45px; transition-delay: 0.25s; } + .minirkx-hex-item:nth-child(6) { --tx: -78px; --ty: -45px; transition-delay: 0.3s; } + + .minirkx-hex-content { + width: 100%; + height: 100%; + border-radius: 12px; + background: linear-gradient(135deg, rgba(0, 82, 204, 0.8) 0%, rgba(0, 210, 255, 0.8) 100%); + border: 2px solid rgba(0, 210, 255, 0.4); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 6px; + transition: all 0.3s ease; + box-shadow: 0 4px 16px rgba(0, 82, 204, 0.2); + user-select: none; + -webkit-user-select: none; + } + + .minirkx-hex-item:hover .minirkx-hex-content { + transform: scale(1.12); + border-color: rgba(0, 210, 255, 0.8); + box-shadow: 0 8px 32px rgba(0, 210, 255, 0.4); + background: linear-gradient(135deg, rgba(0, 82, 204, 1) 0%, rgba(0, 210, 255, 1) 100%); + } + + .minirkx-hex-icon { + font-size: 24px; + line-height: 1; + } + + .minirkx-hex-label { + font-size: 10px; + font-weight: 700; + color: white; + text-align: center; + letter-spacing: 0.5px; + text-transform: uppercase; + } + + @media (max-width: 768px) { + .minirkx-button { + width: 64px; + height: 64px; + bottom: 24px; + right: 24px; + } + + .minirkx-honeycomb { + width: 280px; + height: 280px; + bottom: 24px; + right: 24px; + } + + .minirkx-hex-item:nth-child(1) { --tx: 0px; --ty: -70px; } + .minirkx-hex-item:nth-child(2) { --tx: 60px; --ty: -35px; } + .minirkx-hex-item:nth-child(3) { --tx: 60px; --ty: 35px; } + .minirkx-hex-item:nth-child(4) { --tx: 0px; --ty: 70px; } + .minirkx-hex-item:nth-child(5) { --tx: -60px; --ty: 35px; } + .minirkx-hex-item:nth-child(6) { --tx: -60px; --ty: -35px; } + + .minirkx-hex-content { + width: 72px; + height: 72px; + } + + .minirkx-hex-icon { + font-size: 20px; + } + + .minirkx-hex-label { + font-size: 9px; + } + } @@ -474,7 +674,7 @@

+ + + + + + +
+
+ +
+ +
+
+
🏠
+
Trang chủ
+
+
+ + +
+
+
📚
+
Thư viện
+
+
+ + +
+
+
📂
+
Dự án
+
+
+ + +
+
+
⚙️
+
Ứng dụng
+
+
+ + +
+
+
💻
+
Codex
+
+
+ + +
+
+
🔧
+
Cài đặt
+
+
+
+
+ From 5ef4a887dd46fb93ac48291ca1e90056061b2874 Mon Sep 17 00:00:00 2001 From: v0agent Date: Sat, 6 Jun 2026 18:45:48 +0000 Subject: [PATCH 17/34] feat: update project to modern React + TypeScript workspace with Vite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Huỳnh Thương <252359928+Huynhthuongg@users.noreply.github.com> --- .gitignore | 29 + README.md | 161 ++- index.html | 1146 ++++------------- package-lock.json | 1781 +++++++++++++++++++++++++++ package.json | 24 + src/App.tsx | 79 ++ src/components/ApiSettingsModal.tsx | 67 + src/components/Header.tsx | 36 + src/components/MainContent.tsx | 101 ++ src/components/MiniRkxButton.tsx | 52 + src/components/MiniRkxMenu.tsx | 42 + src/components/Sidebar.tsx | 87 ++ src/main.tsx | 9 + tsconfig.json | 26 + tsconfig.node.json | 10 + tsconfig.node.tsbuildinfo | 1 + tsconfig.tsbuildinfo | 1 + vite.config.d.ts | 2 + vite.config.js | 11 + vite.config.ts | 12 + 20 files changed, 2749 insertions(+), 928 deletions(-) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/App.tsx create mode 100644 src/components/ApiSettingsModal.tsx create mode 100644 src/components/Header.tsx create mode 100644 src/components/MainContent.tsx create mode 100644 src/components/MiniRkxButton.tsx create mode 100644 src/components/MiniRkxMenu.tsx create mode 100644 src/components/Sidebar.tsx create mode 100644 src/main.tsx create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 tsconfig.node.tsbuildinfo create mode 100644 tsconfig.tsbuildinfo create mode 100644 vite.config.d.ts create mode 100644 vite.config.js create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d1f044 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Environment variables +.env +.env.local +.env.*.local diff --git a/README.md b/README.md index 704c5d9..03cd83d 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,168 @@
RKIX3 Logo -

RKIX3 AI Studio

-

Nền tảng AI hỗ trợ lập trình, build dự án, tự động hoá CLI/mobile-first và triển khai web app tốc độ cao.

+

RKIX3 AI Workspace

+

Modern React + TypeScript application for AI-powered development workspace with Vite.

- GitHub Pages - Static Web - AI Ready - Mobile First + React + TypeScript + Vite + Tailwind CSS

- 🚀 Mở giao diện RKIX3 + 🚀 Get Started · - Tính năng + Features · - Vinh danh + Components · - Nhà tài trợ + Deployment

+## 🚀 Getting Started + +### Prerequisites +- Node.js 16+ +- npm or yarn + +### Installation + +```bash +npm install +``` + +### Development Server + +```bash +npm run dev +``` + +The app will start at `http://localhost:5173` with HMR (Hot Module Replacement). + +### Build for Production + +```bash +npm run build +``` + +Creates optimized build in `dist/` directory. + +### Preview Build + +```bash +npm run preview +``` + +## 📁 Project Structure + +``` +src/ +├── components/ +│ ├── Sidebar.tsx # Main navigation sidebar +│ ├── Header.tsx # Top header with controls +│ ├── MainContent.tsx # Central content with prompt input +│ ├── MiniRkxButton.tsx # Floating navigation button +│ ├── MiniRkxMenu.tsx # Honeycomb menu (tổ ong) +│ └── ApiSettingsModal.tsx # API configuration modal +├── App.tsx # Root component with state management +└── main.tsx # React entry point +``` + +## ✨ Features + +- 🎨 **Modern Dark Theme** - Gradient effects with cyan/blue colors +- 🤖 **AI Workspace** - Prompt input with voice recording simulation +- 🎯 **MiniRkx Navigation** - Floating button with honeycomb menu +- 📱 **Fully Responsive** - Mobile-first design for all screen sizes +- ⌨️ **Type Safe** - Full TypeScript support +- ⚡ **Fast Development** - Vite with HMR +- 🎭 **Rich Animations** - Smooth transitions and transforms + +## 🧩 Components + +| Component | Purpose | +|-----------|---------| +| **Sidebar** | Navigation menu with search, projects, and features | +| **Header** | Top bar with menu toggle, API settings, and login | +| **MainContent** | Logo, prompt input, and feature cards | +| **MiniRkxButton** | Floating button with tech-themed logo | +| **MiniRkxMenu** | Honeycomb menu with 6 navigation items | +| **ApiSettingsModal** | Configure API keys and settings | + +## 🛠️ Technologies + +- **React 18** - UI library +- **TypeScript 5** - Type safety +- **Vite 5** - Build tool and dev server +- **Tailwind CSS 3** - Utility-first CSS framework +- **Lucide React** - Icon library + +## 🚀 Deployment + +### Build + +```bash +npm run build +``` + +The `dist/` folder is production-ready and can be deployed to: +- Vercel +- GitHub Pages +- Netlify +- Any static hosting + +### GitHub Pages + +1. Add to `package.json`: +```json +"homepage": "https://yourusername.github.io/AGENTS.RKIX3" +``` + +2. Build and deploy: +```bash +npm run build +git add dist -f +git commit -m "Deploy" +git push origin main +``` + +## 📦 Scripts + +```bash +npm run dev # Start development server +npm run build # Build for production +npm run preview # Preview production build locally +npm run lint # Run ESLint (optional) +``` + +## 🎯 State Management + +The app uses React's built-in `useState` hook for state management. Key states: +- `sidebarOpen` - Mobile sidebar visibility +- `menuOpen` - MiniRkx menu state +- `showApiModal` - API settings modal visibility +- `prompt` - User input text +- `isRecording` - Voice recording state + +## 🤝 Contributing + +Contributions are welcome! Please: +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Submit a pull request + +## 📄 License + +MIT + +
+ Built with 💙 for RKIX3 — Modern, Fast, and Type-Safe +
+ ---
diff --git a/index.html b/index.html index ebfec66..733af5a 100644 --- a/index.html +++ b/index.html @@ -1,941 +1,251 @@ - + - - - + + + RKIX3 AI - Lập trình, Code, Build, Tự động hoá - - - - - - - - - - -
- - - - - - - - - - - - -
- - -
-
- - -
- -
- - -
-
- - -
- - -
-
- RKIX3 Logo -
- -

- Chúng ta nên bắt đầu từ đâu? -

-
- - -
-
- - -
- - -
- - -
-
-
-
- - - - - -
-
-
- -
-

Lập trình

-

Viết code, debug và tối ưu hóa hệ thống

-
- -
-
- -
-

Build

-

Xây dựng sản phẩm nhanh chóng

-
- -
-
- -
-

Tự động hoá

-

Tự động hoá quy trình và công việc

-
- -
-
- -
-

AI thông minh

-

Hỗ trợ bởi AI thế hệ mới

-
-
- -
- -
- - - - - - -
- - - - - - - - - -
- - Hệ thống thông báo! -
- - - - - - - - - - - - - - -
-
- -
- -
-
-
🏠
-
Trang chủ
-
-
- - -
-
-
📚
-
Thư viện
-
-
- - -
-
-
📂
-
Dự án
-
-
- - -
-
-
⚙️
-
Ứng dụng
-
-
- - -
-
-
💻
-
Codex
-
-
- - -
-
-
🔧
-
Cài đặt
-
-
-
-
- - + + +
+ + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2a62acc --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1781 @@ +{ + "name": "rkix3-workspace", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "rkix3-workspace", + "version": "1.0.0", + "dependencies": { + "lucide-react": "^0.263.1", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "@vitejs/plugin-react": "^4.1.1", + "typescript": "^5.2.2", + "vite": "^5.0.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", + "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", + "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", + "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", + "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", + "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", + "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", + "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", + "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", + "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", + "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", + "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", + "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", + "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", + "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", + "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", + "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", + "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", + "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", + "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", + "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", + "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", + "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", + "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", + "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", + "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", + "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.34", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.34.tgz", + "integrity": "sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001797", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001797.tgz", + "integrity": "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.368", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.368.tgz", + "integrity": "sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.263.1", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.263.1.tgz", + "integrity": "sha512-keqxAx97PlaEN89PXZ6ki1N8nRjGWtDa4021GFYLNj0RgruM5odbpl8GHTExj0hhPq3sF6Up0gnxt6TSHu+ovw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", + "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.61.1", + "@rollup/rollup-android-arm64": "4.61.1", + "@rollup/rollup-darwin-arm64": "4.61.1", + "@rollup/rollup-darwin-x64": "4.61.1", + "@rollup/rollup-freebsd-arm64": "4.61.1", + "@rollup/rollup-freebsd-x64": "4.61.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", + "@rollup/rollup-linux-arm-musleabihf": "4.61.1", + "@rollup/rollup-linux-arm64-gnu": "4.61.1", + "@rollup/rollup-linux-arm64-musl": "4.61.1", + "@rollup/rollup-linux-loong64-gnu": "4.61.1", + "@rollup/rollup-linux-loong64-musl": "4.61.1", + "@rollup/rollup-linux-ppc64-gnu": "4.61.1", + "@rollup/rollup-linux-ppc64-musl": "4.61.1", + "@rollup/rollup-linux-riscv64-gnu": "4.61.1", + "@rollup/rollup-linux-riscv64-musl": "4.61.1", + "@rollup/rollup-linux-s390x-gnu": "4.61.1", + "@rollup/rollup-linux-x64-gnu": "4.61.1", + "@rollup/rollup-linux-x64-musl": "4.61.1", + "@rollup/rollup-openbsd-x64": "4.61.1", + "@rollup/rollup-openharmony-arm64": "4.61.1", + "@rollup/rollup-win32-arm64-msvc": "4.61.1", + "@rollup/rollup-win32-ia32-msvc": "4.61.1", + "@rollup/rollup-win32-x64-gnu": "4.61.1", + "@rollup/rollup-win32-x64-msvc": "4.61.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..aa44823 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "rkix3-workspace", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "lucide-react": "^0.263.1" + }, + "devDependencies": { + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "@vitejs/plugin-react": "^4.1.1", + "typescript": "^5.2.2", + "vite": "^5.0.3" + } +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..3e8cc98 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,79 @@ +import { useState } from 'react' +import Sidebar from './components/Sidebar' +import Header from './components/Header' +import MainContent from './components/MainContent' +import MiniRkxButton from './components/MiniRkxButton' +import MiniRkxMenu from './components/MiniRkxMenu' +import ApiSettingsModal from './components/ApiSettingsModal' + +export default function App() { + const [sidebarOpen, setSidebarOpen] = useState(false) + const [menuOpen, setMenuOpen] = useState(false) + const [showApiModal, setShowApiModal] = useState(false) + const [prompt, setPrompt] = useState('') + const [isRecording, setIsRecording] = useState(false) + + const handleMenuCommand = (command: string) => { + console.log(`Menu command: ${command}`) + // Handle menu commands here + } + + const handleSubmitPrompt = () => { + if (!prompt.trim()) return + console.log(`Submitting prompt: ${prompt}`) + setPrompt('') + } + + return ( +
+ {/* Sidebar */} + setSidebarOpen(false)} + onMenuCommand={handleMenuCommand} + /> + + {/* Overlay for mobile */} + {sidebarOpen && ( +
setSidebarOpen(false)} + /> + )} + + {/* Main Content */} +
+
setSidebarOpen(true)} + onApiSettings={() => setShowApiModal(true)} + /> + + +
+ + {/* MiniRkx Button & Menu */} + setMenuOpen(!menuOpen)} + /> + + setMenuOpen(false)} + onMenuCommand={handleMenuCommand} + /> + + {/* API Settings Modal */} + {showApiModal && ( + setShowApiModal(false)} /> + )} +
+ ) +} diff --git a/src/components/ApiSettingsModal.tsx b/src/components/ApiSettingsModal.tsx new file mode 100644 index 0000000..c174416 --- /dev/null +++ b/src/components/ApiSettingsModal.tsx @@ -0,0 +1,67 @@ +import { useState } from 'react' +import { X } from 'lucide-react' + +interface ApiSettingsModalProps { + onClose: () => void +} + +export default function ApiSettingsModal({ onClose }: ApiSettingsModalProps) { + const [apiKey, setApiKey] = useState('') + + return ( +
+
+ {/* Header */} +
+

Cài đặt Mã API

+ +
+ + {/* Form */} +
+
+ + setApiKey(e.target.value)} + placeholder="Nhập mã API của bạn" + className="w-full px-3 py-2 bg-zinc-900 border border-zinc-800 text-zinc-100 placeholder-zinc-500 focus:outline-none focus:border-blue-500 square-flat transition-all" + /> +

+ Bạn có thể lấy mã API từ Google AI Studio +

+
+ + {/* Buttons */} +
+ + +
+
+
+
+ ) +} diff --git a/src/components/Header.tsx b/src/components/Header.tsx new file mode 100644 index 0000000..79e9539 --- /dev/null +++ b/src/components/Header.tsx @@ -0,0 +1,36 @@ +import { Menu, Scan } from 'lucide-react' + +interface HeaderProps { + onMenuOpen: () => void + onApiSettings: () => void +} + +export default function Header({ onMenuOpen, onApiSettings }: HeaderProps) { + return ( +
+
+ + +
+ +
+ + +
+
+ ) +} diff --git a/src/components/MainContent.tsx b/src/components/MainContent.tsx new file mode 100644 index 0000000..efd7206 --- /dev/null +++ b/src/components/MainContent.tsx @@ -0,0 +1,101 @@ +import { Plus, Mic, ArrowUp } from 'lucide-react' + +interface MainContentProps { + prompt: string + setPrompt: (value: string) => void + isRecording: boolean + setIsRecording: (value: boolean) => void + onSubmit: () => void + onMenuCommand: (command: string) => void +} + +export default function MainContent({ + prompt, + setPrompt, + isRecording, + setIsRecording, + onSubmit, + onMenuCommand, +}: MainContentProps) { + return ( +
+ {/* Logo Section */} +
+
+
+ RKIX3 +
+
+ +

+ Chúng ta nên bắt đầu từ đâu? +

+
+ + {/* Prompt Input Box */} +
+
+