OpenLab-NLP commited on
Commit
b1b25e4
·
verified ·
1 Parent(s): cc472d6

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +82 -81
index.html CHANGED
@@ -3,29 +3,30 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>HUIUCL Database</title>
7
  <style>
8
- :root { --bg-color: #f9f7f2; --card-bg: #ffffff; --primary-color: #5d5b54; --accent-color: #d4a373; --border-color: #e0ddd5; }
9
- body { font-family: 'Pretendard', sans-serif; background-color: var(--bg-color); color: var(--primary-color); margin: 0; padding: 0; line-height: 1.6; }
10
- nav { position: sticky; top: 0; background: rgba(249, 247, 242, 0.9); backdrop-filter: blur(10px); padding: 15px; text-align: center; border-bottom: 1px solid var(--border-color); z-index: 100; }
11
- nav a { margin: 0 15px; text-decoration: none; color: var(--primary-color); font-weight: 600; cursor: pointer; }
12
  header { text-align: center; padding: 40px 20px; }
13
- h1 { font-weight: 300; letter-spacing: 8px; color: var(--accent-color); margin: 0; }
14
  .container { max-width: 1100px; margin: 0 auto; padding: 0 20px 100px; }
15
  section { display: none; }
16
  section.active { display: block; }
17
  .filter-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 25px; }
18
- .filter-btn { background: var(--card-bg); border: 1px solid var(--border-color); padding: 8px 16px; cursor: pointer; border-radius: 20px; font-size: 0.85rem; }
19
- .filter-btn.active { background: var(--accent-color); color: white; border-color: var(--accent-color); }
20
- .search-box { width: 100%; padding: 15px 25px; border: 1px solid var(--border-color); border-radius: 30px; font-size: 1rem; margin-bottom: 20px; box-sizing: border-box; outline: none; }
21
  .table-wrapper { background: white; border-radius: 15px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.05); }
22
  table { width: 100%; border-collapse: collapse; }
