OpenLab-NLP commited on
Commit
264f8dd
Β·
verified Β·
1 Parent(s): b070fc7

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +84 -85
index.html CHANGED
@@ -2,62 +2,57 @@
2
  <html lang="ko">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>Huiucl Auto-Load Dictionary</title>
6
  <style>
7
  :root { --primary: #2c3e50; --accent: #e67e22; --bg: #f8f9fa; --card: #ffffff; }
8
- body { font-family: 'Malgun Gothic', 'Apple SD Gothic Neo', sans-serif; background: var(--bg); padding: 20px; color: var(--primary); }
9
  .container { max-width: 900px; margin: 0 auto; }
10
 
11
- /* λ‘œλ”© μƒνƒœ ν‘œμ‹œ */
12
- #loader { text-align: center; padding: 20px; font-weight: bold; color: #2980b9; }
13
-
14
  /* 헀더 μ„Ήμ…˜ */
15
- .header-panel { background: var(--primary); color: white; padding: 30px; border-radius: 15px; margin-bottom: 25px; box-shadow: 0 4px 15px rgba(0,0,0,0.2); }
16
- .header-panel h1 { margin: 0; font-size: 32px; letter-spacing: 1px; }
17
 
18
  /* 검색창 */
19
  .search-container { position: sticky; top: 15px; z-index: 1000; margin-bottom: 30px; }
20
- .search-input { width: 100%; padding: 20px 25px; font-size: 22px; border: 4px solid #ddd; border-radius: 50px; box-sizing: border-box; outline: none; box-shadow: 0 10px 25px rgba(0,0,0,0.1); transition: all 0.3s ease; }
21
- .search-input:focus { border-color: var(--accent); transform: translateY(-2px); }
22
 
23
  /* κ²°κ³Ό μΉ΄λ“œ */
24
- .card { background: var(--card); border-radius: 15px; padding: 30px; margin-bottom: 25px; box-shadow: 0 5px 20px rgba(0,0,0,0.05); border-left: 8px solid #dcdde1; transition: transform 0.2s; }
25
- .card:hover { transform: scale(1.01); }
26
  .card.exact { border-left-color: var(--accent); }
27
 
28
- .badge { display: inline-block; padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: bold; margin-bottom: 10px; }
29
- .badge-cat { background: #f1f2f6; color: #7f8c8d; }
30
- .badge-exact { background: var(--accent); color: white; margin-left: 10px; }
 
31
 
32
- .word-row { display: flex; align-items: baseline; gap: 15px; flex-wrap: wrap; }
33
- .word-text { font-size: 32px; font-weight: 900; color: #2980b9; text-transform: uppercase; }
34
- .meaning-text { font-size: 20px; color: #2c3e50; font-weight: 600; }
35
- .meaning-en { color: #95a5a6; font-size: 16px; font-style: italic; }
36
-
37
- /* 데이터 κ·Έλ¦¬λ“œ (νŒŒμƒμ–΄, λ³€μ΄ν˜•) */
38
- .grid-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 15px; margin-top: 20px; }
39
- .data-list { background: #fdfdfd; border: 1px solid #f1f1f1; border-radius: 10px; padding: 15px; }
40
- .list-title { font-size: 14px; font-weight: bold; color: #34495e; border-bottom: 2px solid #3498db; padding-bottom: 5px; margin-bottom: 10px; }
41
- .item-row { display: flex; font-size: 14px; margin-bottom: 4px; }
42
- .item-key { font-weight: bold; width: 110px; color: #e67e22; }
43
 
44
  /* 상세 정보 (검색 μ œμ™Έ ꡬ역) */
45
- .details { margin-top: 20px; padding-top: 15px; border-top: 1px dashed #eee; font-size: 14px; color: #555; }
46
- .detail-item { margin-bottom: 5px; }
47
- .label { font-weight: bold; color: #7f8c8d; margin-right: 5px; }
48
- .example-box { color: #2980b9; background: #ebf5fb; padding: 10px; border-radius: 5px; margin-top: 5px; }
49
  </style>
50
  </head>
51
  <body>
52
 
53
  <div class="container">
54
  <div class="header-panel">
55
- <h1>Huiucl Engine <small style="font-size: 14px; opacity: 0.8;">v3.0 Auto-Load</small></h1>
56
- <div id="loader">βš™οΈ 데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 쀑...</div>
57
  </div>
58
 
59
  <div class="search-container">
60
- <input type="text" id="query" class="search-input" placeholder="검색어λ₯Ό μž…λ ₯ν•˜μ„Έμš” (su, a, mi, μ œμž‘ν•˜λ‹€...)" onkeyup="search()">
61
  </div>
62
 
63
  <div id="results"></div>
@@ -66,119 +61,123 @@
66
  <script>
67
  let lexicon = {};
68
 
69
- // [μžλ™ λ‘œλ“œ] νŽ˜μ΄μ§€ λ‘œλ“œ μ‹œ Huiucl.json νŒŒμΌμ„ μ¦‰μ‹œ μ½μ–΄μ˜΄
70
  window.onload = async function() {
71
  try {
72
- const response = await fetch('Huiucl.json');
73
- if (!response.ok) throw new Error('νŒŒμΌμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
74
- const data = await response.json();
75
-
76
  process(data);
77
-
78
- document.getElementById('loader').innerText = `βœ… ${Object.keys(lexicon).length}개 ν•­λͺ© λ‘œλ“œ μ™„λ£Œ. λ°”λ‘œ 검색 κ°€λŠ₯ν•©λ‹ˆλ‹€.`;
79
- setTimeout(() => document.getElementById('loader').style.display = 'none', 3000);
80
  } catch (err) {
81
- document.getElementById('loader').innerHTML = `❌ 였λ₯˜: ${err.message}<br><small>Huiucl.json 파일이 같은 폴더에 μžˆλŠ”μ§€ ν™•μΈν•˜μ„Έμš”.</small>`;
82
  }
83
  };
84
 
 
85
  function process(obj, parentKey = null, currentCat = null) {
86
  if (typeof obj !== 'object' || obj === null) return;
87
 
88
- // 1. λŒ€λͺ…사 μ„Ήμ…˜ (a, i, u λ“± ν•œ κΈ€μž λŒ€λͺ…사 μ™„λ²½ λ‘œλ“œ)
89
  const pSects = ["1st_Person", "2nd_Person", "3rd_Person", "Demonstratives"];
90
  if (pSects.includes(parentKey)) {
91
  for (const [pk, pv] of Object.entries(obj)) {
92
  lexicon[pk] = {
93
  meaning_ko: pv,
94
- _category: `Pronoun (${parentKey})`,
95
  _search_target: `${pk} ${pv}`.toLowerCase()
96
  };
97
  }
98
  return;
99
  }
100
 
101
- // 2. 일반 단어 처리
102
- const keys = ['meaning_ko', 'ko', 'definition', 'morpheme', 'meaning_en', 'en'];
103
- const hasInfo = keys.some(k => k in obj);
104
 
105
- if (hasInfo && parentKey) {
106
  let entry = { ...obj };
107
- if (entry.definition && typeof entry.definition === 'object') Object.assign(entry, entry.definition);
 
 
108
 
109
- // [μ€‘μš”] 검색 νƒ€κ²Ÿμ—μ„œ usage, example은 제거 (μ˜€λ‘œμ§€ 단어λͺ…κ³Ό 뜻만)
110
- let targets = [parentKey];
111
- keys.forEach(k => { if (entry[k]) targets.push(entry[k]); });
112
-
113
  entry._category = currentCat;
114
- entry._search_target = targets.join(" ").toLowerCase();
 
 
 
115
  lexicon[parentKey] = entry;
116
  }
117
 
118
  for (const [k, v] of Object.entries(obj)) {
119
- if (typeof v === 'object') {
120
- const nextCat = (parentKey === null) ? k : currentCat;
121
- if (k !== 'Settings') process(v, k, nextCat);
122
  }
123
  }
124
  }
125
 
 
126
  function search() {
127
  const q = document.getElementById('query').value.trim().toLowerCase();
128
- const resDiv = document.getElementById('results');
129
- resDiv.innerHTML = '';
130
  if (!q) return;
131
 
132
  let found = [];
133
- // μ •ν™•ν•œ 독립 ν˜•νƒœμ†Œ 인지λ₯Ό μœ„ν•œ μ •κ·œμ‹
134
  const re = new RegExp(`(^|[^a-zA-Zκ°€-힣])${q}($|[^a-zA-Zκ°€-힣])`, 'i');
135
 
136
  for (const [word, info] of Object.entries(lexicon)) {
137
  const wordL = word.toLowerCase();
138
  const target = info._search_target || "";
139
-
140
  if (q === wordL) found.push({ word, info, score: 2 });
141
  else if (re.test(target) || (q.length > 1 && target.includes(q))) found.push({ word, info, score: 1 });
142
  }
143
 
144
- found.sort((a, b) => b.score - a.score).forEach(item => {
145
  const info = item.info;
146
  const card = document.createElement('div');
147
  card.className = `card ${item.score === 2 ? 'exact' : ''}`;
148
 
149
- // νŒŒμƒμ–΄/λ³€μ΄ν˜• κ·Έλ¦¬λ“œ 생성
150
- let gridHtml = '';
151
- const derivs = info.derivations || info.derivation;
152
- if (derivs) {
153
- gridHtml += `<div class="data-list"><div class="list-title">πŸ“‚ 기둝된 νŒŒμƒμ–΄</div>`;
154
- for(const [dw, dm] of Object.entries(derivs)) gridHtml += `<div class="item-row"><span class="item-key">${dw}</span> <span>${dm}</span></div>`;
155
- gridHtml += `</div>`;
156
  }
157
-
158
- let vars = {};
159
- ["tense_variants", "aspect_voice", "variants"].forEach(k => { if(info[k]) Object.assign(vars, info[k]); });
160
- if (Object.keys(vars).length > 0) {
161
- gridHtml += `<div class="data-list"><div class="list-title">πŸ“‚ μ‹œμ œ 및 변이</div>`;
162
- for(const [vw, vi] of Object.entries(vars)) gridHtml += `<div class="item-row"><span class="item-key">${vw}</span> <span>${vi.meaning_ko || vi.ko || ''}</span></div>`;
163
- gridHtml += `</div>`;
164
  }
165
 
166
  card.innerHTML = `
167
- <span class="badge badge-cat">${info._category}</span>
168
- ${item.score === 2 ? '<span class="badge badge-exact">μ •ν™•ν•œ 일치</span>' : ''}
 
 
169
  <div class="word-row">
170
  <span class="word-text">${item.word}</span>
171
- <span class="meaning-text">${info.meaning_ko || info.ko || info.morpheme || ''}</span>
172
- <span class="meaning-en">${info.meaning_en || info.en || ''}</span>
173
  </div>
174
- <div class="grid-container">${gridHtml}</div>
175
- <div class="details">
176
- ${info.usage ? `<div class="detail-item"><span class="label">πŸ“ μš©λ²•:</span> ${typeof info.usage === 'object' ? info.usage.ko : info.usage}</div>` : ''}
177
- ${info.note ? `<div class="detail-item"><span class="label">πŸ’‘ μ°Έκ³ :</span> ${info.note}</div>` : ''}
178
- ${info.example ? `<div class="example-box"><span class="label">πŸ“– 예문:</span> ${info.example}</div>` : ''}
179
  </div>
180
  `;
181
- resDiv.appendChild(card);
182
  });
183
  }
184
  </script>
 
2
  <html lang="ko">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <title>Huiucl Precision Dictionary v4</title>
6
  <style>
7
  :root { --primary: #2c3e50; --accent: #e67e22; --bg: #f8f9fa; --card: #ffffff; }
8
+ body { font-family: 'Malgun Gothic', sans-serif; background: var(--bg); padding: 20px; color: var(--primary); }
9
  .container { max-width: 900px; margin: 0 auto; }
10
 
 
 
 
11
  /* 헀더 μ„Ήμ…˜ */
12
+ .header-panel { background: var(--primary); color: white; padding: 25px; border-radius: 15px; margin-bottom: 25px; text-align: center; }
 
13
 
14
  /* 검색창 */
15
  .search-container { position: sticky; top: 15px; z-index: 1000; margin-bottom: 30px; }
16
+ .search-input { width: 100%; padding: 18px 25px; font-size: 20px; border: 4px solid #ddd; border-radius: 50px; outline: none; box-shadow: 0 8px 20px rgba(0,0,0,0.1); }
17
+ .search-input:focus { border-color: var(--accent); }
18
 
19
  /* κ²°κ³Ό μΉ΄λ“œ */
20
+ .card { background: var(--card); border-radius: 12px; padding: 25px; margin-bottom: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.05); border-left: 8px solid #bdc3c7; }
 
21
  .card.exact { border-left-color: var(--accent); }
22
 
23
+ .tag-row { margin-bottom: 10px; }
24
+ .badge { display: inline-block; padding: 3px 10px; border-radius: 5px; font-size: 11px; font-weight: bold; text-transform: uppercase; }
25
+ .badge-cat { background: #ebf5fb; color: #2980b9; }
26
+ .badge-exact { background: var(--accent); color: white; margin-left: 5px; }
27
 
28
+ .word-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
29
+ .word-text { font-size: 28px; font-weight: 900; color: #2c3e50; }
30
+ .meaning-ko { font-size: 22px; color: #e74c3c; font-weight: bold; }
31
+ .meaning-en { color: #7f8c8d; font-size: 16px; }
32
+
33
+ /* νŒŒμƒ/변이 κ·Έλ¦¬λ“œ */
34
+ .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px; margin-top: 15px; }
35
+ .data-box { background: #fcfcfc; border: 1px solid #efefef; border-radius: 8px; padding: 12px; }
36
+ .box-title { font-size: 13px; font-weight: bold; color: #34495e; margin-bottom: 8px; border-bottom: 1px solid #3498db; }
37
+ .item-row { display: flex; font-size: 13px; margin-bottom: 3px; }
38
+ .item-key { font-weight: bold; width: 100px; color: #d35400; }
39
 
40
  /* 상세 정보 (검색 μ œμ™Έ ꡬ역) */
41
+ .extra { margin-top: 15px; padding-top: 10px; border-top: 1px dashed #eee; font-size: 13px; color: #666; }
42
+ .ex-box { color: #2980b9; background: #f0f7ff; padding: 10px; border-radius: 5px; margin-top: 5px; border-left: 3px solid #3498db; }
43
+ .label { font-weight: bold; color: #95a5a6; margin-right: 5px; }
 
44
  </style>
45
  </head>
46
  <body>
47
 
48
  <div class="container">
49
  <div class="header-panel">
50
+ <h1 id="title">Huiucl Precision Dictionary</h1>
51
+ <p id="status">βš™οΈ 데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 쀑...</p>
52
  </div>
53
 
54
  <div class="search-container">
55
+ <input type="text" id="query" class="search-input" placeholder="Huiucl.json을 같은 폴더에 두고 λ‘œλ“œλ˜κΈΈ κΈ°λ‹€λ¦¬μ„Έμš”..." disabled onkeyup="search()">
56
  </div>
57
 
58
  <div id="results"></div>
 
61
  <script>
62
  let lexicon = {};
63
 
64
+ // 1. 파일 μžλ™ λ‘œλ“œ
65
  window.onload = async function() {
66
  try {
67
+ const res = await fetch('Huiucl.json');
68
+ if (!res.ok) throw new Error('νŒŒμΌμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
69
+ const data = await res.json();
 
70
  process(data);
71
+ document.getElementById('status').innerText = `βœ… ${Object.keys(lexicon).length}개 단어 λ‘œλ“œ μ™„λ£Œ`;
72
+ document.getElementById('query').disabled = false;
73
+ document.getElementById('query').placeholder = "단어 λ˜λŠ” 뜻 검색 (su, a, muihi, κ΄€μ°°...)";
74
  } catch (err) {
75
+ document.getElementById('status').innerText = `❌ 였λ₯˜: ${err.message}`;
76
  }
77
  };
78
 
79
+ // 2. 데이터 처리 (뜻 μš°μ„ μˆœμœ„ 및 검색 νƒ€κ²Ÿ μ •λ°€ν™”)
80
  function process(obj, parentKey = null, currentCat = null) {
81
  if (typeof obj !== 'object' || obj === null) return;
82
 
83
+ // λŒ€λͺ…사 특수 계측
84
  const pSects = ["1st_Person", "2nd_Person", "3rd_Person", "Demonstratives"];
85
  if (pSects.includes(parentKey)) {
86
  for (const [pk, pv] of Object.entries(obj)) {
87
  lexicon[pk] = {
88
  meaning_ko: pv,
89
+ _category: `Pronoun`,
90
  _search_target: `${pk} ${pv}`.toLowerCase()
91
  };
92
  }
93
  return;
94
  }
95
 
96
+ // 단어 정보 νŒλ‹¨
97
+ const keys = ['ko', 'meaning_ko', 'morpheme', 'en', 'meaning_en'];
98
+ const hasMeaning = keys.some(k => k in obj);
99
 
100
+ if (hasMeaning && parentKey) {
101
  let entry = { ...obj };
102
+ // 뜻 μΆ”μΆœ μš°μ„ μˆœμœ„: ν•œκ΅­μ–΄ λŒ€μ‘μ–΄(ko) -> μ‹€μ œ 뜻(meaning_ko) -> ν˜•νƒœμ†Œ 정보(morpheme)
103
+ const koVal = entry.ko || entry.meaning_ko || entry.morpheme || "";
104
+ const enVal = entry.en || entry.meaning_en || "";
105
 
106
+ // [핡심] 검색 νƒ€κ²Ÿμ—μ„œ μƒμœ„ ν‚€(Nominative λ“±) 및 예문/μš©λ²• μ œμ™Έ!
107
+ // 였직 단어 이름과 μœ„μ—μ„œ μΆ”μΆœν•œ koVal, enVal만 검색 λŒ€μƒ
 
 
108
  entry._category = currentCat;
109
+ entry._display_ko = koVal;
110
+ entry._display_en = enVal;
111
+ entry._search_target = `${parentKey} ${koVal} ${enVal}`.toLowerCase();
112
+
113
  lexicon[parentKey] = entry;
114
  }
115
 
116
  for (const [k, v] of Object.entries(obj)) {
117
+ if (typeof v === 'object' && k !== 'Settings') {
118
+ process(v, k, parentKey === null ? k : currentCat);
 
119
  }
120
  }
121
  }
122
 
123
+ // 3. 검색 및 λ Œλ”λ§
124
  function search() {
125
  const q = document.getElementById('query').value.trim().toLowerCase();
126
+ const area = document.getElementById('results');
127
+ area.innerHTML = '';
128
  if (!q) return;
129
 
130
  let found = [];
 
131
  const re = new RegExp(`(^|[^a-zA-Zκ°€-힣])${q}($|[^a-zA-Zκ°€-힣])`, 'i');
132
 
133
  for (const [word, info] of Object.entries(lexicon)) {
134
  const wordL = word.toLowerCase();
135
  const target = info._search_target || "";
136
+
137
  if (q === wordL) found.push({ word, info, score: 2 });
138
  else if (re.test(target) || (q.length > 1 && target.includes(q))) found.push({ word, info, score: 1 });
139
  }
140
 
141
+ found.sort((a,b) => b.score - a.score).forEach(item => {
142
  const info = item.info;
143
  const card = document.createElement('div');
144
  card.className = `card ${item.score === 2 ? 'exact' : ''}`;
145
 
146
+ // νŒŒμƒμ–΄/μ‹œμ œ λ°•μŠ€ 생성 (데이터 μžˆλŠ” 경우만)
147
+ let subHtml = '';
148
+ const dr = info.derivations || info.derivation;
149
+ if (dr) {
150
+ subHtml += `<div class="data-box"><div class="box-title">πŸ“‚ 기둝된 νŒŒμƒμ–΄</div>`;
151
+ for(const [k, v] of Object.entries(dr)) subHtml += `<div class="item-row"><span class="item-key">${k}</span><span>${v}</span></div>`;
152
+ subHtml += `</div>`;
153
  }
154
+
155
+ let vr = {};
156
+ ['tense_variants', 'aspect_voice', 'variants'].forEach(k => { if(info[k]) Object.assign(vr, info[k]); });
157
+ if (Object.keys(vr).length > 0) {
158
+ subHtml += `<div class="data-box"><div class="box-title">πŸ“‚ μ‹œμ œ 및 변이</div>`;
159
+ for(const [k, v] of Object.entries(vr)) subHtml += `<div class="item-row"><span class="item-key">${k}</span><span>${v.ko || v.meaning_ko || ''}</span></div>`;
160
+ subHtml += `</div>`;
161
  }
162
 
163
  card.innerHTML = `
164
+ <div class="tag-row">
165
+ <span class="badge badge-cat">${info._category}</span>
166
+ ${item.score === 2 ? '<span class="badge badge-exact">μ •ν™•ν•œ 일치</span>' : ''}
167
+ </div>
168
  <div class="word-row">
169
  <span class="word-text">${item.word}</span>
170
+ <span class="meaning-ko">${info._display_ko}</span>
171
+ <span class="meaning-en">${info._display_en}</span>
172
  </div>
173
+ <div class="grid">${subHtml}</div>
174
+ <div class="extra">
175
+ ${info.usage ? `<div><span class="label">πŸ“ μš©λ²•:</span> ${typeof info.usage === 'object' ? info.usage.ko : info.usage}</div>` : ''}
176
+ ${info.note ? `<div><span class="label">πŸ’‘ μ°Έκ³ :</span> ${info.note}</div>` : ''}
177
+ ${info.example ? `<div class="ex-box"><span class="label">πŸ“– 예문:</span> ${info.example}</div>` : ''}
178
  </div>
179
  `;
180
+ area.appendChild(card);
181
  });
182
  }
183
  </script>