본문으로 건너뛰기
Public Source Viewer

비나래아카이브 개발자 포털

실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.

Redacted View
view/hinana/partials/site-header.ejs
공개 가능
1 <%
2 const siteDark = typeof theme !== 'undefined' && theme === 'dark';
3 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
4 const sitePath = typeof uiPath !== 'undefined' && uiPath.startsWith('/') && !uiPath.startsWith('//') ? uiPath : '/hinana/index';
5 const sitePage = typeof uiPage !== 'undefined' ? uiPage : '';
6 const siteSection = ['login','signup','userInfo','admin','backups','monitor','securityDashboard','developer','forbidden'].includes(sitePage) || sitePage.startsWith('404') ? ''
7 : ['index','post','archiveSearch'].includes(sitePage) ? 'index'
8 : ['blog','blogpost','write','editPost'].includes(sitePage) ? 'blog'
9 : ['main','info','gallery','plaza','studio'].includes(sitePage) ? sitePage : 'lounge';
10 const siteLinks = [['main','/','홈','home'],['index','/hinana/index','아카이브','archive'],['blog','/hinana/blog','블로그','book'],['studio','/hinana/studio','Hinana Studio','spark'],['lounge','/hinana/lounge','라운지','cup'],['gallery','/hinana/gallery','갤러리','image'],['plaza','/hinana/plaza','광장','chat'],['info','/hinana/info','소개','note']];
11 const siteTools = [['works','/hinana/works','작품 일람','book'],['rail','/hinana/rail','히나나레일','train'],['japaneseLounge','/hinana/japanese-lounge','일본어 라운지','language']];
12 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
13 const siteRelated = {aiNotes:[['/hinana/ai','AI 대화'],['/hinana/personal-notes','개인 노트']],personalNotes:[['/hinana/ai/notes','AI 노트']],aiView:[['/hinana/ai','AI 대화로 돌아가기']],subway:[['/hinana/subway/map','지하철 노선도']],subwayMap:[['/hinana/subway','실시간 지하철']],exhibition:[['/hinana/gallery','갤러리']],monitor:[['/hinana/userInfo','내 정보']],blogpost:siteUser?[['/hinana/write','새 글 쓰기']]:[]}[sitePage] || [];
14 %>
15 <%- include('site-icons') %>
16 <a class="ui-skip" href="#ui-content">본문으로 건너뛰기</a>
17 <aside class="ui-sidebar" id="ui-sidebar" aria-label="사이트 메뉴">
18 <a class="ui-side-brand" href="/" aria-label="비나래 아카이브 홈"><img src="/image/<%= siteDark ? 'archive1.png' : 'archive.png' %>" alt="비나래 아카이브"></a>
19 <div class="ui-side-group"><div class="ui-side-label">ARCHIVE</div><nav aria-label="주요 메뉴">
20 <% siteLinks.forEach(([key,href,label,icon])=>{ %><a class="ui-side-link<%= siteSection===key?' is-current':'' %>" href="<%= href %>"<%- siteSection===key?' aria-current="page"':'' %>><svg aria-hidden="true"><use href="#ui-i-<%= icon %>"/></svg><span><%= label %></span></a><% }); %>
21 </nav></div>
22 <div class="ui-side-group"><div class="ui-side-label">작은 도구들</div><nav aria-label="도구 메뉴">
23 <% siteTools.forEach(([key,href,label,icon])=>{ %><a class="ui-side-link<%= sitePage===key?' is-current':'' %>" href="<%= href %>"<%- sitePage===key?' aria-current="page"':'' %>><svg aria-hidden="true"><use href="#ui-i-<%= icon %>"/></svg><span><%= label %></span></a><% }); %>
24 <% if(siteUser){ %><a class="ui-side-link<%= sitePage==='aiNotes'?' is-current':'' %>" href="/hinana/ai/notes"><svg aria-hidden="true"><use href="#ui-i-note"/></svg><span>AI 노트</span></a><% } %>
25 </nav></div>
26 <div class="ui-side-bottom">
27 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
28 <div class="ui-side-note"><strong>Archive My Memory</strong><span>취향과 기록이 모이는 작은 공간.</span><span>© 2024–2026 비나래 · hinana.moe</span></div>
29 </div>
30 </aside>
31 <button class="ui-sidebar-dim" id="ui-sidebar-dim" aria-label="메뉴 닫기" tabindex="-1" hidden></button>
32 <header class="ui-header">
33 <button type="button" class="ui-icon ui-mobile-menu" id="ui-menu-toggle" aria-label="메뉴 열기" aria-controls="ui-sidebar" aria-expanded="false"><svg aria-hidden="true"><use href="#ui-i-menu"/></svg></button>
34 <nav class="ui-breadcrumbs" aria-label="현재 위치"><a href="/">비나래 아카이브</a><span aria-hidden="true">/</span><span><%= siteLabels[sitePage] || (sitePage.startsWith('404')?'페이지를 찾을 수 없어요':'라운지') %></span></nav>
35 <form class="ui-global-search" action="/hinana/archive-search" method="GET" role="search"><svg aria-hidden="true"><use href="#ui-i-search"/></svg><input type="search" name="q" id="ui-global-search" aria-label="아카이브 통합 검색" placeholder="기록 검색..." value="<%= sitePage==='archiveSearch'&&typeof query!=='undefined'?query:'' %>" maxlength="120"><span class="ui-keycap" aria-hidden="true">⌘ K</span><button type="submit" class="ui-search-submit" aria-label="검색"><svg aria-hidden="true"><use href="#ui-i-arrow"/></svg></button></form>
36 <div class="ui-actions">
37 <% if(sitePage==='ai'){ %><button type="button" class="ui-icon btn-history-toggle" id="btn-history-toggle" aria-controls="ai-history-drawer" aria-expanded="false" title="대화 기록" aria-label="대화 기록" style="display:none"><svg aria-hidden="true"><use href="#ui-i-book"/></svg></button><% } %>
38 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
39 <% if(siteUser){ %><details class="ui-account-menu"><summary class="ui-account" aria-label="<%= siteUser %> 계정 메뉴"><span class="ui-account-dot" aria-hidden="true"></span><span><%= siteUser %></span></summary><nav class="ui-account-panel" aria-label="계정 메뉴"><a href="/hinana/userInfo">내 정보</a><a href="/hinana/ai/notes">AI 노트</a><% if(siteUser==='비나래'){ %><a href="/hinana/personal-notes">개인 노트</a><a href="/hinana/security">보안 관제</a><a href="/hinana/backups">백업 센터</a><% } %><a href="/logout?redirect=<%= encodeURIComponent(sitePath) %>">로그아웃</a></nav></details>
40 <% }else{ %><a class="ui-account" href="/login?redirect=<%= encodeURIComponent(sitePath) %>"><span>로그인</span></a><% } %>
41 </div>
42 </header>
43 <% if(siteRelated.length){ %><nav class="ui-context" aria-label="관련 메뉴"><% siteRelated.forEach(([href,label])=>{ %><a href="<%= href %>"><%= label %><span aria-hidden="true"> →</span></a><% }); %></nav><% } %>
44 <script src="/js/site-app.js?v=1" defer></script>
45