23
  th, td { padding: 15px 20px; text-align: left; border-bottom: 1px solid #eee; }
24
  th { background: #f1eee6; color: #777; font-size: 0.85rem; }
25
- .word-cell { font-weight: bold; color: var(--accent-color); width: 25%; }
26
- .meaning-cell { width: 55%; font-size: 0.95rem; }
27
  .path-cell { font-size: 0.7rem; color: #bbb; width: 20%; text-align: right; }
28
- .usage-text { font-size: 0.85rem; color: #7a7a7a; background: #fcfcfc; border-left: 3px solid var(--accent-color); padding: 5px 10px; margin-top: 8px; }
 
29
  </style>
30
  </head>
31
  <body>
@@ -37,19 +38,19 @@
37
 
38
  <header>
39
  <h1>HUIUCL</h1>
40
- <div style="color:#999; font-size:0.8rem; margin-top:5px;">DATABASE v2.8 (Strict Object Handing)</div>
41
  </header>
42
 
43
  <div class="container">
44
  <section id="dictionary" class="active">
45
- <input type="text" id="searchInput" class="search-box" placeholder="단어, 검색..." oninput="renderTable()">
46
  <div class="filter-container" id="categoryButtons">
47
  <button class="filter-btn active" onclick="filterCategory('모두', this)">모두 보기</button>
48
  </div>
49
  <div class="table-wrapper">
50
  <table>
51
  <thead>
52
- <tr><th>단어</th><th>의미 및 상세 설명</th><th style="text-align:right;">분류</th></tr>
53
  </thead>
54
  <tbody id="dictBody"></tbody>
55
  </table>
@@ -59,8 +60,8 @@
59
  </div>
60
 
61
  <script>
62
- let conlangData = {};
63
- let currentCategory = '모두';
64
 
65
  function showSection(id) {
66
  document.querySelectorAll('section').forEach(s => s.classList.remove('active'));
@@ -68,122 +69,122 @@
68
  }
69
 
70
  window.onload = () => {
71
- fetch('Huiucl.json').then(res => res.json()).then(data => {
72
- conlangData = data;
73
- initFilterButtons();
74
  renderTable();
75
- renderGrammarPage();
76
  });
77
  };
78
 
79
- function initFilterButtons() {
80
- const btnContainer = document.getElementById('categoryButtons');
81
- Object.keys(conlangData).forEach(key => {
82
  if (key === "Settings") return;
83
  const btn = document.createElement('button');
84
  btn.className = 'filter-btn';
85
  btn.innerText = key;
86
- btn.onclick = (e) => filterCategory(key, e.target);
87
- btnContainer.appendChild(btn);
 
 
 
 
 
88
  });
89
  }
90
 
91
- function filterCategory(cat, btn) {
92
- document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
93
- btn.classList.add('active');
94
- currentCategory = cat;
95
- renderTable();
96
- }
97
-
98
  function renderTable() {
99
  const query = document.getElementById('searchInput').value.toLowerCase();
100
  const body = document.getElementById('dictBody');
101
  body.innerHTML = '';
102
- const cats = currentCategory === '모두' ? Object.keys(conlangData).filter(k => k !== "Settings") : [currentCategory];
103
- cats.forEach(cat => strictProcess(conlangData[cat], cat, query));
 
104
  }
105
 
106
- function strictProcess(obj, path, query) {
107
- // 문법 규칙 제외
108
  if (path.includes("Grammar_Rules")) return;
109
 
110
  for (let key in obj) {
111
  const val = obj[key];
112
  if (!val) continue;
113
 
114
- // 출력 제외 예약
115
- const skipKeys = ["usage", "note", "definition", "tense_variants", "ko", "en"];
116
- if (skipKeys.includes(key)) continue;
 
 
117
 
118
- // 1. 단어 정보가 담긴 객체인 경우
119
- if (typeof val === 'object') {
120
- const kor = val.meaning_ko || val.ko || val.뜻 || val.definition || "";
121
- const eng = val.meaning_en || val.en || "";
122
- const usage = val.usage || val.note || "";
123
 
124
- // 한국어 뜻이나 영문 키에 정보가 있는 '진짜 단어'인 경우 출력
125
- if (kor || eng) {
126
- if (key.toLowerCase().includes(query) || (typeof kor === 'string' && kor.includes(query))) {
127
- appendRow(key, kor, eng, usage, path);
128
- }
129
-
130
- // 파생어 처리
131
- if (val.derivations) {
132
- for (let dKey in val.derivations) {
133
- appendRow(dKey, val.derivations[dKey], "", "", path, true);
134
- }
135
  }
136
- // 시제 변형이 있다면 내부 탐색
137
- if (val.tense_variants) strictProcess(val.tense_variants, path + " > " + key, query);
138
- }
139
- // 하위 데이터가 더 있다면 재귀 탐색
140
- else {
141
- strictProcess(val, path + " > " + key, query);
142
  }
 
143
  }
144
- // 2. 대명사/인사말 등 단순 문자열인 경우
145
  else if (typeof val === 'string') {
146
  if (key.toLowerCase().includes(query) || val.toLowerCase().includes(query)) {
147
- appendRow(key, val, "", "", path);
148
  }
149
  }
 
 
 
 
150
  }
151
  }
152
 
153
- function appendRow(word, kor, eng, usage, path, isSub) {
154
  const body = document.getElementById('dictBody');
155
  const row = body.insertRow();
156
  if (isSub) row.className = 'variation-row';
157
 
158
- let content = `<strong>${typeof kor === 'object' ? JSON.stringify(kor) : kor}</strong>`;
159
- if (eng) content += ` <span style="color:#888;">(${eng})</span>`;
160
- if (usage) content += `<div class="usage-text"> ${usage}</div>`;
161
 
162
  row.innerHTML = `
163
- <td class="word-cell">${isSub ? ' ' : ''}${word}</td>
164
- <td class="meaning-cell">${content}</td>
165
  <td class="path-cell">${path}</td>
166
  `;
167
  }
168
 
169
- function renderGrammarPage() {
170
  const target = document.getElementById('grammarContent');
171
  let html = "";
172
- function findRules(obj, path) {
173
- for (let key in obj) {
174
- if (key === "Grammar_Rules") {
175
- html += `<div style="background:white; padding:30px; border-radius:15px; margin-bottom:20px; box-shadow:0 5px 15px rgba(0,0,0,0.05);">
176
- <h3 style="margin-top:0; color:var(--accent-color);">${path || 'General'} Rules</h3>`;
177
- for (let rKey in obj[key]) {
178
- html += `<p><strong>${rKey}:</strong> ${obj[key][rKey]}</p>`;
 
 
 
 
 
 
 
 
 
 
 
179
  }
180
  html += `</div>`;
181
- } else if (typeof obj[key] === 'object' && key !== "Settings") {
182
- findRules(obj[key], path ? path + " > " + key : key);
183
  }
184
  }
185
  }
186
- findRules(conlangData, "");
187
  target.innerHTML = html;
188
  }
189
  </script>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>HUIUCL Database v3.0</title>
7
  <style>
8
+ :root { --bg: #f9f7f2; --card: #ffffff; --primary: #5d5b54; --accent: #d4a373; --border: #e0ddd5; }
9
+ body { font-family: 'Pretendard', sans-serif; background: var(--bg); color: var(--primary); margin: 0; line-height: 1.6; }
10
+ nav { position: sticky; top: 0; background: rgba(249, 247, 242, 0.9); backdrop-filter: blur(10px); padding: 15px; text-align: center; border-bottom: 1px solid var(--border); z-index: 100; }
11
+ nav a { margin: 0 15px; text-decoration: none; color: var(--primary); font-weight: 600; cursor: pointer; }
12
  header { text-align: center; padding: 40px 20px; }
13
+ h1 { font-weight: 300; letter-spacing: 8px; color: var(--accent); margin: 0; }
14
  .container { max-width: 1100px; margin: 0 auto; padding: 0 20px 100px; }
15
  section { display: none; }
16
  section.active { display: block; }
17
  .filter-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 25px; }
18
+ .filter-btn { background: var(--card); border: 1px solid var(--border); padding: 8px 16px; cursor: pointer; border-radius: 20px; font-size: 0.85rem; }
19
+ .filter-btn.active { background: var(--accent); color: white; border-color: var(--accent); }
20
+ .search-box { width: 100%; padding: 15px 25px; border: 1px solid var(--border); border-radius: 30px; font-size: 1rem; margin-bottom: 20px; box-sizing: border-box; outline: none; }
21
  .table-wrapper { background: white; border-radius: 15px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.05); }
22
  table { width: 100%; border-collapse: collapse; }
23
  th, td { padding: 15px 20px; text-align: left; border-bottom: 1px solid #eee; }
24
  th { background: #f1eee6; color: #777; font-size: 0.85rem; }
25
+ .word-cell { font-weight: bold; color: var(--accent); width: 25%; font-size: 1.1rem; }
26
+ .meaning-cell { width: 55%; }
27
  .path-cell { font-size: 0.7rem; color: #bbb; width: 20%; text-align: right; }
28
+ .desc-box { background: #fafafa; border-left: 3px solid var(--accent); padding: 8px 12px; margin-top: 10px; font-size: 0.85rem; color: #666; }
29
+ .tag { display: inline-block; background: #eee; padding: 2px 8px; border-radius: 4px; font-size: 0.75rem; margin-right: 5px; color: #555; }
30
  </style>
31
  </head>
32
  <body>
 
38
 
39
  <header>
40
  <h1>HUIUCL</h1>
41
+ <div style="color:#999; font-size:0.85rem; margin-top:5px;">DATABASE v3.0 FINAL REVISION</div>
42
  </header>
43
 
44
  <div class="container">
45
  <section id="dictionary" class="active">
46
+ <input type="text" id="searchInput" class="search-box" placeholder="단어, 한국어 의미, 영어 의미 검색..." oninput="renderTable()">
47
  <div class="filter-container" id="categoryButtons">
48
  <button class="filter-btn active" onclick="filterCategory('모두', this)">모두 보기</button>
49
  </div>
50
  <div class="table-wrapper">
51
  <table>
52
  <thead>
53
+ <tr><th>단어 (Word)</th><th>의미 및 용법 (Meaning/Usage)</th><th style="text-align:right;">분류</th></tr>
54
  </thead>
55
  <tbody id="dictBody"></tbody>
56
  </table>
 
60
  </div>
61
 
62
  <script>
63
+ let db = {};
64
+ let currentCat = '모두';
65
 
66
  function showSection(id) {
67
  document.querySelectorAll('section').forEach(s => s.classList.remove('active'));
 
69
  }
70
 
71
  window.onload = () => {
72
+ fetch('Huiucl.json').then(r => r.json()).then(data => {
73
+ db = data;
74
+ initUI();
75
  renderTable();
76
+ renderGrammar();
77
  });
78
  };
79
 
80
+ function initUI() {
81
+ const container = document.getElementById('categoryButtons');
82
+ Object.keys(db).forEach(key => {
83
  if (key === "Settings") return;
84
  const btn = document.createElement('button');
85
  btn.className = 'filter-btn';
86
  btn.innerText = key;
87
+ btn.onclick = (e) => {
88
+ document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
89
+ e.target.classList.add('active');
90
+ currentCat = key;
91
+ renderTable();
92
+ };
93
+ container.appendChild(btn);
94
  });
95
  }
96
 
 
 
 
 
 
 
 
97
  function renderTable() {
98
  const query = document.getElementById('searchInput').value.toLowerCase();
99
  const body = document.getElementById('dictBody');
100
  body.innerHTML = '';
101
+
102
+ const targets = currentCat === '모두' ? Object.keys(db).filter(k => k !== "Settings") : [currentCat];
103
+ targets.forEach(cat => parseData(db[cat], cat, query));
104
  }
105
 
106
+ function parseData(obj, path, query) {
 
107
  if (path.includes("Grammar_Rules")) return;
108
 
109
  for (let key in obj) {
110
  const val = obj[key];
111
  if (!val) continue;
112
 
113
+ // 1. 객체 (의미 정보 포함)
114
+ if (typeof val === 'object' && (val.meaning_ko || val.ko || val.definition || val.뜻)) {
115
+ const ko = val.meaning_ko || val.ko || val.뜻 || val.definition || "";
116
+ const en = val.meaning_en || val.en || "";
117
+ const note = val.usage || val.note || "";
118
 
119
+ if (key.toLowerCase().includes(query) || (typeof ko === 'string' && ko.includes(query))) {
120
+ addRow(key, ko, en, note, path);
121
+ }
 
 
122
 
123
+ if (val.derivations) {
124
+ for (let dKey in val.derivations) {
125
+ addRow(dKey, val.derivations[dKey], "", "", path, true);
 
 
 
 
 
 
 
 
126
  }
 
 
 
 
 
 
127
  }
128
+ if (val.tense_variants) parseData(val.tense_variants, path + " > " + key, query);
129
  }
130
+ // 2. 단순 문자열 (대명사, 등)
131
  else if (typeof val === 'string') {
132
  if (key.toLowerCase().includes(query) || val.toLowerCase().includes(query)) {
133
+ addRow(key, val, "", "", path);
134
  }
135
  }
136
+ // 3. 중첩 객체 (재귀 - 단, 데이터용 키는 제외)
137
+ else if (typeof val === 'object' && !["usage", "note", "definition", "tense_variants"].includes(key)) {
138
+ parseData(val, path + " > " + key, query);
139
+ }
140
  }
141
  }
142
 
143
+ function addRow(word, ko, en, note, path, isSub) {
144
  const body = document.getElementById('dictBody');
145
  const row = body.insertRow();
146
  if (isSub) row.className = 'variation-row';
147
 
148
+ let meaningHtml = `<div style="font-weight:600; font-size:1.05rem;">${ko}</div>`;
149
+ if (en) meaningHtml += `<div style="color:#888; font-size:0.9rem;">${en}</div>`;
150
+ if (note) meaningHtml += `<div class="desc-box"><span class="tag">USAGE</span>${note}</div>`;
151
 
152
  row.innerHTML = `
153
+ <td class="word-cell">${isSub ? ' ' : ''}${word}</td>
154
+ <td class="meaning-cell">${meaningHtml}</td>
155
  <td class="path-cell">${path}</td>
156
  `;
157
  }
158
 
159
+ function renderGrammar() {
160
  const target = document.getElementById('grammarContent');
161
  let html = "";
162
+
163
+ // Settings 출력
164
+ if (db.Settings) {
165
+ html += `<div style="background:white; padding:30px; border-radius:15px; margin-bottom:20px; border:1px solid var(--border);">
166
+ <h2 style="margin-top:0; color:var(--accent);">Basic Phonology & Syntax</h2>
167
+ <p><strong>어순:</strong> ${db.Settings.Syntax.Word_Order.join(' / ')}</p>
168
+ <p><strong>Vowels:</strong> ${Object.keys(db.Settings.Phonology.Vowels).join(', ')}</p>
169
+ <p><strong>Consonants:</strong> ${Object.keys(db.Settings.Phonology.Consonants).join(', ')}</p>
170
+ </div>`;
171
+ }
172
+
173
+ function collectRules(obj, path) {
174
+ for (let k in obj) {
175
+ if (k === "Grammar_Rules") {
176
+ html += `<div style="background:white; padding:30px; border-radius:15px; margin-bottom:20px; border:1px solid var(--border);">
177
+ <h3 style="margin-top:0; color:var(--accent);">${path} Rules</h3>`;
178
+ for (let rule in obj[k]) {
179
+ html += `<p style="margin:8px 0; border-bottom:1px solid #f9f9f9; padding-bottom:5px;"><strong>${rule}:</strong> ${obj[k][rule]}</p>`;
180
  }
181
  html += `</div>`;
182
+ } else if (typeof obj[k] === 'object' && k !== "Settings") {
183
+ collectRules(obj[k], path ? path + " > " + k : k);
184
  }
185
  }
186
  }
187
+ collectRules(db, "");
188
  target.innerHTML = html;
189
  }
190
  </script>