SeaWolf-AI commited on
Commit
16a249d
ยท
verified ยท
1 Parent(s): ec6ef95

link the LEADBOARD benchmark alongside the sister challenge

Browse files
Files changed (1) hide show
  1. index.html +868 -864
index.html CHANGED
@@ -1,864 +1,868 @@
1
- <!doctype html>
2
- <html lang="ko">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width,initial-scale=1">
6
- <title>Open Materials Challenge #1 ์ „๊ณ ์ฒด ์ „ํ•ด์งˆ</title>
7
- <!-- <head> ๋Š” ์„ ํƒ์ด ์•„๋‹ˆ๋‹ค: ํ”Œ๋žซํผ์ด ์ž๊ธฐ ํƒœ๊ทธ๋ฅผ ๋ฌธ์„œ์— ์ฃผ์ž…ํ•˜๋Š”๋ฐ, ๋ฐ›์„ head ๊ฐ€ ์—†์œผ๋ฉด
8
- ๊ทธ๊ฒƒ๋“ค์ด doctype ์•ž์— ๋†“์ด๊ณ  ํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ ์ฟผํฌ ๋ชจ๋“œ๋กœ ๋–จ์–ด์ง„๋‹ค. -->
9
- <style>
10
- :root{
11
- --bg:#f7f8fa; --card:#fff; --ink:#16181d; --muted:#6b7280; --line:#e5e7eb;
12
- --accent:#1f6f4a; --accent-soft:#e8f3ed; --warn:#9a6700; --warn-soft:#fff8e1;
13
- --anchor:#fffbe6; --anchor-line:#f2e3a8;
14
- }
15
- :root:not([data-theme="light"]){}
16
- @media (prefers-color-scheme: dark){
17
- :root:not([data-theme="light"]){
18
- --bg:#101215; --card:#171a1f; --ink:#e8eaed; --muted:#9aa1ab; --line:#2a2f37;
19
- --accent:#4bbb87; --accent-soft:#16281f; --warn:#e0b23c; --warn-soft:#2a2312;
20
- --anchor:#241f10; --anchor-line:#4a4022;
21
- }
22
- }
23
- :root[data-theme="dark"]{
24
- --bg:#101215; --card:#171a1f; --ink:#e8eaed; --muted:#9aa1ab; --line:#2a2f37;
25
- --accent:#4bbb87; --accent-soft:#16281f; --warn:#e0b23c; --warn-soft:#2a2312;
26
- --anchor:#241f10; --anchor-line:#4a4022;
27
- }
28
- *{box-sizing:border-box}
29
- body{margin:0;background:var(--bg);color:var(--ink);
30
- font:15px/1.65 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans KR",sans-serif}
31
- .wrap{max-width:1120px;margin:0 auto;padding:20px 16px 80px}
32
- header{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin:8px 0 4px}
33
- h1{font-size:22px;margin:0;letter-spacing:-.3px}
34
- h2{font-size:17px;margin:0 0 10px;display:flex;align-items:baseline;gap:10px}
35
- .sub{color:var(--muted);font-size:14px}
36
- .card{background:var(--card);border:1px solid var(--line);border-radius:14px;
37
- padding:18px 20px;margin:14px 0}
38
- .grid{display:grid;grid-template-columns:1fr 360px;gap:14px;align-items:start}
39
- @media (max-width:900px){.grid{grid-template-columns:1fr}}
40
- .cnt{color:var(--muted);font-size:13px;font-weight:400;margin-left:auto}
41
- #langbar,#seasonbar{display:flex;gap:6px;flex-wrap:wrap}
42
- #langbar{margin-left:auto}
43
- #langbar button,#seasonbar button{border:1px solid var(--line);background:var(--card);
44
- color:var(--muted);border-radius:8px;padding:5px 12px;cursor:pointer;font:inherit;font-size:13px}
45
- #langbar button.on,#seasonbar button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
46
- .scroll{overflow-x:auto}
47
- table{width:100%;border-collapse:collapse;font-size:13.5px;min-width:780px}
48
- th,td{padding:8px 10px;text-align:left;border-bottom:1px solid var(--line);white-space:nowrap}
49
- th{color:var(--muted);font-weight:600;font-size:12.5px;cursor:pointer;user-select:none}
50
- th .ar{opacity:.4;margin-left:3px;font-size:10px}
51
- th.sorted{color:var(--accent)} th.sorted .ar{opacity:1}
52
- tr.anchor{background:var(--anchor)}
53
- tr.anchor td{border-bottom-color:var(--anchor-line)}
54
- td.num{text-align:right;font-variant-numeric:tabular-nums}
55
- .pill{display:inline-block;padding:1px 7px;border-radius:999px;font-size:11.5px;
56
- background:var(--accent-soft);color:var(--accent);border:1px solid transparent}
57
- .note{color:var(--muted);font-size:12.5px;margin-top:12px;line-height:1.7}
58
- .pager{display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;
59
- padding:14px 4px 2px;font-size:13px}
60
- .pager button{border:1px solid var(--line);background:var(--card);color:var(--muted);
61
- border-radius:8px;padding:5px 11px;cursor:pointer;font:inherit;min-width:36px}
62
- .pager button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
63
- .pager button:disabled{opacity:.4;cursor:default}
64
- .pager .pinfo{color:var(--muted);margin:0 8px}
65
- .pager .gap{color:var(--muted);padding:0 2px}
66
- label{display:block;font-size:13px;color:var(--muted);margin:12px 0 5px}
67
- input,textarea,select{width:100%;padding:9px 11px;border:1px solid var(--line);
68
- border-radius:9px;background:var(--bg);color:var(--ink);font:inherit;font-size:14px}
69
- textarea{resize:vertical;min-height:64px}
70
- .radio{display:flex;gap:8px;margin-top:6px}
71
- .radio label{flex:1;display:flex;align-items:center;gap:7px;margin:0;padding:10px;
72
- border:1px solid var(--line);border-radius:9px;cursor:pointer;font-size:13px;color:var(--ink)}
73
- .radio label.on{border-color:var(--accent);background:var(--accent-soft)}
74
- .go{width:100%;margin-top:16px;padding:12px;border:0;border-radius:10px;
75
- background:var(--accent);color:#fff;font:inherit;font-size:15px;font-weight:600;cursor:pointer}
76
- .go:disabled{opacity:.5;cursor:default}
77
- .msg{margin-top:10px;padding:10px 12px;border-radius:9px;font-size:13px;display:none}
78
- .msg.ok{display:block;background:var(--accent-soft);color:var(--accent)}
79
- .msg.bad{display:block;background:var(--warn-soft);color:var(--warn)}
80
- .callout{background:var(--warn-soft);border:1px solid var(--anchor-line);
81
- border-radius:10px;padding:12px 14px;font-size:13px;color:var(--ink);margin:12px 0}
82
- .axes{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0 2px}
83
- .axes span{font-size:12.5px;color:var(--muted);background:var(--bg);
84
- border:1px solid var(--line);border-radius:999px;padding:3px 10px}
85
- .axes b{color:var(--ink)}
86
- a{color:var(--accent)}
87
- .badges{display:flex;gap:8px;flex-wrap:wrap;margin-top:6px}
88
- .badges img{height:22px}
89
- #divbar{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 12px}
90
- #divbar button{border:1px solid var(--line);background:var(--card);color:var(--muted);
91
- border-radius:999px;padding:4px 12px;cursor:pointer;font:inherit;font-size:12.5px}
92
- #divbar button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
93
- #divbar button .dn{opacity:.65;margin-left:5px;font-size:11.5px}
94
- .hf-user{color:var(--accent);text-decoration:none;white-space:nowrap}
95
- .hf-user:hover{text-decoration:underline}
96
- .signin{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--accent);
97
- background:var(--accent);color:#fff;border-radius:9px;padding:6px 13px;font-size:13px;
98
- text-decoration:none;font-weight:600}
99
- .signin.out{background:var(--card);color:var(--muted);border-color:var(--line);font-weight:400}
100
- .me{display:flex;align-items:center;gap:9px;margin:10px 0 0;font-size:13px;color:var(--muted)}
101
- .me img{width:22px;height:22px;border-radius:50%}
102
- .xlink{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);
103
- background:var(--card);border-radius:9px;padding:6px 12px;font-size:12.5px;
104
- color:var(--muted);text-decoration:none;margin-top:8px}
105
- .xlink:hover{border-color:var(--accent);color:var(--accent)}
106
- .xlink b{color:var(--ink);font-weight:600}
107
- .xlink em{font-style:normal;opacity:.75}
108
- .lead{font-size:15px;margin:0 0 12px}
109
- .sinfo{display:flex;gap:16px;flex-wrap:wrap;color:var(--muted);font-size:13px;margin:10px 0 0}
110
- .sinfo b{color:var(--ink);font-weight:600}
111
- #tabbar{display:flex;gap:2px;margin:16px 0 0;border-bottom:1px solid var(--line);flex-wrap:wrap}
112
- #tabbar button{border:0;background:none;color:var(--muted);font:inherit;font-size:14px;
113
- padding:9px 15px;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px}
114
- #tabbar button:hover{color:var(--ink)}
115
- #tabbar button.on{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}
116
- #tabbar .tc{margin-left:5px;font-size:11.5px;opacity:.7}
117
- .axhelp{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:8px;margin:12px 0 2px}
118
- .axhelp div{font-size:12.5px;color:var(--muted);line-height:1.55}
119
- .axhelp b{color:var(--ink)}
120
- tr.det td{background:var(--bg);white-space:normal;font-size:12.5px;color:var(--muted);
121
- border-bottom:1px solid var(--line)}
122
- tr.det ul{margin:2px 0;padding-left:16px} tr.det li{margin:2px 0}
123
- tr.held td{opacity:.72}
124
- .pill.warn{background:var(--warn-soft);color:var(--warn)}
125
- tr.pick{cursor:pointer}
126
- tr.pick:hover td{background:var(--accent-soft)}
127
- .facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px;margin:12px 0}
128
- .fact{background:var(--bg);border:1px solid var(--line);border-radius:10px;padding:11px 13px;font-size:13px}
129
- .fact b{display:block;color:var(--accent);font-size:12px;margin-bottom:3px}
130
- .pcard{border:1px solid var(--line);border-radius:11px;margin:10px 0;overflow:hidden}
131
- .phead{display:flex;align-items:center;gap:9px;padding:9px 13px;background:var(--bg);
132
- border-bottom:1px solid var(--line);flex-wrap:wrap}
133
- .ptag{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;
134
- border-radius:6px;background:var(--accent);color:#fff;font-size:12px;font-weight:700}
135
- .phead b{font-size:14px} .phead span{color:var(--muted);font-size:12.5px}
136
- .pcopy{margin-left:auto;border:1px solid var(--line);background:var(--card);color:var(--muted);
137
- border-radius:7px;padding:4px 11px;cursor:pointer;font:inherit;font-size:12px}
138
- .pcopy:hover{border-color:var(--accent);color:var(--accent)}
139
- .pbody{padding:12px 14px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
140
- font-size:12.5px;line-height:1.6;white-space:pre-wrap;color:var(--ink);max-height:280px;overflow:auto}
141
- .pbody em{color:var(--warn);font-style:normal;font-weight:600}
142
- .mrow{display:grid;grid-template-columns:minmax(120px,1.4fr) 1fr auto;gap:10px;
143
- align-items:center;padding:7px 0;border-bottom:1px solid var(--line);font-size:13px}
144
- .mrow:last-child{border-bottom:0}
145
- .mname{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
146
- .mbar{position:relative;height:16px;background:var(--bg);border-radius:5px;overflow:hidden}
147
- .mbar i{position:absolute;inset:0 auto 0 0;background:var(--accent);border-radius:5px}
148
- .mbar u{position:absolute;top:0;bottom:0;width:2px;background:var(--ink);opacity:.55}
149
- .mnum{font-variant-numeric:tabular-nums;color:var(--muted);white-space:nowrap;font-size:12.5px}
150
- .mlegend{display:flex;gap:14px;color:var(--muted);font-size:12px;margin-top:10px;flex-wrap:wrap}
151
- .mlegend i{display:inline-block;width:10px;height:10px;background:var(--accent);border-radius:2px;margin-right:4px}
152
- .mlegend u{display:inline-block;width:2px;height:11px;background:var(--ink);opacity:.55;margin-right:4px;
153
- vertical-align:-1px;text-decoration:none}
154
- </style>
155
- </head>
156
- <body>
157
- <div class="wrap">
158
-
159
- <header>
160
- <h1 id="t_title">Open Materials Challenge</h1>
161
- <span class="sub" id="t_sub"></span>
162
- <div id="langbar">
163
- <button data-lang="ko" class="on">ํ•œ๊ตญ์–ด</button>
164
- <button data-lang="en">English</button>
165
- </div>
166
- </header>
167
- <div id="seasonbar" style="margin:14px 0 0"></div>
168
- <div class="sinfo" id="sinfo"></div>
169
- <a class="xlink" id="xlink" href="https://huggingface.co/spaces/FINAL-Bench/open-discovery-challenge" target="_blank" rel="noopener"></a>
170
- <div id="tabbar"></div>
171
-
172
- <section data-tab="board">
173
- <div class="card">
174
- <h2 id="t_about_h"></h2>
175
- <div id="t_about"></div>
176
- <div class="axes" id="wts"></div>
177
- <div class="axhelp" id="axhelp"></div>
178
- <div class="callout" id="t_honest"></div>
179
- </div>
180
-
181
- </section>
182
-
183
- <section data-tab="guide" hidden>
184
- <div class="card">
185
- <h2 id="t_guide_h"></h2>
186
- <p class="lead" id="t_guide_lead"></p>
187
- <div class="facts" id="facts"></div>
188
- <div id="t_guide_how"></div>
189
- <div id="prompts"></div>
190
- </div>
191
-
192
- </section>
193
-
194
- <section data-tab="models" hidden>
195
- <div class="card">
196
- <h2><span id="t_models_h"></span><span class="cnt" id="mcounts"></span></h2>
197
- <div id="t_models_lead" class="note" style="margin-top:0"></div>
198
- <div id="models"></div>
199
- <div class="mlegend" id="t_mlegend"></div>
200
- </div>
201
- </section>
202
-
203
- <section data-tab="board" hidden>
204
- <div class="grid">
205
- <div class="card">
206
- <h2><span id="t_board_h"></span><span class="cnt" id="counts"></span></h2>
207
- <div id="divbar"></div>
208
- <div class="scroll">
209
- <table>
210
- <thead><tr id="head"></tr></thead>
211
- <tbody id="rows"></tbody>
212
- </table>
213
- </div>
214
- <div class="pager" id="pager"></div>
215
- <div class="note" id="t_boardnote"></div>
216
- </div>
217
-
218
- <div class="card">
219
- <h2 id="t_submit_h"></h2>
220
- <div id="gate" class="callout" style="display:none"></div>
221
- <div class="me" id="me"></div>
222
- <label id="l_formula"></label>
223
- <input id="f_formula" placeholder="Li3YCl6">
224
- <label id="l_name"></label>
225
- <input id="f_name" placeholder="">
226
- <label id="l_model"></label>
227
- <input id="f_model" placeholder="anthropic/claude-โ€ฆ, Qwen/โ€ฆ">
228
- <label id="l_cif"></label>
229
- <textarea id="f_cif" placeholder="# generated using pymatgen&#10;data_โ€ฆ"></textarea>
230
- <div class="note" id="t_cifnote" style="margin-top:4px"></div>
231
- <label id="l_why"></label>
232
- <textarea id="f_why"></textarea>
233
- <label id="l_vis"></label>
234
- <div class="radio" id="visbox">
235
- <label class="on"><input type="radio" name="vis" value="private" checked><span id="t_priv"></span></label>
236
- <label><input type="radio" name="vis" value="public"><span id="t_pub"></span></label>
237
- </div>
238
- <button class="go" id="go"></button>
239
- <div class="msg" id="msg"></div>
240
- <div class="note" id="t_limits"></div>
241
- </div>
242
- </div>
243
-
244
- </section>
245
-
246
- <section data-tab="board" hidden>
247
- <div class="card">
248
- <h2 id="t_broker_h"></h2>
249
- <div id="t_broker"></div>
250
- </div>
251
- </section>
252
-
253
- </div>
254
- <script>
255
- const T = {
256
- ko:{
257
- sub:"์ธ๋ฅ˜์˜ ๋‚œ์ œ๋ฅผ AI ์™€ ํ•จ๊ป˜ โ€” ๊ฐœ์ธ์ด ์ฐธ์—ฌํ•˜๋Š” ์‹ ์†Œ์žฌ ํƒ์ƒ‰",
258
- about_h:"์ด ๋Œ€ํšŒ๋Š” ๋ฌด์—‡์ธ๊ฐ€",
259
- about:`<p>์ „๊ณ ์ฒด ๋ฐฐํ„ฐ๋ฆฌ๋Š” ๋ฆฌํŠฌ์ด์˜จ ์ „์ง€์˜ ์•ก์ฒด ์ „ํ•ด์งˆ์„ ๊ณ ์ฒด๋กœ ๋ฐ”๊พผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋” ์•ˆ์ „ํ•˜๊ณ  ๋” ์˜ค๋ž˜ ๊ฐˆ ์ˆ˜ ์žˆ์ง€๋งŒ,
260
- <b>๊ณ ์ฒด์ด๋ฉด์„œ ๋ฆฌํŠฌ๋งŒ ์ž˜ ํ†ต๊ณผ์‹œํ‚ค๋Š” ๋ฌผ์งˆ</b>์„ ์ฐพ๋Š” ์ผ์ด ์•„์ง ํ’€๋ฆฌ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.</p>
261
- <p>์ด ๋Œ€ํšŒ๋Š” ๊ทธ ํ›„๋ณด ๋ฌผ์งˆ์„ ์ฐพ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ฐ€์ž๋Š” <b>์กฐ์„ฑ ํ•˜๋‚˜</b>๋ฅผ ๋ƒ…๋‹ˆ๋‹ค โ€” ์˜ˆ: <code>Li3YCl6</code>.
262
- ์ €ํฌ๊ฐ€ ๊ณ„์‚ฐ์œผ๋กœ ์ฑ„์ ํ•ด ์ˆœ์œ„ํ‘œ์— ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค. ์ƒ๊ธˆ์€ ์—†์Šต๋‹ˆ๋‹ค.</p>`,
263
- honest:`<b>์ด ์‹œ์ฆŒ์ด ์ฑ„์ ํ•˜๋Š” ๊ฒƒ.</b> <b>์ „๊ธฐํ™”ํ•™์  ๊ฐ•๊ฑด์„ฑ</b>์ž…๋‹ˆ๋‹ค โ€” ๋†’์€ ์ „์••์„ ๊ฒฌ๋””๋Š”์ง€,
264
- ๋ฆฌํŠฌ ๊ธˆ์†์— ๋‹ฟ์•„๋„ ๋ฒ„ํ‹ฐ๋Š”์ง€, ๋ฆฌํŠฌ์ด ์ง€๋‚˜๊ฐˆ ๊ธธ์ด ๋šซ๋ ค ์žˆ๋Š”์ง€.
265
- <b>์ด์˜จ์ „๋„๋„๋Š” ์ด๋ฒˆ ์‹œ์ฆŒ์˜ ์ฑ„์  ํ•ญ๋ชฉ์ด ์•„๋‹™๋‹ˆ๋‹ค.</b> ๋”ฐ๋ผ์„œ ์ „๋„๋„๊ฐ€ ๋†’์€ ๊ณ„์—ด์ด๋ผ๋„
266
- ์‚ฐํ™”์ฐฝ์ด ์ข๊ฑฐ๋‚˜ ๋ฆฌํŠฌ ๊ธˆ์†๊ณผ ๋ฐ˜์‘ํ•˜๋ฉด ๋‚ฎ๊ฒŒ ๋‚˜์˜ต๋‹ˆ๋‹ค โ€” ๊ทธ ๋‘ ๊ฐ€์ง€๊ฐ€ ์ด ์‹œ์ฆŒ์ด ๋ฌป๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.
267
- ๋ชจ๋“  ๊ฐ’์€ <b>๊ณ„์‚ฐ ์ถ”์ •์น˜</b>์ด๋ฉฐ ์‹ค์ œ ์„ฑ๋Šฅ์ด๋‚˜ ์•ˆ์ „์„ฑ์„ ๋œปํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.`,
268
- guide_h:"์ฐธ๊ฐ€ ๊ฐ€์ด๋“œ",
269
- guide_lead:`์ „๊ณ ์ฒด ์ „์ง€๋Š” ๋ฆฌํŠฌ ์ด์˜จ์ด <b>๊ณ ์ฒด ์•ˆ์„</b> ์ง€๋‚˜๊ฐ€์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ ๋ฌผ์งˆ์€ ๋™์‹œ์—
270
- <b>์ „์ž๋Š” ํ†ต๊ณผ์‹œํ‚ค์ง€ ์•Š์•„์•ผ</b> ํ•˜๊ณ , ์ถฉ์ „ ์ „์••์„ ๊ฒฌ๋ŽŒ์•ผ ํ•˜๊ณ , ์Œ๊ทน์˜ <b>๋ฆฌํŠฌ ๊ธˆ์†</b>์— ๋‹ฟ์•„๋„
271
- ๋ถ„ํ•ด๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋„ค ๊ฐ€์ง€๋ฅผ ํ•œ ๋ฌผ์งˆ์—์„œ ๋™์‹œ์— ๋งŒ์กฑ์‹œํ‚ค๋Š” ๊ฒƒ์ด ์•„์ง ํ’€๋ฆฌ๏ฟฝ๏ฟฝ ์•Š์€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.`,
272
- facts:[
273
- ["ํ‘œ์ ", "๋ฆฌํŠฌ์ด ์ง€๋‚˜๊ฐˆ ํ†ต๋กœ๊ฐ€ ์žˆ๋Š” ๊ณ ์ฒด. ๋ฆฌํŠฌ์„ ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."],
274
- ["๋„˜์–ด์•ผ ํ•  ๊ด€๋ฌธ", "์ „์ž๊ฐ€ ํ†ตํ•˜๋ฉด ์ „์ง€๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‹จ๋ฝ๋ฉ๋‹ˆ๋‹ค. ์ „์ž ์ ˆ์—ฐ์„ฑ์ด ์ „์ œ ์กฐ๊ฑด์ž…๋‹ˆ๋‹ค."],
275
- ["๊ฐ€์žฅ ์–ด๋ ค์šด ๊ณณ", "์‚ฐํ™” ์•ˆ์ •์„ฑ๊ณผ ๋ฆฌํŠฌ๊ธˆ์† ์•ˆ์ •์„ฑ์€ ์„œ๋กœ ์ž˜ ์•ˆ ๋งž์Šต๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ์žก๋Š” ๊ฒƒ์ด ์ด ์‹œ์ฆŒ์˜ ๊ณผ์ œ์ž…๋‹ˆ๋‹ค."],
276
- ["์ œ์ถœ", "์กฐ์„ฑ ํ•˜๋‚˜. ๊ตฌ์กฐ(CIF)๋Š” ์„ ํƒ์ด๋ฉฐ, ๋‚ด๋ฉด ์ฑ„์ ์ด ๋” ๋น ๋ฅด๊ณ  ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค."]],
277
- guide_how:`<p style="margin:14px 0 2px">์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์“ฐ์‹œ๋Š” AI ๋ชจ๋ธ์— ๊ทธ๋Œ€๋กœ ๋„ฃ์œผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
278
- <b>๋ณต์‚ฌ</b> ๋ฒ„ํŠผ์œผ๋กœ ๊ฐ€์ ธ๊ฐ€์‹  ๋’ค, ๊ธฐ์šธ์ž„์ฒด๋กœ ํ‘œ์‹œ๋œ ๋ถ€๋ถ„์€ ๋ณธ์ธ ๊ด€์‹ฌ์‚ฌ๋กœ ๋ฐ”๊ฟ” ์ฃผ์‹ญ์‹œ์˜ค โ€”
279
- ๊ทธ๋ž˜์•ผ ๋‹ค๋ฅธ ์ฐธ๊ฐ€์ž์™€ ๊ฐ™์€ ํ›„๋ณด๊ฐ€ ๊ฒน์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜์˜จ ์กฐ์„ฑ์„ ์˜ค๋ฅธ์ชฝ ์นธ์— ํ•˜๋‚˜์”ฉ ์ œ์ถœํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.</p>`,
280
- models_h:"AI ๋ชจ๋ธ๋ณ„ ์„ฑ๊ณผ",
281
- models_lead:`์–ด๋А ๋ชจ๋ธ์ด <b>๊ฐ€์žฅ ์ข‹์€ ํ›„๋ณด</b>๋ฅผ ๋ƒˆ๋Š”์ง€(๋ง‰๋Œ€)์™€ <b>์–ผ๋งˆ๋‚˜ ์“ฐ์ด๋Š”์ง€</b>(์˜ค๋ฅธ์ชฝ)๋ฅผ
282
- ํ•จ๊ป˜ ๋ด…๋‹ˆ๋‹ค. ๋งŽ์ด ์“ฐ์ธ๋‹ค๊ณ  ์ž˜ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ ๋”ฐ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.`,
283
- mempty:"์ฑ„์ ๋œ ์ œ์ถœ์ด ์Œ“์ด๋ฉด ๋ชจ๋ธ๋ณ„ ์„ฑ๊ณผ๊ฐ€ ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.",
284
- mcounts:(m,n)=>`๋ชจ๋ธ ${m} ยท ์ œ์ถœ ${n}`,
285
- mlegend:`<span><i></i>์ตœ๊ณ  ์ ์ˆ˜</span><span><u></u>ํ‰๊ท </span><span>์ œ์ถœ ์ˆ˜</span>`,
286
- tabs:{board:"๋Œ€ํšŒ ยท ์ˆœ์œ„ํ‘œ", guide:"์ฐธ๊ฐ€ ๊ฐ€์ด๋“œ", models:"๋ชจ๋ธ๋ณ„ ์„ฑ๊ณผ"},
287
- divs:{all:"์ „์ฒด", fluoride:"๋ถˆํ™”๋ฌผ", halide:"์—ผํ™”ยท๋ธŒ๋กฌํ™”ยท์š”์˜ค๋“œํ™”", sulfide:"ํ™ฉํ™”๋ฌผ",
288
- oxide:"์‚ฐํ™”๋ฌผ", nitride:"์งˆํ™”๋ฌผ", hydride:"์ˆ˜์†Œํ™”๋ฌผ", other:"๊ธฐํƒ€"},
289
- divnote:"์Œ์ด์˜จ ๊ณจ๊ฒฉ์— ๋”ฐ๋ผ ๋ถ€๋ฌธ์„ ๋‚˜๋ˆด์Šต๋‹ˆ๋‹ค. <b>์ ์ˆ˜๋Š” ๋ถ€๋ฌธ๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋™์ผํ•œ ๊ธฐ์ค€</b>์œผ๋กœ ๋งค๊ฒจ์ง€๋ฉฐ, ๋ถ€๋ฌธ์€ ๊ฐ™์€ ํ™”ํ•™ ๊ณ„์—ด ์•ˆ์—์„œ ๋น„๊ตํ•˜์‹œ๋ผ๊ณ  ๋‘” ๊ฒƒ์ž…๋‹ˆ๋‹ค.",
290
- xlink:`๐Ÿงช <b>Open Discovery Challenge</b> <em>โ€” ์‹ ์•ฝ ํ›„๋ณด ๋ฌผ์งˆ์„ ์ฐพ๋Š” ์ž๋งค ๋Œ€ํšŒ</em> โ†—`,
291
- sinfo:(o,c)=>[`์‹œ์ฆŒ ๊ธฐ๊ฐ„ <b>${o} ~ ${c}</b>`,`์ƒ๊ธˆ <b>์—†์Œ</b>`,`์ œ์ถœ <b>์กฐ์„ฑ ํ•˜๋‚˜</b>`],
292
- axhelp:[
293
- ["์‚ฐํ™” ์•ˆ์ •์„ฑ","์ถฉ์ „ ์ „์••์ด ๋†’์•„์กŒ์„ ๋•Œ ์ „ํ•ด์งˆ ์ž์‹ ์ด ๋ถ„ํ•ด๋˜์ง€ ์•Š๊ณ  ๋ฒ„ํ‹ฐ๋Š” ์ •๋„."],
294
- ["Li๊ธˆ์† ์•ˆ์ •์„ฑ","๋ฆฌํŠฌ ๊ธˆ์† ์Œ๊ทน์— ๋‹ฟ์•˜์„ ๋•Œ ๋ฐ˜์‘ํ•ด ๋ง๊ฐ€์ง€์ง€ ์•Š๋Š” ์ •๋„."],
295
- ["์šฉ๋„ ์‹ ๊ทœ์„ฑ","์ด ์กฐ์„ฑ์ด ๊ณ ์ฒด์ „ํ•ด์งˆ ์šฉ๋„๋กœ ๋ณด๊ณ ๋œ ์ ์ด ์—†์„์ˆ˜๋ก ๋†’์Šต๋‹ˆ๋‹ค."],
296
- ["๋ฆฌํŠฌ ์ด๋™ ๊ฒฝ๋กœ","์ ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ <b>์ฐธ๊ฐ€ ์กฐ๊ฑด</b>์ž…๋‹ˆ๋‹ค. ๋ฆฌํŠฌ์ด ์ง€๋‚˜๊ฐˆ ๊ด€ํ†ต ๊ฒฝ๋กœ๊ฐ€ ์—†์œผ๋ฉด ์ ‘์ˆ˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."]],
297
- limits:(L)=>`์ œ์ถœ ์ œํ•œ โ€” ๋ฆฌํŠฌ ํ•„์ˆ˜ ยท ๊ธฐ์•ฝ ์กฐ์„ฑ ์›์ž ์ˆ˜ ${L.max_atoms}๊ฐœ ์ดํ•˜ ยท ์›์†Œ 6์ข… ์ดํ•˜.
298
- ๊ฐ™์€ ๋ฌผ์งˆ์„ ์ •์ˆ˜๋ฐฐ๋กœ ๋ฐ”๊ฟ” ๋‹ค์‹œ ๋‚ด๋ฉด ๊ฐ™์€ ์ œ์ถœ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.`,
299
- detail_h:"์ฑ„์  ๋‚ด์—ญ",
300
- board_h:"์ˆœ์œ„ํ‘œ",
301
- boardnote:`<b>๊ธฐ์ค€๋ฌผ์งˆ(๋…ธ๋ž€ ํ–‰)</b>์€ ์ ์ˆ˜๋ฅผ ๋ฐ›๋˜ ๋“ฑ์ˆ˜๋ฅผ ๊ฐ–์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์“ฐ์ด๋Š” ์ „ํ•ด์งˆ์ด ๋ช‡ ์ ์ธ์ง€
302
- ๋ˆˆ์œผ๋กœ ๋น„๊ตํ•˜์‹œ๋ผ๊ณ  ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.<br>
303
- ๋น„๊ณต๊ฐœ ์ œ์ถœ์€ ์กฐ์„ฑ์„ ๊ฐ€๋ฆฌ๊ณ  <b>์›์†Œ ์ข…๋ฅ˜๋งŒ</b> ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์›๋ณธ์€ ๋น„๊ณต๊ฐœ๋กœ ๋ณด๊ด€๋ฉ๋‹ˆ๋‹ค.<br>
304
- <b>๊ตฌ์กฐ ํ•„์š” ยท ๋น„๊ต์ž๋ฃŒ ๋ถ€์กฑ</b>๋Š” ์ฑ„์  ์š”๊ฑด์ด ๊ฐ–์ถฐ์ง€์ง€ ์•Š์€ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. 0์ ์œผ๋กœ ๊ธฐ๋กํ•˜์ง€
305
- ์•Š๊ณ  ๋“ฑ์ˆ˜๋„ ๋งค๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค โ€” ์žฌ์ง€ ์•Š์€ ๊ฒƒ์„ ์„ฑ์ ์œผ๋กœ ์ ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
306
- <b>๋Œ€๋ถ€๋ถ„์€ ๊ตฌ์กฐ ํŒŒ์ผ(CIF)์„ ์ฒจ๋ถ€ํ•ด ๋‹ค์‹œ ์ œ์ถœํ•˜์‹œ๋ฉด ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค.</b> ํ–‰์„ ๋ˆ„๋ฅด๋ฉด ํ•„์š”ํ•œ ๊ฒƒ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.<br>
307
- ์—ด ์ œ๋ชฉ์„ ๋ˆŒ๋Ÿฌ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.`,
308
- submit_h:"์ œ์ถœ",
309
- l_formula:"์กฐ์„ฑ (ํ™”ํ•™์‹)", l_name:"ํ‘œ์‹œ ID (์ด๋ฆ„ยท์†Œ์†ยท๋‹‰๋„ค์ž„)", l_model:"์‚ฌ์šฉ ๋ชจ๋ธ๋ช… (์„ ํƒ)",
310
- l_cif:"๊ตฌ์กฐ ํŒŒ์ผ CIF (์„ ํƒ)", l_why:"์„ค๊ณ„ ๊ทผ๊ฑฐ (์„ ํƒ)", l_vis:"๊ณต๊ฐœ ์—ฌ๋ถ€",
311
- cifnote:`๊ตฌ์กฐ๋ฅผ ํ•จ๊ป˜ ๋‚ด๋ฉด ๋” ๋น ๋ฅด๊ณ  ์ •ํ™•ํ•˜๊ฒŒ ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค. ์—†์œผ๋ฉด ์ €ํฌ๊ฐ€ ๊ตฌ์กฐ๋ฅผ ์ถ”์ •ํ•˜๋ฉฐ,
312
- ์ถ”์ •์ด ๋˜์ง€ ์•Š๋Š” ์กฐ์„ฑ์€ <b>๊ตฌ์กฐ ํ•„์š”</b>๋กœ ํ‘œ์‹œ๋˜๊ณ  ๊ตฌ์กฐ๋ฅผ ์ฒจ๋ถ€ํ•ด ๋‹ค์‹œ ์ œ์ถœํ•˜์‹œ๋ฉด ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค.`,
313
- priv:"๐Ÿ”’ ๋น„๊ณต๊ฐœ (๊ธฐ๋ณธ)", pub:"๐Ÿ”“ ์กฐ์„ฑ ๊ณต๊ฐœ",
314
- go:"์ œ์ถœํ•˜๊ธฐ",
315
- gate:"์ œ์ถœํ•˜๋ ค๋ฉด <b>Hugging Face ๋กœ๊ทธ์ธ</b>์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ œ์ถœ์ž ๊ณ„์ •์ด ์ˆœ์œ„ํ‘œ์— ํ•จ๊ป˜ ํ‘œ์‹œ๋˜๋ฉฐ, ์ด๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ ์ด๋ฆ„์œผ๋กœ ์˜ฌ๋ฆฌ๋Š” ๊ฒƒ์„ ๋ง‰๊ณ  ๋ชจ๋ธ๋ณ„ ์ง‘๊ณ„๋ฅผ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.",
316
- signin:"Hugging Face ๋กœ ๋กœ๊ทธ์ธ", signout:"๋กœ๊ทธ์•„์›ƒ", signed_as:"๋กœ๊ทธ์ธ:",
317
- broker_h:"์ œ์ถœ ๊ธฐ๋ก๊ณผ ์ œ3์ž ์—ฐ๊ฒฐ",
318
- broker:`<p>์ œ์ถœ์€ ์‹œ๊ฐ๊ณผ ํ•จ๊ป˜ ์ €ํฌ ์›์žฅ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์กฐ์„ฑ์„ <b>๋น„๊ณต๊ฐœ</b>๋กœ ๋‘๋ฉด ์ €ํฌ๋งŒ ๋ณด๊ด€ํ•˜๋ฉฐ,
319
- ๊ณต๊ฐœํ•˜์ง€ ์•Š๋Š” ํ•œ ์™ธ๋ถ€์— ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ก์ด ํ–ฅํ›„ ๊ถŒ๋ฆฌ ์ฃผ์žฅ์— ์ฐธ๊ณ ๊ฐ€ ๋  ์ˆ˜ ์žˆ์œผ๋‚˜,
320
- <b>ํŠนํ—ˆ ์ถœ์›์„ ๋Œ€์‹ ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋ฒ•์  ํšจ๋ ฅ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.</b> ๏ฟฝ๏ฟฝ๏ฟฝ์›์€ ์ „๋ฌธ๊ฐ€์™€ ์ƒ์˜ํ•˜์‹ญ์‹œ์˜ค.</p>
321
- <p>์ œ3์ž๊ฐ€ ํŠน์ • ์ œ์ถœ์— ๋Œ€ํ•ด ํ˜‘์˜๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ, ์šด์˜์ž๊ฐ€ <b>์ค‘๊ฐœ</b>ํ•ฉ๋‹ˆ๋‹ค.
322
- ์ œ์ถœ์ž์˜ ์‹ ์›์ด๋‚˜ ์—ฐ๋ฝ์ฒ˜๋Š” <b>๋ณธ์ธ ๋™์˜ ์—†์ด ์ „๋‹ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.</b></p>`,
323
- cols:{rank:"#",cand:"ํ›„๋ณด",user:"์ œ์ถœ์ž",who:"๋ชจ๋ธ",date:"์ œ์ถœ์ผ",
324
- oxidation:"์‚ฐํ™”",li_stability:"Li์•ˆ์ •",migration:"์ด๋™",novelty:"์‹ ๊ทœ",total:"์ด์ "},
325
- counts:(a,b,h)=>`์ฑ„์  ${a} ยท ๊ธฐ์ค€๋ฌผ์งˆ ${b}` + (h ? ` ยท ๋ฏธ์‚ฐ์ถœ ${h}` : ""),
326
- prange:(a,b,n)=>`${a.toLocaleString()}โ€“${b.toLocaleString()} / ์ „์ฒด ${n.toLocaleString()}`,
327
- empty:"์•„์ง ์ฑ„์ ๋œ ์ œ์ถœ์ด ์—†์Šต๋‹ˆ๋‹ค.",
328
- fail:"์ˆœ์œ„ํ‘œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค: ",
329
- ok:(id,q)=>`์ ‘์ˆ˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ›„๋ณด ID <b>${id}</b> ยท ๋Œ€๊ธฐ ${q}๊ฑด`,
330
- need:"์กฐ์„ฑ๊ณผ ํ‘œ์‹œ ID๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.",
331
- hold:"๋ฏธ์‚ฐ์ถœ",
332
- holds:{need_structure:"๊ตฌ์กฐ ํ•„์š”", no_reference:"๋น„๊ต์ž๋ฃŒ ๋ถ€์กฑ", no_value:"์‚ฐ์ถœ ๋ถˆ๊ฐ€"},
333
- holdnote:"์•„๋ž˜ ์š”๊ฑด์„ ๊ฐ–์ถฐ ๋‹ค์‹œ ์ œ์ถœํ•˜์‹œ๋ฉด ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค."
334
- },
335
- en:{
336
- sub:"Open problems, worked on together โ€” materials discovery anyone can join",
337
- about_h:"What this is",
338
- about:`<p>A solid-state battery replaces the liquid electrolyte of a lithium-ion cell with a solid.
339
- It can be safer and last longer, but finding a material that is <b>solid and still lets lithium through</b>
340
- remains unsolved.</p>
341
- <p>This challenge looks for candidates. You submit <b>one composition</b> โ€” for example <code>Li3YCl6</code>.
342
- We score it computationally and place it on the board. There is no prize.</p>`,
343
- honest:`<b>What this season scores.</b> <b>Electrochemical robustness</b>: whether the material holds up at
344
- high voltage, survives contact with lithium metal, and has a path for lithium to move through.
345
- <b>Ionic conductivity is not a scored axis this season.</b> A highly conductive family therefore still
346
- scores low if its oxidation window is narrow or it reacts with lithium metal โ€” those two are the problem
347
- this season puts to you.
348
- Every value is a <b>computational estimate</b> and implies nothing about real performance or safety.`,
349
- guide_h:"How to take part",
350
- guide_lead:`In a solid-state cell the lithium ion has to travel <b>through a solid</b>. That same solid
351
- must <b>block electrons</b>, hold up at the charging voltage, and survive contact with the
352
- <b>lithium metal</b> anode without decomposing. Meeting all four in one material is the open problem.`,
353
- facts:[
354
- ["Target", "A solid with a path for lithium to move through. It must contain lithium."],
355
- ["Get past this", "If electrons pass, the cell simply shorts. Electronic insulation is a precondition."],
356
- ["Hardest part", "Oxidation stability and lithium-metal stability pull against each other. Holding both is the task."],
357
- ["Submission", "One composition. A structure (CIF) is optional and makes scoring faster and more accurate."]],
358
- guide_how:`<p style="margin:14px 0 2px">Paste a prompt below into the model you use. Hit <b>Copy</b>,
359
- then change the italicised part to something of your own โ€” otherwise your candidates will collide with
360
- other entrants'. Submit the compositions it returns, one at a time, on the right.</p>`,
361
- models_h:"By model",
362
- models_lead:`Which model produced the <b>best candidate</b> (bar) and <b>how often it is used</b> (right).
363
- Being used a lot is not the same as doing well, so the two are shown separately.`,
364
- mempty:"Model standings appear here once scored entries accumulate.",
365
- mcounts:(m,n)=>`${m} models ยท ${n} entries`,
366
- mlegend:`<span><i></i>Best score</span><span><u></u>Mean</span><span>Entries</span>`,
367
- tabs:{board:"Challenge ยท Board", guide:"How to take part", models:"By model"},
368
- divs:{all:"All", fluoride:"Fluoride", halide:"Chloride / bromide / iodide", sulfide:"Sulfide",
369
- oxide:"Oxide", nitride:"Nitride", hydride:"Hydride", other:"Other"},
370
- divnote:"Divisions follow the anion framework. <b>Scores are identical across divisions</b> - the split is there so you can compare within a chemical family.",
371
- xlink:`๐Ÿงช <b>Open Discovery Challenge</b> <em>โ€” the sister challenge, for drug candidates</em> โ†—`,
372
- sinfo:(o,c)=>[`Season <b>${o} โ€“ ${c}</b>`,`Prize <b>none</b>`,`Submit <b>one composition</b>`],
373
- axhelp:[
374
- ["Oxidation","How well the electrolyte itself resists decomposing as the cell voltage rises."],
375
- ["Li-metal stability","How well it survives contact with a lithium-metal anode."],
376
- ["Use novelty","Higher when the composition has not been reported as a solid electrolyte."],
377
- ["Lithium pathway","Not a score but an <b>entry condition</b>: without a percolating path for lithium, an entry is not accepted."]],
378
- limits:(L)=>`Limits โ€” lithium required ยท at most ${L.max_atoms} atoms in the reduced composition ยท
379
- at most 6 elements. Re-submitting the same material as an integer multiple counts as the same entry.`,
380
- detail_h:"How this was scored",
381
- board_h:"Leaderboard",
382
- boardnote:`<b>Reference materials (amber rows)</b> are scored but hold no rank. They are there so you can see
383
- where materials in actual use land.<br>
384
- Private entries show <b>elements only</b>; the composition is held back.<br>
385
- <b>Structure needed / no reference data</b> means the requirements for scoring are not yet met.
386
- Nothing is recorded as zero and no rank is assigned - an unmeasured entry is not given a standing.
387
- <b>Most cases are scored once a structure file (CIF) is attached and the entry resubmitted.</b>
388
- Click the row to see what is required.<br>
389
- Click a column header to sort.`,
390
- submit_h:"Submit",
391
- l_formula:"Composition (formula)", l_name:"Display ID (name, affiliation or handle)",
392
- l_model:"Model used (optional)", l_cif:"Structure file, CIF (optional)",
393
- l_why:"Design rationale (optional)", l_vis:"Visibility",
394
- cifnote:`Including a structure makes scoring faster and more accurate. Without one we estimate the
395
- structure; where that is not possible the entry is marked <b>structure needed</b> and is scored
396
- once a structure is attached and it is resubmitted.`,
397
- priv:"๐Ÿ”’ Private (default)", pub:"๐Ÿ”“ Show composition",
398
- go:"Submit",
399
- gate:"Submitting requires a <b>Hugging Face sign-in</b>. Your account appears alongside the entry, which stops anyone posting under another person's name and keeps the per-model standings trustworthy.",
400
- signin:"Sign in with Hugging Face", signout:"Sign out", signed_as:"Signed in as",
401
- broker_h:"Record of submission, and third-party contact",
402
- broker:`<p>Entries are recorded with a timestamp in our ledger. A <b>private</b> composition stays with us and
403
- is not disclosed unless you choose to publish it. This record may serve as a reference later, but it
404
- <b>is not a patent filing and carries no guaranteed legal effect.</b> Consult a professional before filing.</p>
405
- <p>If a third party asks to discuss a specific entry, we pass the request along. We never share a
406
- submitter's identity or contact details <b>without their consent.</b></p>`,
407
- cols:{rank:"#",cand:"Entry",user:"Submitter",who:"Model",date:"Date",
408
- oxidation:"Oxid.",li_stability:"Li-stab.",migration:"Migration",novelty:"Novelty",total:"Total"},
409
- counts:(a,b,h)=>`${a} scored ยท ${b} references` + (h ? ` ยท ${h} not scored` : ""),
410
- prange:(a,b,n)=>`${a.toLocaleString()}โ€“${b.toLocaleString()} of ${n.toLocaleString()}`,
411
- empty:"No entries have been scored yet.",
412
- fail:"Could not load the leaderboard: ",
413
- ok:(id,q)=>`Accepted. Entry <b>${id}</b> ยท ${q} in queue`,
414
- need:"Please enter a composition and a display ID.",
415
- hold:"not scored",
416
- holds:{need_structure:"structure needed", no_reference:"no reference data", no_value:"no value"},
417
- holdnote:"Meet the requirement below and resubmit; the entry will then be scored."
418
- }
419
- };
420
-
421
- // ํ”„๋กฌํ”„ํŠธ๋Š” **๋ชฉํ‘œ**๋งŒ ๋งํ•œ๋‹ค. ๋ฌด์—‡์„ ์–ด๋–ป๊ฒŒ ์žฌ๋Š”์ง€๋Š” ์ ์ง€ ์•Š๋Š”๋‹ค - ์ ์œผ๋ฉด ๋ฌผ์งˆ์ด ์•„๋‹ˆ๋ผ
422
- // ์ฑ„์ ๊ธฐ๋ฅผ ๊ฒจ๋ƒฅํ•œ ์ œ์ถœ์ด ๋“ค์–ด์˜จ๋‹ค.
423
- const PROMPTS_BY_SEASON = {
424
- 1: [
425
- {id:"A", ko:["๊ธฐ๋ณธํ˜•","์ฒ˜์Œ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด ์ด๊ฒƒ๋ถ€ํ„ฐ"], en:["Starter","Begin here"],
426
- body:`You are proposing candidate solid electrolytes for an all-solid-state lithium battery,
427
- for an open materials challenge.
428
-
429
- Requirements for every candidate:
430
- - Contains lithium, with a plausible connected pathway for Li+ to migrate through the
431
- lattice.
432
- - An electronic insulator. If electrons conduct, the cell short-circuits; this is a
433
- precondition, not a trade-off.
434
- - Wide electrochemical window: stable against oxidation at high cell voltage.
435
- - Stable in contact with lithium metal at the anode, or decomposing only into a passivating
436
- layer rather than an electronically conductive one.
437
- - Plausibly synthesisable: a composition close to a stable phase, not an exotic guess.
438
-
439
- Propose 8 candidate compositions as a JSON array:
440
- [{"formula":"...","name":"...","rationale":"why lithium should move through it, why it
441
- should not conduct electrons, and how it behaves against lithium metal"}]
442
-
443
- Use plain chemical formulae, e.g. Li3YCl6 or LiZr2(PO4)3.
444
-
445
- <em>VARY THIS: name a chemical family you want to explore (halides, oxides, phosphates,
446
- oxyhalides, anti-perovskites, โ€ฆ) or a constraint of your own, so your set does not collide
447
- with other entrants'. Identical submissions are rejected.</em>`},
448
-
449
- {id:"B", ko:["์‚ฐํ™” ์•ˆ์ •์„ฑ","๋†’์€ ์ „์••์„ ๊ฒฌ๋””๋Š” ์„ค๊ณ„ (40์ )"], en:["Oxidation","Holding up at high voltage (40 pts)"],
450
- body:`Propose solid lithium-ion electrolytes designed specifically for a WIDE oxidation
451
- window, so they survive against a high-voltage cathode.
452
-
453
- Reason from this:
454
- - The anion is usually what oxidises first. Sulfide frameworks conduct well but oxidise at
455
- low potential; more electronegative anions push the oxidation limit higher.
456
- - The counter-cation matters: a cation already in a high oxidation state has less room to
457
- be oxidised further.
458
- - A material that resists oxidation but has no lithium pathway is worthless. A connected
459
- migration path is a precondition, not a trade-off.
460
-
461
- For each candidate state explicitly: which anion framework you chose and why you expect it
462
- to resist oxidation, and how lithium still moves through it.
463
-
464
- Propose 8 candidates as JSON: [{"formula","name","rationale"}]
465
-
466
- <em>VARY THIS: commit to ONE anion chemistry and build the whole set around it, rather than
467
- eight unrelated guesses.</em>`},
468
-
469
- {id:"C", ko:["๋ฆฌํŠฌ๊ธˆ์† ์•ˆ์ •์„ฑ","์Œ๊ทน์—์„œ ๋ฒ„ํ‹ฐ๋Š” ์„ค๊ณ„ (35์ )"], en:["Lithium-metal stability","Surviving the anode (35 pts)"],
470
- body:`Propose solid lithium-ion electrolytes designed to survive direct contact with
471
- LITHIUM METAL.
472
-
473
- Reason from this:
474
- - Lithium metal is strongly reducing. Any cation in the electrolyte that can be reduced
475
- will be. Transition metals in high oxidation states are the classic failure: they reduce,
476
- the interface becomes electronically conductive, and the reaction never stops.
477
- - The useful case is a decomposition product that is itself an insulator, so the interface
478
- passivates and the reaction halts.
479
- - Wide oxidation window alone does not help if the anode side fails. Both ends of the
480
- window matter.
481
-
482
- For each candidate state explicitly: which element you expect lithium metal to attack, and
483
- why the interface should stop reacting rather than keep going.
484
-
485
- Propose 8 candidates as JSON: [{"formula","name","rationale"}]
486
-
487
- <em>VARY THIS: choose one strategy โ€” reduction-proof cations, or a self-passivating
488
- decomposition product โ€” and build the set around it.</em>`},
489
-
490
- {id:"D", ko:["์šฉ๋„ ์‹ ๊ทœ์„ฑ","๊ฐ€์žฅ ํฐ ์ ์ˆ˜ ์—ฌ์ง€ (25์ )"], en:["Use novelty","Where the headroom is (25 pts)"],
491
- body:`Propose lithium-containing compositions that are NOT already reported as solid
492
- electrolytes.
493
-
494
- Important distinction: the composition does not have to be brand new. What matters is
495
- whether anyone has proposed it FOR THIS USE. A known compound that nobody has evaluated as
496
- a lithium electrolyte is exactly the target; a well-studied electrolyte family is not.
497
-
498
- So avoid the ones already worked over โ€” the common sulfide, garnet, NASICON and
499
- argyrodite electrolyte families โ€” and look at lithium compounds studied for other reasons
500
- entirely, or not studied much at all.
501
-
502
- Every candidate must still meet the basics: a lithium migration path, electronic
503
- insulation, and reasonable stability at both electrodes. Novelty with no function scores
504
- nothing.
505
-
506
- For each candidate state: what the composition is normally known for (if anything), and
507
- why it might work as an electrolyte.
508
-
509
- Propose 8 candidates as JSON: [{"formula","name","rationale"}]
510
-
511
- <em>VARY THIS: pick one source of overlooked compounds โ€” a mineral class, a family studied
512
- for optics or ionics elsewhere, a ternary system that is sparsely mapped โ€” and work it.</em>`}
513
- ]
514
- };
515
-
516
- const $ = s => document.querySelector(s);
517
- const COLS = ["rank","cand","user","who","date","oxidation","li_stability","novelty","total"];
518
- // ํ‘œ๊ฐ€ ์ปค์ง€๋ฉด ํ•œ๊บผ๋ฒˆ์— ๊ทธ๋ฆฌ์ง€ ์•Š๊ณ  ํ•œ ํŽ˜์ด์ง€์”ฉ ๊ทธ๋ฆฐ๋‹ค.
519
- const PAGE_SIZE = 500;
520
- let LANG = "ko", DATA = null, SEASONS = [], SEASON = 1;
521
- let sortKey = "total", sortDir = -1, page = 0, DIV = "all";
522
- const t = () => T[LANG];
523
-
524
- let ME = null;
525
-
526
- function renderAuth(){
527
- const d = t(), g = $("#gate"), m = $("#me");
528
- if(!ME || !ME.oauth_configured){ g.style.display="none"; m.innerHTML=""; return; }
529
- if(ME.signed_in && ME.user){
530
- g.style.display = "none";
531
- const u = ME.user;
532
- const pic = u.picture ? `<img src="${esc(u.picture)}" alt="">` : "๐Ÿค—";
533
- m.innerHTML = `${pic}<span>${d.signed_as} ${hfProfile(u.name)}</span>`
534
- + `<a class="signin out" href="/logout" style="margin-left:auto">${esc(d.signout)}</a>`;
535
- } else {
536
- g.style.display = "block";
537
- g.innerHTML = d.gate;
538
- m.innerHTML = `<a class="signin" href="/login">๐Ÿค— ${esc(d.signin)}</a>`;
539
- }
540
- }
541
-
542
- function hfProfile(user){
543
- if(!user) return "";
544
- const url = `https://huggingface.co/${encodeURIComponent(user)}`;
545
- return `<a class="hf-user" href="${url}" target="_blank" rel="noopener noreferrer"`
546
- + ` title="Hugging Face: ${esc(user)}">๐Ÿค— ${esc(user)}</a>`;
547
- }
548
-
549
- function esc(s){ return String(s ?? "").replace(/[&<>"']/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c])); }
550
-
551
- function setLang(l){
552
- LANG = l;
553
- document.documentElement.lang = l;
554
- document.querySelectorAll("#langbar button").forEach(b=>b.classList.toggle("on", b.dataset.lang===l));
555
- const d = t();
556
- $("#t_sub").textContent = d.sub;
557
- $("#t_about_h").textContent = d.about_h;
558
- $("#t_about").innerHTML = d.about;
559
- $("#t_honest").innerHTML = d.honest;
560
- $("#t_board_h").textContent = d.board_h;
561
- $("#t_boardnote").innerHTML = d.boardnote;
562
- $("#t_submit_h").textContent = d.submit_h;
563
- $("#t_broker_h").textContent = d.broker_h;
564
- $("#t_broker").innerHTML = d.broker;
565
- $("#t_cifnote").innerHTML = d.cifnote;
566
- $("#xlink").innerHTML = d.xlink;
567
- renderAuth();
568
- $("#t_guide_h").textContent = d.guide_h;
569
- $("#t_guide_lead").innerHTML = d.guide_lead;
570
- $("#t_guide_how").innerHTML = d.guide_how;
571
- $("#t_models_h").textContent = d.models_h;
572
- $("#t_models_lead").innerHTML = d.models_lead;
573
- renderFacts();
574
- renderPrompts();
575
- renderTabs();
576
- renderSeasonInfo();
577
- renderAxHelp();
578
- $("#t_priv").textContent = d.priv;
579
- $("#t_pub").textContent = d.pub;
580
- $("#go").textContent = d.go;
581
- for(const k of ["formula","name","model","cif","why","vis"]) $("#l_"+k).textContent = d["l_"+k];
582
- const g = $("#gate"); if(g.style.display !== "none") g.innerHTML = d.gate;
583
- renderSeasonBar();
584
- if(DATA) render();
585
- }
586
- document.querySelectorAll("#langbar button").forEach(b=>b.onclick=()=>setLang(b.dataset.lang));
587
-
588
- function renderSeasonBar(){
589
- $("#seasonbar").innerHTML = SEASONS.slice().sort((a,b)=>b.number-a.number).map(s=>{
590
- const nm = LANG==="ko" ? (s.topic_ko||s.topic) : s.topic;
591
- return `<button data-season="${s.number}" class="${s.number===SEASON?"on":""}">
592
- #${s.number} ${esc(nm)}</button>`;
593
- }).join("");
594
- document.querySelectorAll("#seasonbar button").forEach(b=>
595
- b.onclick=()=>{ SEASON=parseInt(b.dataset.season,10); page=0;
596
- renderSeasonBar(); renderPrompts(); renderSeasonInfo(); renderAxHelp();
597
- MODELS_LOADED = false; load(); if(TAB==="models"){ MODELS_LOADED=true; loadModels(); } });
598
- }
599
-
600
- function sortVal(e,k){
601
- if(k==="rank") return e.rank ?? 1e9;
602
- if(k==="cand") return String(e.candidate_id||"").toLowerCase();
603
- if(k==="user") return String(e.hf_user||e.display_name||"").toLowerCase();
604
- if(k==="who") return String(e.model_name||"").toLowerCase();
605
- if(k==="date") return e.submitted_at ?? 0;
606
- if(k==="total") return e.total ?? -1;
607
- return (e.axes||{})[k] ?? -1;
608
- }
609
-
610
- let TAB = "board";
611
-
612
- function renderTabs(){
613
- const d = t();
614
- $("#tabbar").innerHTML = ["board","guide","models"].map(k=>
615
- `<button data-tab="${k}" class="${k===TAB?"on":""}">${esc(d.tabs[k])}</button>`).join("");
616
- $("#tabbar").querySelectorAll("button").forEach(b=>b.onclick=()=>{
617
- TAB = b.dataset.tab; renderTabs(); showTab();
618
- window.scrollTo({top:0,behavior:"smooth"});
619
- });
620
- }
621
-
622
- function showTab(){
623
- document.querySelectorAll("section[data-tab]").forEach(sec=>{
624
- sec.hidden = sec.dataset.tab !== TAB;
625
- });
626
- // ๋ชจ๋ธ ์ง‘๊ณ„๋Š” ๊ทธ ํƒญ์„ ์—ด ๋•Œ ์ฒ˜์Œ ๋ถ€๋ฅธ๋‹ค. ์•ˆ ๋ณด๋Š” ํ™”๋ฉด์„ ์œ„ํ•ด ๋งค๋ฒˆ ๋ฐ›์•„์˜ฌ ์ด์œ ๊ฐ€ ์—†๋‹ค.
627
- if(TAB==="models" && !MODELS_LOADED){ MODELS_LOADED = true; loadModels(); }
628
- }
629
- let MODELS_LOADED = false;
630
-
631
- function seasonInfo(){ return SEASONS.find(x=>x.number===SEASON) || SEASONS[0] || {}; }
632
-
633
- function renderSeasonInfo(){
634
- const si = seasonInfo(), d = t();
635
- if(!si.opens){ $("#sinfo").innerHTML=""; return; }
636
- $("#sinfo").innerHTML = d.sinfo(si.opens, si.closes).map(x=>`<span>${x}</span>`).join("");
637
- }
638
-
639
- function renderAxHelp(){
640
- const d = t();
641
- $("#axhelp").innerHTML = (d.axhelp||[]).map(([k,v])=>
642
- `<div><b>${esc(k)}</b> โ€” ${esc(v)}</div>`).join("");
643
- const L = (seasonInfo().limits)||{};
644
- $("#t_limits").innerHTML = L.max_atoms ? d.limits(L) : "";
645
- }
646
-
647
- function promptsFor(){ return PROMPTS_BY_SEASON[SEASON] || PROMPTS_BY_SEASON[1]; }
648
-
649
- function renderPrompts(){
650
- const d = t(), host = $("#prompts");
651
- if(!host) return;
652
- host.innerHTML = promptsFor().map((p,i)=>{
653
- const [title,sub] = (LANG==="ko" ? p.ko : p.en);
654
- return `<div class="pcard">
655
- <div class="phead"><span class="ptag">${p.id}</span><b>${esc(title)}</b><span>${esc(sub)}</span>
656
- <button class="pcopy" data-i="${i}">${LANG==="ko"?"๋ณต์‚ฌ":"Copy"}</button></div>
657
- <div class="pbody">${p.body.trim()}</div></div>`;
658
- }).join("");
659
- host.querySelectorAll(".pcopy").forEach(b=>b.onclick=async()=>{
660
- // ๊ฐ•์กฐ ํ‘œ์‹œ๋Š” ํ™”๋ฉด์šฉ์ด๋‹ค. ํด๋ฆฝ๋ณด๋“œ์—๋Š” ๊นจ๋—ํ•œ ๋ณธ๋ฌธ๋งŒ ๋„ฃ๋Š”๋‹ค.
661
- const raw = promptsFor()[+b.dataset.i].body.replace(/<\/?em>/g,"").trim();
662
- try{ await navigator.clipboard.writeText(raw); }
663
- catch(_){ const ta=document.createElement("textarea"); ta.value=raw;
664
- document.body.appendChild(ta); ta.select(); document.execCommand("copy"); ta.remove(); }
665
- const was=b.textContent;
666
- b.textContent = LANG==="ko" ? "๋ณต์‚ฌ๋จ โœ“" : "Copied โœ“";
667
- setTimeout(()=>{ b.textContent=was; },1500);
668
- });
669
- }
670
-
671
- function renderFacts(){
672
- const d = t();
673
- $("#facts").innerHTML = (d.facts||[]).map(([k,v])=>
674
- `<div class="fact"><b>${esc(k)}</b>${esc(v)}</div>`).join("");
675
- }
676
-
677
- function renderModels(m){
678
- const d = t(), host = $("#models");
679
- const rows = (m && m.models) || [];
680
- $("#mcounts").textContent = d.mcounts((m&&m.counts&&m.counts.models)||0,
681
- (m&&m.counts&&m.counts.entries)||0);
682
- $("#t_mlegend").innerHTML = d.mlegend;
683
- if(!rows.length){ host.innerHTML = `<div class="note">${d.mempty}</div>`; return; }
684
- const max = Math.max(...rows.map(r=>r.best), 1);
685
- host.innerHTML = rows.slice(0,14).map(r=>`
686
- <div class="mrow">
687
- <div class="mname" title="${esc(r.model)}">${esc(r.model)}</div>
688
- <div class="mbar"><i style="width:${(r.best/max*100).toFixed(1)}%"></i>
689
- <u style="left:${(r.mean/max*100).toFixed(1)}%"></u></div>
690
- <div class="mnum">${r.best.toFixed(1)} ยท ${r.n}</div>
691
- </div>`).join("");
692
- }
693
-
694
- async function loadModels(){
695
- try{ renderModels(await (await fetch(`/api/models?season=${SEASON}`)).json()); }
696
- catch(e){ renderModels(null); }
697
- }
698
-
699
- function renderDivBar(){
700
- const d = t(), host = $("#divbar");
701
- const tally = (DATA && DATA.divisions) || {};
702
- const keys = Object.keys(tally).sort((a,b)=>(tally[b]||0)-(tally[a]||0));
703
- if(!keys.length){ host.innerHTML=""; return; }
704
- const total = Object.values(tally).reduce((a,b)=>a+b,0);
705
- const btn = (k,n)=>`<button data-d="${k}" class="${k===DIV?"on":""}">${esc(d.divs[k]||k)}<span class="dn">${n}</span></button>`;
706
- host.innerHTML = btn("all",total) + keys.map(k=>btn(k,tally[k])).join("");
707
- host.querySelectorAll("button[data-d]").forEach(b=>b.onclick=()=>{
708
- DIV=b.dataset.d; page=0; render();
709
- });
710
- }
711
-
712
- function renderPager(total,pages){
713
- const host = $("#pager"), d = t();
714
- if(pages<=1){ host.innerHTML=""; return; }
715
- const from = page*PAGE_SIZE+1, to = Math.min(total,(page+1)*PAGE_SIZE);
716
- let nums=[];
717
- if(pages<=9){ for(let i=0;i<pages;i++) nums.push(i); }
718
- else{
719
- const near=[page-1,page,page+1].filter(i=>i>0&&i<pages-1);
720
- nums=[...new Set([0,...near,pages-1])].sort((a,b)=>a-b);
721
- }
722
- let out=`<button ${page===0?"disabled":""} data-p="${page-1}">โ€น</button>`, prev=-1;
723
- for(const i of nums){
724
- if(i-prev>1) out+=`<span class="gap">โ€ฆ</span>`;
725
- out+=`<button class="${i===page?"on":""}" data-p="${i}">${i+1}</button>`; prev=i;
726
- }
727
- out+=`<button ${page>=pages-1?"disabled":""} data-p="${page+1}">โ€บ</button>`;
728
- out+=`<span class="pinfo">${d.prange(from,to,total)}</span>`;
729
- host.innerHTML=out;
730
- host.querySelectorAll("button[data-p]").forEach(b=>b.onclick=()=>{
731
- if(b.disabled) return;
732
- page=parseInt(b.dataset.p,10); render();
733
- const c=document.querySelector(".card .scroll");
734
- if(c) window.scrollTo({top:c.getBoundingClientRect().top+window.scrollY-80,behavior:"smooth"});
735
- });
736
- }
737
-
738
- function render(){
739
- const d = t(), W = (DATA.season && DATA.season.weights) || {};
740
- $("#wts").innerHTML = Object.entries(W)
741
- .map(([k,v])=>`<span>${esc(d.cols[k]||k)} <b>${v}</b></span>`).join("");
742
- $("#counts").textContent = d.counts(DATA.counts.scored, DATA.counts.anchors, DATA.counts.held || 0);
743
-
744
- $("#head").innerHTML = COLS.map(k=>{
745
- const on = sortKey===k, ar = on ? (sortDir<0?"โ–ผ":"โ–ฒ") : "โ–พ";
746
- return `<th data-k="${k}" class="${on?"sorted":""}">${esc(d.cols[k]||k)}<span class="ar">${ar}</span></th>`;
747
- }).join("");
748
- document.querySelectorAll("#head th").forEach(th=>th.onclick=()=>{
749
- const k=th.dataset.k;
750
- if(sortKey===k) sortDir=-sortDir;
751
- else { sortKey=k; sortDir=(k==="rank"||k==="cand"||k==="who")?1:-1; }
752
- page=0; render();
753
- });
754
-
755
- renderDivBar();
756
- // ๋ถ€๋ฌธ์„ ๊ณ ๋ฅด๋ฉด ๊ทธ ๋ถ€๋ฌธ + ๊ธฐ์ค€๋ฌผ์งˆ๋งŒ ๋‚จ๊ธด๋‹ค. ๊ธฐ์ค€๋ฌผ์งˆ์€ ์ฒ™๋„๋ผ ํ•ญ์ƒ ๋ณด์—ฌ์•ผ ํ•œ๋‹ค.
757
- const pool = DIV==="all" ? DATA.entries
758
- : DATA.entries.filter(e=>e.is_anchor || e.division===DIV);
759
- const all = pool.slice().sort((a,b)=>{
760
- const x=sortVal(a,sortKey), y=sortVal(b,sortKey);
761
- if(x<y) return -sortDir; if(x>y) return sortDir; return 0;
762
- });
763
- const pages = Math.max(1, Math.ceil(all.length/PAGE_SIZE));
764
- if(page>=pages) page=pages-1;
765
- if(page<0) page=0;
766
- const rows = all.slice(page*PAGE_SIZE, page*PAGE_SIZE+PAGE_SIZE);
767
- renderPager(all.length, pages);
768
-
769
- { const bn = $("#t_boardnote"); if(bn) bn.innerHTML = d.boardnote + "<br>" + d.divnote; }
770
- $("#rows").innerHTML = rows.length ? rows.map(e=>{
771
- const a = e.axes||{};
772
- const unscored = !e.is_anchor && (e.total == null || (e.held_axes||[]).length > 0);
773
- const cls = [e.is_anchor?"anchor":"", unscored?"held":""].join(" ").trim();
774
- const who = e.is_anchor ? esc(e.display_name)
775
- : (e.hf_user ? hfProfile(e.hf_user)
776
- : `<span title="${esc(e.display_name||"")}">${esc(e.display_name||"โ€“")}</span>`);
777
- const num = k => {
778
- const v = a[k];
779
- return `<td class="num">${v==null?`<span class="pill">${d.hold}</span>`:v.toFixed(1)}</td>`;
780
- };
781
- const dt = e.submitted_at ? new Date(e.submitted_at*1000).toISOString().slice(0,10) : "";
782
- const hk = e.hold_kind && d.holds[e.hold_kind];
783
- const tot = e.total==null ? `<span class="pill warn">${esc(hk || d.hold)}</span>`
784
- : `${e.total.toFixed(1)}<span class="sub" style="font-size:11px"> /${e.total_max||100}</span>`
785
- + (unscored ? ` <span class="pill warn">${esc(hk || d.hold)}</span>` : "");
786
- const has = (e.detail && Object.keys(e.detail).length) || (unscored && e.gate);
787
- return `<tr class="${cls}${has?" pick":""}"${has?` data-i="${e.candidate_id}"`:""}>
788
- <td class="num">${(DIV==="all" ? e.rank : e.div_rank) ?? "โ€”"}</td>
789
- <td>${esc(e.formula||e.candidate_id||"")}${e.masked?' <span class="pill">๐Ÿ”’</span>':""}</td>
790
- <td>${who}</td><td>${esc(e.model_name||"")}</td><td>${dt}</td>
791
- ${num("oxidation")}${num("li_stability")}${num("novelty")}
792
- <td class="num"><b>${tot}</b></td></tr>`;
793
- }).join("") : `<tr><td colspan="${COLS.length}" class="sub">${d.empty}</td></tr>`;
794
-
795
- // ์ฑ„์  ๊ทผ๊ฑฐ๋Š” ์ด๋ฏธ ์‘๋‹ต์— ๋“ค์–ด ์žˆ๋Š”๋ฐ ํ‘œ์—๋Š” ์•ˆ ๋ณด์˜€๋‹ค. ํ–‰์„ ๋ˆ„๋ฅด๋ฉด ์•„๋ž˜๋กœ ํŽผ์นœ๋‹ค.
796
- const byId = {}; rows.forEach(e=>{ if(e.candidate_id) byId[e.candidate_id]=e; });
797
- $("#rows").querySelectorAll("tr.pick").forEach(tr=>tr.onclick=()=>{
798
- const nxt = tr.nextElementSibling;
799
- if(nxt && nxt.classList.contains("det")){ nxt.remove(); return; }
800
- $("#rows").querySelectorAll("tr.det").forEach(x=>x.remove());
801
- const e = byId[tr.dataset.i]; if(!e) return;
802
- const items = Object.entries(e.detail||{})
803
- .map(([k,v])=>`<li><b>${esc(d.cols[k]||k)}</b> โ€” ${esc(v)}</li>`).join("")
804
- || (e.gate ? `<li>${esc(e.gate)}</li>` : "");
805
- const extra = (e.notes||[]).map(n=>`<li>${esc(n)}</li>`).join("");
806
- const note = e.note ? `<div style="margin-top:6px">${esc(e.note)}</div>`
807
- : (extra ? `<ul>${extra}</ul>` : "");
808
- const row = document.createElement("tr");
809
- row.className = "det";
810
- row.innerHTML = `<td colspan="${COLS.length}"><b>${esc(d.detail_h)}</b><ul>${items}</ul>${note}</td>`;
811
- tr.after(row);
812
- });
813
- }
814
-
815
- async function load(){
816
- try{
817
- const r = await fetch(`/api/leaderboard?season=${SEASON}`);
818
- DATA = await r.json();
819
- render();
820
- }catch(e){
821
- $("#rows").innerHTML = `<tr><td colspan="${COLS.length}" class="sub">${t().fail}${esc(e)}</td></tr>`;
822
- }
823
- }
824
-
825
- document.querySelectorAll('input[name="vis"]').forEach(r=>r.onchange=()=>{
826
- document.querySelectorAll("#visbox label").forEach(l=>l.classList.toggle("on", l.querySelector("input").checked));
827
- });
828
-
829
- $("#go").onclick = async () => {
830
- const d = t(), m = $("#msg");
831
- const formula = $("#f_formula").value.trim(), name = $("#f_name").value.trim();
832
- if(!formula || !name){ m.className="msg bad"; m.textContent=d.need; return; }
833
- $("#go").disabled = true;
834
- try{
835
- const r = await fetch("/api/submit",{method:"POST",headers:{"Content-Type":"application/json"},
836
- body:JSON.stringify({formula, display_name:name, model_name:$("#f_model").value.trim(),
837
- rationale:$("#f_why").value.trim(), structure:$("#f_cif").value.trim(),
838
- visibility:document.querySelector('input[name="vis"]:checked').value, season:SEASON})});
839
- const j = await r.json();
840
- if(!r.ok){ m.className="msg bad"; m.textContent = j.detail || ("HTTP "+r.status); }
841
- else{ m.className="msg ok"; m.innerHTML = d.ok(j.candidate_id, j.queue_position);
842
- $("#f_formula").value=""; $("#f_cif").value=""; load(); MODELS_LOADED=false; }
843
- }catch(e){ m.className="msg bad"; m.textContent=String(e); }
844
- $("#go").disabled = false;
845
- };
846
-
847
- (async function boot(){
848
- try{
849
- const s = await (await fetch("/api/seasons")).json();
850
- SEASONS = s.seasons || [];
851
- const open = SEASONS.filter(x=>x.open);
852
- SEASON = (open.length?open:SEASONS).slice(-1)[0]?.number || 1;
853
- }catch(e){}
854
- try{ ME = await (await fetch("/api/me")).json(); }catch(e){ ME = null; }
855
- renderAuth();
856
- setLang("ko");
857
- showTab();
858
- await load();
859
- setInterval(load, 20000);
860
- setInterval(()=>{ if(TAB==="models") loadModels(); }, 600000);
861
- })();
862
- </script>
863
- </body>
864
- </html>
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="ko">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <title>Open Materials Challenge #1 ์ „๊ณ ์ฒด ์ „ํ•ด์งˆ</title>
7
+ <!-- <head> ๋Š” ์„ ํƒ์ด ์•„๋‹ˆ๋‹ค: ํ”Œ๋žซํผ์ด ์ž๊ธฐ ํƒœ๊ทธ๋ฅผ ๋ฌธ์„œ์— ์ฃผ์ž…ํ•˜๋Š”๋ฐ, ๋ฐ›์„ head ๊ฐ€ ์—†์œผ๋ฉด
8
+ ๊ทธ๊ฒƒ๋“ค์ด doctype ์•ž์— ๋†“์ด๊ณ  ํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ ์ฟผํฌ ๋ชจ๋“œ๋กœ ๋–จ์–ด์ง„๋‹ค. -->
9
+ <style>
10
+ :root{
11
+ --bg:#f7f8fa; --card:#fff; --ink:#16181d; --muted:#6b7280; --line:#e5e7eb;
12
+ --accent:#1f6f4a; --accent-soft:#e8f3ed; --warn:#9a6700; --warn-soft:#fff8e1;
13
+ --anchor:#fffbe6; --anchor-line:#f2e3a8;
14
+ }
15
+ :root:not([data-theme="light"]){}
16
+ @media (prefers-color-scheme: dark){
17
+ :root:not([data-theme="light"]){
18
+ --bg:#101215; --card:#171a1f; --ink:#e8eaed; --muted:#9aa1ab; --line:#2a2f37;
19
+ --accent:#4bbb87; --accent-soft:#16281f; --warn:#e0b23c; --warn-soft:#2a2312;
20
+ --anchor:#241f10; --anchor-line:#4a4022;
21
+ }
22
+ }
23
+ :root[data-theme="dark"]{
24
+ --bg:#101215; --card:#171a1f; --ink:#e8eaed; --muted:#9aa1ab; --line:#2a2f37;
25
+ --accent:#4bbb87; --accent-soft:#16281f; --warn:#e0b23c; --warn-soft:#2a2312;
26
+ --anchor:#241f10; --anchor-line:#4a4022;
27
+ }
28
+ *{box-sizing:border-box}
29
+ body{margin:0;background:var(--bg);color:var(--ink);
30
+ font:15px/1.65 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans KR",sans-serif}
31
+ .wrap{max-width:1120px;margin:0 auto;padding:20px 16px 80px}
32
+ header{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin:8px 0 4px}
33
+ h1{font-size:22px;margin:0;letter-spacing:-.3px}
34
+ h2{font-size:17px;margin:0 0 10px;display:flex;align-items:baseline;gap:10px}
35
+ .sub{color:var(--muted);font-size:14px}
36
+ .card{background:var(--card);border:1px solid var(--line);border-radius:14px;
37
+ padding:18px 20px;margin:14px 0}
38
+ .grid{display:grid;grid-template-columns:1fr 360px;gap:14px;align-items:start}
39
+ @media (max-width:900px){.grid{grid-template-columns:1fr}}
40
+ .cnt{color:var(--muted);font-size:13px;font-weight:400;margin-left:auto}
41
+ #langbar,#seasonbar{display:flex;gap:6px;flex-wrap:wrap}
42
+ #langbar{margin-left:auto}
43
+ #langbar button,#seasonbar button{border:1px solid var(--line);background:var(--card);
44
+ color:var(--muted);border-radius:8px;padding:5px 12px;cursor:pointer;font:inherit;font-size:13px}
45
+ #langbar button.on,#seasonbar button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
46
+ .scroll{overflow-x:auto}
47
+ table{width:100%;border-collapse:collapse;font-size:13.5px;min-width:780px}
48
+ th,td{padding:8px 10px;text-align:left;border-bottom:1px solid var(--line);white-space:nowrap}
49
+ th{color:var(--muted);font-weight:600;font-size:12.5px;cursor:pointer;user-select:none}
50
+ th .ar{opacity:.4;margin-left:3px;font-size:10px}
51
+ th.sorted{color:var(--accent)} th.sorted .ar{opacity:1}
52
+ tr.anchor{background:var(--anchor)}
53
+ tr.anchor td{border-bottom-color:var(--anchor-line)}
54
+ td.num{text-align:right;font-variant-numeric:tabular-nums}
55
+ .pill{display:inline-block;padding:1px 7px;border-radius:999px;font-size:11.5px;
56
+ background:var(--accent-soft);color:var(--accent);border:1px solid transparent}
57
+ .note{color:var(--muted);font-size:12.5px;margin-top:12px;line-height:1.7}
58
+ .pager{display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;
59
+ padding:14px 4px 2px;font-size:13px}
60
+ .pager button{border:1px solid var(--line);background:var(--card);color:var(--muted);
61
+ border-radius:8px;padding:5px 11px;cursor:pointer;font:inherit;min-width:36px}
62
+ .pager button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
63
+ .pager button:disabled{opacity:.4;cursor:default}
64
+ .pager .pinfo{color:var(--muted);margin:0 8px}
65
+ .pager .gap{color:var(--muted);padding:0 2px}
66
+ label{display:block;font-size:13px;color:var(--muted);margin:12px 0 5px}
67
+ input,textarea,select{width:100%;padding:9px 11px;border:1px solid var(--line);
68
+ border-radius:9px;background:var(--bg);color:var(--ink);font:inherit;font-size:14px}
69
+ textarea{resize:vertical;min-height:64px}
70
+ .radio{display:flex;gap:8px;margin-top:6px}
71
+ .radio label{flex:1;display:flex;align-items:center;gap:7px;margin:0;padding:10px;
72
+ border:1px solid var(--line);border-radius:9px;cursor:pointer;font-size:13px;color:var(--ink)}
73
+ .radio label.on{border-color:var(--accent);background:var(--accent-soft)}
74
+ .go{width:100%;margin-top:16px;padding:12px;border:0;border-radius:10px;
75
+ background:var(--accent);color:#fff;font:inherit;font-size:15px;font-weight:600;cursor:pointer}
76
+ .go:disabled{opacity:.5;cursor:default}
77
+ .msg{margin-top:10px;padding:10px 12px;border-radius:9px;font-size:13px;display:none}
78
+ .msg.ok{display:block;background:var(--accent-soft);color:var(--accent)}
79
+ .msg.bad{display:block;background:var(--warn-soft);color:var(--warn)}
80
+ .callout{background:var(--warn-soft);border:1px solid var(--anchor-line);
81
+ border-radius:10px;padding:12px 14px;font-size:13px;color:var(--ink);margin:12px 0}
82
+ .axes{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0 2px}
83
+ .axes span{font-size:12.5px;color:var(--muted);background:var(--bg);
84
+ border:1px solid var(--line);border-radius:999px;padding:3px 10px}
85
+ .axes b{color:var(--ink)}
86
+ a{color:var(--accent)}
87
+ .badges{display:flex;gap:8px;flex-wrap:wrap;margin-top:6px}
88
+ .badges img{height:22px}
89
+ #divbar{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 12px}
90
+ #divbar button{border:1px solid var(--line);background:var(--card);color:var(--muted);
91
+ border-radius:999px;padding:4px 12px;cursor:pointer;font:inherit;font-size:12.5px}
92
+ #divbar button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
93
+ #divbar button .dn{opacity:.65;margin-left:5px;font-size:11.5px}
94
+ .hf-user{color:var(--accent);text-decoration:none;white-space:nowrap}
95
+ .hf-user:hover{text-decoration:underline}
96
+ .signin{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--accent);
97
+ background:var(--accent);color:#fff;border-radius:9px;padding:6px 13px;font-size:13px;
98
+ text-decoration:none;font-weight:600}
99
+ .signin.out{background:var(--card);color:var(--muted);border-color:var(--line);font-weight:400}
100
+ .me{display:flex;align-items:center;gap:9px;margin:10px 0 0;font-size:13px;color:var(--muted)}
101
+ .me img{width:22px;height:22px;border-radius:50%}
102
+ .xlink{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);
103
+ background:var(--card);border-radius:9px;padding:6px 12px;font-size:12.5px;
104
+ color:var(--muted);text-decoration:none;margin-top:8px}
105
+ .xlink:hover{border-color:var(--accent);color:var(--accent)}
106
+ .xlink b{color:var(--ink);font-weight:600}
107
+ .xlink em{font-style:normal;opacity:.75}
108
+ .lead{font-size:15px;margin:0 0 12px}
109
+ .sinfo{display:flex;gap:16px;flex-wrap:wrap;color:var(--muted);font-size:13px;margin:10px 0 0}
110
+ .sinfo b{color:var(--ink);font-weight:600}
111
+ #tabbar{display:flex;gap:2px;margin:16px 0 0;border-bottom:1px solid var(--line);flex-wrap:wrap}
112
+ #tabbar button{border:0;background:none;color:var(--muted);font:inherit;font-size:14px;
113
+ padding:9px 15px;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px}
114
+ #tabbar button:hover{color:var(--ink)}
115
+ #tabbar button.on{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}
116
+ #tabbar .tc{margin-left:5px;font-size:11.5px;opacity:.7}
117
+ .axhelp{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:8px;margin:12px 0 2px}
118
+ .axhelp div{font-size:12.5px;color:var(--muted);line-height:1.55}
119
+ .axhelp b{color:var(--ink)}
120
+ tr.det td{background:var(--bg);white-space:normal;font-size:12.5px;color:var(--muted);
121
+ border-bottom:1px solid var(--line)}
122
+ tr.det ul{margin:2px 0;padding-left:16px} tr.det li{margin:2px 0}
123
+ tr.held td{opacity:.72}
124
+ .pill.warn{background:var(--warn-soft);color:var(--warn)}
125
+ tr.pick{cursor:pointer}
126
+ tr.pick:hover td{background:var(--accent-soft)}
127
+ .facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px;margin:12px 0}
128
+ .fact{background:var(--bg);border:1px solid var(--line);border-radius:10px;padding:11px 13px;font-size:13px}
129
+ .fact b{display:block;color:var(--accent);font-size:12px;margin-bottom:3px}
130
+ .pcard{border:1px solid var(--line);border-radius:11px;margin:10px 0;overflow:hidden}
131
+ .phead{display:flex;align-items:center;gap:9px;padding:9px 13px;background:var(--bg);
132
+ border-bottom:1px solid var(--line);flex-wrap:wrap}
133
+ .ptag{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;
134
+ border-radius:6px;background:var(--accent);color:#fff;font-size:12px;font-weight:700}
135
+ .phead b{font-size:14px} .phead span{color:var(--muted);font-size:12.5px}
136
+ .pcopy{margin-left:auto;border:1px solid var(--line);background:var(--card);color:var(--muted);
137
+ border-radius:7px;padding:4px 11px;cursor:pointer;font:inherit;font-size:12px}
138
+ .pcopy:hover{border-color:var(--accent);color:var(--accent)}
139
+ .pbody{padding:12px 14px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
140
+ font-size:12.5px;line-height:1.6;white-space:pre-wrap;color:var(--ink);max-height:280px;overflow:auto}
141
+ .pbody em{color:var(--warn);font-style:normal;font-weight:600}
142
+ .mrow{display:grid;grid-template-columns:minmax(120px,1.4fr) 1fr auto;gap:10px;
143
+ align-items:center;padding:7px 0;border-bottom:1px solid var(--line);font-size:13px}
144
+ .mrow:last-child{border-bottom:0}
145
+ .mname{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
146
+ .mbar{position:relative;height:16px;background:var(--bg);border-radius:5px;overflow:hidden}
147
+ .mbar i{position:absolute;inset:0 auto 0 0;background:var(--accent);border-radius:5px}
148
+ .mbar u{position:absolute;top:0;bottom:0;width:2px;background:var(--ink);opacity:.55}
149
+ .mnum{font-variant-numeric:tabular-nums;color:var(--muted);white-space:nowrap;font-size:12.5px}
150
+ .mlegend{display:flex;gap:14px;color:var(--muted);font-size:12px;margin-top:10px;flex-wrap:wrap}
151
+ .mlegend i{display:inline-block;width:10px;height:10px;background:var(--accent);border-radius:2px;margin-right:4px}
152
+ .mlegend u{display:inline-block;width:2px;height:11px;background:var(--ink);opacity:.55;margin-right:4px;
153
+ vertical-align:-1px;text-decoration:none}
154
+ </style>
155
+ </head>
156
+ <body>
157
+ <div class="wrap">
158
+
159
+ <header>
160
+ <h1 id="t_title">Open Materials Challenge</h1>
161
+ <span class="sub" id="t_sub"></span>
162
+ <div id="langbar">
163
+ <button data-lang="ko" class="on">ํ•œ๊ตญ์–ด</button>
164
+ <button data-lang="en">English</button>
165
+ </div>
166
+ </header>
167
+ <div id="seasonbar" style="margin:14px 0 0"></div>
168
+ <div class="sinfo" id="sinfo"></div>
169
+ <a class="xlink" id="xlink" href="https://huggingface.co/spaces/FINAL-Bench/open-discovery-challenge" target="_blank" rel="noopener"></a>
170
+ <a class="xlink" id="xlink2" href="https://huggingface.co/spaces/FINAL-Bench/leadboard" target="_blank" rel="noopener"></a>
171
+ <div id="tabbar"></div>
172
+
173
+ <section data-tab="board">
174
+ <div class="card">
175
+ <h2 id="t_about_h"></h2>
176
+ <div id="t_about"></div>
177
+ <div class="axes" id="wts"></div>
178
+ <div class="axhelp" id="axhelp"></div>
179
+ <div class="callout" id="t_honest"></div>
180
+ </div>
181
+
182
+ </section>
183
+
184
+ <section data-tab="guide" hidden>
185
+ <div class="card">
186
+ <h2 id="t_guide_h"></h2>
187
+ <p class="lead" id="t_guide_lead"></p>
188
+ <div class="facts" id="facts"></div>
189
+ <div id="t_guide_how"></div>
190
+ <div id="prompts"></div>
191
+ </div>
192
+
193
+ </section>
194
+
195
+ <section data-tab="models" hidden>
196
+ <div class="card">
197
+ <h2><span id="t_models_h"></span><span class="cnt" id="mcounts"></span></h2>
198
+ <div id="t_models_lead" class="note" style="margin-top:0"></div>
199
+ <div id="models"></div>
200
+ <div class="mlegend" id="t_mlegend"></div>
201
+ </div>
202
+ </section>
203
+
204
+ <section data-tab="board" hidden>
205
+ <div class="grid">
206
+ <div class="card">
207
+ <h2><span id="t_board_h"></span><span class="cnt" id="counts"></span></h2>
208
+ <div id="divbar"></div>
209
+ <div class="scroll">
210
+ <table>
211
+ <thead><tr id="head"></tr></thead>
212
+ <tbody id="rows"></tbody>
213
+ </table>
214
+ </div>
215
+ <div class="pager" id="pager"></div>
216
+ <div class="note" id="t_boardnote"></div>
217
+ </div>
218
+
219
+ <div class="card">
220
+ <h2 id="t_submit_h"></h2>
221
+ <div id="gate" class="callout" style="display:none"></div>
222
+ <div class="me" id="me"></div>
223
+ <label id="l_formula"></label>
224
+ <input id="f_formula" placeholder="Li3YCl6">
225
+ <label id="l_name"></label>
226
+ <input id="f_name" placeholder="">
227
+ <label id="l_model"></label>
228
+ <input id="f_model" placeholder="anthropic/claude-โ€ฆ, Qwen/โ€ฆ">
229
+ <label id="l_cif"></label>
230
+ <textarea id="f_cif" placeholder="# generated using pymatgen&#10;data_โ€ฆ"></textarea>
231
+ <div class="note" id="t_cifnote" style="margin-top:4px"></div>
232
+ <label id="l_why"></label>
233
+ <textarea id="f_why"></textarea>
234
+ <label id="l_vis"></label>
235
+ <div class="radio" id="visbox">
236
+ <label class="on"><input type="radio" name="vis" value="private" checked><span id="t_priv"></span></label>
237
+ <label><input type="radio" name="vis" value="public"><span id="t_pub"></span></label>
238
+ </div>
239
+ <button class="go" id="go"></button>
240
+ <div class="msg" id="msg"></div>
241
+ <div class="note" id="t_limits"></div>
242
+ </div>
243
+ </div>
244
+
245
+ </section>
246
+
247
+ <section data-tab="board" hidden>
248
+ <div class="card">
249
+ <h2 id="t_broker_h"></h2>
250
+ <div id="t_broker"></div>
251
+ </div>
252
+ </section>
253
+
254
+ </div>
255
+ <script>
256
+ const T = {
257
+ ko:{
258
+ sub:"์ธ๋ฅ˜์˜ ๋‚œ์ œ๋ฅผ AI ์™€ ํ•จ๊ป˜ โ€” ๊ฐœ์ธ์ด ์ฐธ์—ฌํ•˜๋Š” ์‹ ์†Œ์žฌ ํƒ์ƒ‰",
259
+ about_h:"์ด ๋Œ€ํšŒ๋Š” ๋ฌด์—‡์ธ๊ฐ€",
260
+ about:`<p>์ „๊ณ ์ฒด ๋ฐฐํ„ฐ๋ฆฌ๋Š” ๋ฆฌํŠฌ์ด์˜จ ์ „์ง€์˜ ์•ก์ฒด ์ „ํ•ด์งˆ์„ ๊ณ ์ฒด๋กœ ๋ฐ”๊พผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋” ์•ˆ์ „ํ•˜๊ณ  ๋” ์˜ค๋ž˜ ๊ฐˆ ์ˆ˜ ์žˆ์ง€๋งŒ,
261
+ <b>๊ณ ์ฒด์ด๋ฉด์„œ ๋ฆฌํŠฌ๋งŒ ์ž˜ ํ†ต๊ณผ์‹œํ‚ค๋Š” ๋ฌผ์งˆ</b>์„ ์ฐพ๋Š” ์ผ์ด ์•„์ง ํ’€๋ฆฌ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.</p>
262
+ <p>์ด ๋Œ€ํšŒ๋Š” ๊ทธ ํ›„๋ณด ๋ฌผ์งˆ์„ ์ฐพ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ฐ€์ž๋Š” <b>์กฐ์„ฑ ํ•˜๋‚˜</b>๋ฅผ ๋ƒ…๋‹ˆ๋‹ค โ€” ์˜ˆ: <code>Li3YCl6</code>.
263
+ ์ €ํฌ๊ฐ€ ๊ณ„์‚ฐ์œผ๋กœ ์ฑ„์ ํ•ด ์ˆœ์œ„ํ‘œ์— ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค. ์ƒ๊ธˆ์€ ์—†์Šต๋‹ˆ๋‹ค.</p>`,
264
+ honest:`<b>์ด ์‹œ์ฆŒ์ด ์ฑ„์ ํ•˜๋Š” ๊ฒƒ.</b> <b>์ „๊ธฐํ™”ํ•™์  ๊ฐ•๊ฑด์„ฑ</b>์ž…๋‹ˆ๋‹ค โ€” ๋†’์€ ์ „์••์„ ๊ฒฌ๋””๋Š”์ง€,
265
+ ๋ฆฌํŠฌ ๊ธˆ์†์— ๋‹ฟ์•„๋„ ๋ฒ„ํ‹ฐ๋Š”์ง€, ๋ฆฌํŠฌ์ด ์ง€๋‚˜๊ฐˆ ๊ธธ์ด ๋šซ๋ ค ์žˆ๋Š”์ง€.
266
+ <b>์ด์˜จ์ „๋„๋„๋Š” ์ด๋ฒˆ ์‹œ์ฆŒ์˜ ์ฑ„์  ํ•ญ๋ชฉ์ด ์•„๋‹™๋‹ˆ๋‹ค.</b> ๋”ฐ๋ผ์„œ ์ „๋„๋„๊ฐ€ ๋†’์€ ๊ณ„์—ด์ด๋ผ๋„
267
+ ์‚ฐํ™”์ฐฝ์ด ์ข๊ฑฐ๋‚˜ ๋ฆฌํŠฌ ๊ธˆ์†๊ณผ ๋ฐ˜์‘ํ•˜๋ฉด ๋‚ฎ๊ฒŒ ๋‚˜์˜ต๋‹ˆ๋‹ค โ€” ๊ทธ ๋‘ ๊ฐ€์ง€๊ฐ€ ์ด ์‹œ์ฆŒ์ด ๋ฌป๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.
268
+ ๋ชจ๋“  ๊ฐ’์€ <b>๊ณ„์‚ฐ ์ถ”์ •์น˜</b>์ด๋ฉฐ ์‹ค์ œ ์„ฑ๋Šฅ์ด๋‚˜ ์•ˆ์ „์„ฑ์„ ๋œปํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.`,
269
+ guide_h:"์ฐธ๊ฐ€ ๊ฐ€์ด๋“œ",
270
+ guide_lead:`์ „๊ณ ์ฒด ์ „์ง€๋Š” ๋ฆฌํŠฌ ์ด์˜จ์ด <b>๊ณ ์ฒด ์•ˆ์„</b> ์ง€๋‚˜๊ฐ€์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ ๋ฌผ์งˆ์€ ๋™์‹œ์—
271
+ <b>์ „์ž๋Š” ํ†ต๊ณผ์‹œํ‚ค์ง€ ์•Š์•„์•ผ</b> ํ•˜๊ณ , ์ถฉ์ „ ์ „์••์„ ๊ฒฌ๋ŽŒ์•ผ ํ•˜๊ณ , ์Œ๊ทน์˜ <b>๋ฆฌํŠฌ ๊ธˆ์†</b>์— ๋‹ฟ์•„๋„
272
+ ๋ถ„ํ•ด๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋„ค ๊ฐ€์ง€๋ฅผ ํ•œ ๋ฌผ์งˆ์—์„œ ๋™์‹œ์— ๋งŒ์กฑ์‹œํ‚ค๋Š” ๊ฒƒ์ด ์•„์ง ํ’€๋ฆฌ์ง€ ์•Š์€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.`,
273
+ facts:[
274
+ ["ํ‘œ์ ", "๋ฆฌํŠฌ์ด ์ง€๋‚˜๊ฐˆ ํ†ต๋กœ๊ฐ€ ์žˆ๋Š” ๊ณ ์ฒด. ๋ฆฌํŠฌ์„ ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."],
275
+ ["๋„˜์–ด์•ผ ํ•  ๊ด€๋ฌธ", "์ „์ž๊ฐ€ ํ†ตํ•˜๋ฉด ์ „์ง€๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‹จ๋ฝ๋ฉ๋‹ˆ๋‹ค. ์ „์ž ์ ˆ์—ฐ์„ฑ์ด ์ „์ œ ์กฐ๊ฑด์ž…๋‹ˆ๋‹ค."],
276
+ ["๊ฐ€์žฅ ์–ด๋ ค์šด ๊ณณ", "์‚ฐํ™” ์•ˆ์ •์„ฑ๊ณผ ๋ฆฌํŠฌ๊ธˆ์† ์•ˆ์ •์„ฑ์€ ์„œ๋กœ ์ž˜ ์•ˆ ๋งž์Šต๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ์žก๋Š” ๊ฒƒ์ด ์ด ์‹œ์ฆŒ์˜ ๊ณผ์ œ์ž…๋‹ˆ๋‹ค."],
277
+ ["์ œ์ถœ", "์กฐ์„ฑ ํ•˜๋‚˜. ๊ตฌ์กฐ(CIF)๋Š” ์„ ํƒ์ด๋ฉฐ, ๋‚ด๋ฉด ์ฑ„์ ์ด ๋” ๋น ๋ฅด๊ณ  ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค."]],
278
+ guide_how:`<p style="margin:14px 0 2px">์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์“ฐ์‹œ๋Š” AI ๋ชจ๋ธ์— ๊ทธ๋Œ€๋กœ ๋„ฃ์œผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
279
+ <b>๋ณต์‚ฌ</b> ๋ฒ„ํŠผ์œผ๋กœ ๊ฐ€์ ธ๊ฐ€์‹  ๋’ค, ๊ธฐ์šธ์ž„์ฒด๋กœ ํ‘œ์‹œ๋œ ๋ถ€๋ถ„์€ ๋ณธ์ธ ๊ด€์‹ฌ์‚ฌ๋กœ ๋ฐ”๊ฟ” ์ฃผ์‹ญ์‹œ์˜ค โ€”
280
+ ๊ทธ๋ž˜์•ผ ๋‹ค๋ฅธ ์ฐธ๊ฐ€์ž์™€ ๊ฐ™์€ ํ›„๋ณด๊ฐ€ ๊ฒน์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜์˜จ ์กฐ์„ฑ์„ ์˜ค๋ฅธ์ชฝ ์นธ์— ํ•˜๋‚˜์”ฉ ์ œ์ถœํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.</p>`,
281
+ models_h:"AI ๋ชจ๋ธ๋ณ„ ์„ฑ๊ณผ",
282
+ models_lead:`์–ด๋А ๋ชจ๋ธ์ด <b>๊ฐ€์žฅ ์ข‹์€ ํ›„๋ณด</b>๋ฅผ ๋ƒˆ๋Š”์ง€(๋ง‰๋Œ€)์™€ <b>์–ผ๋งˆ๋‚˜ ์“ฐ์ด๋Š”์ง€</b>(์˜ค๋ฅธ์ชฝ)๋ฅผ
283
+ ํ•จ๊ป˜ ๋ด…๋‹ˆ๋‹ค. ๋งŽ์ด ์“ฐ์ธ๋‹ค๊ณ  ์ž˜ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ ๋”ฐ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.`,
284
+ mempty:"์ฑ„์ ๋œ ์ œ์ถœ์ด ์Œ“์ด๋ฉด ๋ชจ๋ธ๋ณ„ ์„ฑ๊ณผ๊ฐ€ ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.",
285
+ mcounts:(m,n)=>`๋ชจ๋ธ ${m} ยท ์ œ์ถœ ${n}`,
286
+ mlegend:`<span><i></i>์ตœ๊ณ  ์ ์ˆ˜</span><span><u></u>ํ‰๊ท </span><span>์ œ์ถœ ์ˆ˜</span>`,
287
+ tabs:{board:"๋Œ€ํšŒ ยท ์ˆœ์œ„ํ‘œ", guide:"๏ฟฝ๏ฟฝ๏ฟฝ๊ฐ€ ๊ฐ€์ด๋“œ", models:"๋ชจ๋ธ๋ณ„ ์„ฑ๊ณผ"},
288
+ divs:{all:"์ „์ฒด", fluoride:"๋ถˆํ™”๋ฌผ", halide:"์—ผํ™”ยท๋ธŒ๋กฌํ™”ยท์š”์˜ค๋“œํ™”", sulfide:"ํ™ฉํ™”๋ฌผ",
289
+ oxide:"์‚ฐํ™”๋ฌผ", nitride:"์งˆํ™”๋ฌผ", hydride:"์ˆ˜์†Œํ™”๋ฌผ", other:"๊ธฐํƒ€"},
290
+ divnote:"์Œ์ด์˜จ ๊ณจ๊ฒฉ์— ๋”ฐ๋ผ ๋ถ€๋ฌธ์„ ๋‚˜๋ˆด์Šต๋‹ˆ๋‹ค. <b>์ ์ˆ˜๋Š” ๋ถ€๋ฌธ๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋™์ผํ•œ ๊ธฐ์ค€</b>์œผ๋กœ ๋งค๊ฒจ์ง€๋ฉฐ, ๋ถ€๋ฌธ์€ ๊ฐ™์€ ํ™”ํ•™ ๊ณ„์—ด ์•ˆ์—์„œ ๋น„๊ตํ•˜์‹œ๋ผ๊ณ  ๋‘” ๊ฒƒ์ž…๋‹ˆ๋‹ค.",
291
+ xlink:`๐Ÿงช <b>Open Discovery Challenge</b> <em>โ€” ์‹ ์•ฝ ํ›„๋ณด ๋ฌผ์งˆ์„ ์ฐพ๋Š” ์ž๋งค ๋Œ€ํšŒ</em> โ†—`,
292
+ xlink2:`๐ŸŽฏ <b>LEADBOARD</b> <em>โ€” ์‹ ์•ฝ ์˜ˆ์ธก ๋„๊ตฌ๋ฅผ ๋ถ„์•ผ๋ณ„๋กœ ์žฌ๋Š” ์‹œํ—˜๋Œ€</em> โ†—`,
293
+ sinfo:(o,c)=>[`์‹œ์ฆŒ ๊ธฐ๊ฐ„ <b>${o} ~ ${c}</b>`,`์ƒ๊ธˆ <b>์—†์Œ</b>`,`์ œ์ถœ <b>์กฐ์„ฑ ํ•˜๋‚˜</b>`],
294
+ axhelp:[
295
+ ["์‚ฐํ™” ์•ˆ์ •์„ฑ","์ถฉ์ „ ์ „์••์ด ๋†’์•„์กŒ์„ ๋•Œ ์ „ํ•ด์งˆ ์ž์‹ ์ด ๋ถ„ํ•ด๋˜์ง€ ์•Š๊ณ  ๋ฒ„ํ‹ฐ๋Š” ์ •๋„."],
296
+ ["Li๊ธˆ์† ์•ˆ์ •์„ฑ","๋ฆฌํŠฌ ๊ธˆ์† ์Œ๊ทน์— ๋‹ฟ์•˜์„ ๋•Œ ๋ฐ˜์‘ํ•ด ๋ง๊ฐ€์ง€์ง€ ์•Š๋Š” ์ •๋„."],
297
+ ["์šฉ๋„ ์‹ ๊ทœ์„ฑ","์ด ์กฐ์„ฑ์ด ๊ณ ์ฒด์ „ํ•ด์งˆ ์šฉ๋„๋กœ ๋ณด๊ณ ๋œ ์ ์ด ์—†์„์ˆ˜๋ก ๋†’์Šต๋‹ˆ๋‹ค."],
298
+ ["๋ฆฌํŠฌ ์ด๋™ ๊ฒฝ๋กœ","์ ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ <b>์ฐธ๊ฐ€ ์กฐ๊ฑด</b>์ž…๋‹ˆ๋‹ค. ๋ฆฌํŠฌ์ด ์ง€๋‚˜๊ฐˆ ๊ด€ํ†ต ๊ฒฝ๋กœ๊ฐ€ ์—†์œผ๋ฉด ์ ‘์ˆ˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."]],
299
+ limits:(L)=>`์ œ์ถœ ์ œํ•œ โ€” ๋ฆฌํŠฌ ํ•„์ˆ˜ ยท ๊ธฐ์•ฝ ์กฐ์„ฑ ์›์ž ์ˆ˜ ${L.max_atoms}๊ฐœ ์ดํ•˜ ยท ์›์†Œ 6์ข… ์ดํ•˜.
300
+ ๊ฐ™์€ ๋ฌผ์งˆ์„ ์ •์ˆ˜๋ฐฐ๋กœ ๋ฐ”๊ฟ” ๋‹ค์‹œ ๋‚ด๋ฉด ๊ฐ™์€ ์ œ์ถœ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.`,
301
+ detail_h:"์ฑ„์  ๋‚ด์—ญ",
302
+ board_h:"์ˆœ์œ„ํ‘œ",
303
+ boardnote:`<b>๊ธฐ์ค€๋ฌผ์งˆ(๋…ธ๋ž€ ํ–‰)</b>์€ ์ ์ˆ˜๋ฅผ ๋ฐ›๋˜ ๋“ฑ์ˆ˜๋ฅผ ๊ฐ–์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์“ฐ์ด๋Š” ์ „ํ•ด์งˆ์ด ๋ช‡ ์ ์ธ์ง€
304
+ ๋ˆˆ์œผ๋กœ ๋น„๊ตํ•˜์‹œ๋ผ๊ณ  ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.<br>
305
+ ๋น„๊ณต๊ฐœ ์ œ์ถœ์€ ์กฐ์„ฑ์„ ๊ฐ€๋ฆฌ๊ณ  <b>์›์†Œ ์ข…๋ฅ˜๋งŒ</b> ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์›๋ณธ์€ ๋น„๊ณต๊ฐœ๋กœ ๋ณด๊ด€๋ฉ๋‹ˆ๋‹ค.<br>
306
+ <b>๊ตฌ์กฐ ํ•„์š” ยท ๋น„๊ต์ž๋ฃŒ ๋ถ€์กฑ</b>๋Š” ์ฑ„์  ์š”๊ฑด์ด ๊ฐ–์ถฐ์ง€์ง€ ์•Š์€ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. 0์ ์œผ๋กœ ๊ธฐ๋กํ•˜์ง€
307
+ ์•Š๊ณ  ๋“ฑ์ˆ˜๋„ ๋งค๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค โ€” ์žฌ์ง€ ์•Š์€ ๊ฒƒ์„ ์„ฑ์ ์œผ๋กœ ์ ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
308
+ <b>๋Œ€๋ถ€๋ถ„์€ ๊ตฌ์กฐ ํŒŒ์ผ(CIF)์„ ์ฒจ๋ถ€ํ•ด ๋‹ค์‹œ ์ œ์ถœํ•˜์‹œ๋ฉด ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค.</b> ํ–‰์„ ๋ˆ„๋ฅด๋ฉด ํ•„์š”ํ•œ ๊ฒƒ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.<br>
309
+ ์—ด ์ œ๋ชฉ์„ ๋ˆŒ๋Ÿฌ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.`,
310
+ submit_h:"์ œ์ถœ",
311
+ l_formula:"์กฐ์„ฑ (ํ™”ํ•™์‹)", l_name:"ํ‘œ์‹œ ID (์ด๋ฆ„ยท์†Œ์†ยท๋‹‰๋„ค์ž„)", l_model:"์‚ฌ์šฉ ๋ชจ๋ธ๋ช… (์„ ํƒ)",
312
+ l_cif:"๊ตฌ์กฐ ํŒŒ์ผ CIF (์„ ํƒ)", l_why:"์„ค๊ณ„ ๊ทผ๊ฑฐ (์„ ํƒ)", l_vis:"๊ณต๊ฐœ ์—ฌ๋ถ€",
313
+ cifnote:`๊ตฌ์กฐ๋ฅผ ํ•จ๊ป˜ ๋‚ด๋ฉด ๋” ๋น ๋ฅด๊ณ  ์ •ํ™•ํ•˜๊ฒŒ ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค. ์—†์œผ๋ฉด ์ €ํฌ๊ฐ€ ๊ตฌ์กฐ๋ฅผ ์ถ”์ •ํ•˜๋ฉฐ,
314
+ ์ถ”์ •์ด ๋˜์ง€ ์•Š๋Š” ์กฐ์„ฑ์€ <b>๊ตฌ์กฐ ํ•„์š”</b>๋กœ ํ‘œ์‹œ๋˜๊ณ  ๊ตฌ์กฐ๋ฅผ ์ฒจ๋ถ€ํ•ด ๋‹ค์‹œ ์ œ์ถœํ•˜์‹œ๋ฉด ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค.`,
315
+ priv:"๐Ÿ”’ ๋น„๊ณต๊ฐœ (๊ธฐ๋ณธ)", pub:"๐Ÿ”“ ์กฐ์„ฑ ๊ณต๊ฐœ",
316
+ go:"์ œ์ถœํ•˜๊ธฐ",
317
+ gate:"์ œ์ถœํ•˜๋ ค๋ฉด <b>Hugging Face ๋กœ๊ทธ์ธ</b>์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ œ์ถœ์ž ๊ณ„์ •์ด ์ˆœ์œ„ํ‘œ์— ํ•จ๊ป˜ ํ‘œ์‹œ๋˜๋ฉฐ, ์ด๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ ์ด๋ฆ„์œผ๋กœ ์˜ฌ๋ฆฌ๋Š” ๊ฒƒ์„ ๋ง‰๊ณ  ๋ชจ๋ธ๋ณ„ ์ง‘๊ณ„๋ฅผ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.",
318
+ signin:"Hugging Face ๋กœ ๋กœ๊ทธ์ธ", signout:"๋กœ๊ทธ์•„์›ƒ", signed_as:"๋กœ๊ทธ์ธ:",
319
+ broker_h:"์ œ์ถœ ๊ธฐ๋ก๊ณผ ์ œ3์ž ์—ฐ๊ฒฐ",
320
+ broker:`<p>์ œ์ถœ์€ ์‹œ๊ฐ๊ณผ ํ•จ๊ป˜ ์ €ํฌ ์›์žฅ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์กฐ์„ฑ์„ <b>๋น„๊ณต๊ฐœ</b>๋กœ ๋‘๋ฉด ์ €ํฌ๋งŒ ๋ณด๊ด€ํ•˜๋ฉฐ,
321
+ ๊ณต๊ฐœํ•˜์ง€ ์•Š๋Š” ํ•œ ์™ธ๋ถ€์— ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ก์ด ํ–ฅํ›„ ๊ถŒ๋ฆฌ ์ฃผ์žฅ์— ์ฐธ๊ณ ๊ฐ€ ๋  ์ˆ˜ ์žˆ์œผ๋‚˜,
322
+ <b>ํŠนํ—ˆ ์ถœ์›์„ ๋Œ€์‹ ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋ฒ•์  ํšจ๋ ฅ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.</b> ์ถœ์›์€ ์ „๋ฌธ๊ฐ€์™€ ์ƒ์˜ํ•˜์‹ญ์‹œ์˜ค.</p>
323
+ <p>์ œ3์ž๊ฐ€ ํŠน์ • ์ œ์ถœ์— ๋Œ€ํ•ด ํ˜‘์˜๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ, ์šด์˜์ž๊ฐ€ <b>์ค‘๊ฐœ</b>ํ•ฉ๋‹ˆ๋‹ค.
324
+ ์ œ์ถœ์ž์˜ ์‹ ์›์ด๋‚˜ ์—ฐ๋ฝ์ฒ˜๋Š” <b>๋ณธ์ธ ๋™์˜ ์—†์ด ์ „๋‹ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.</b></p>`,
325
+ cols:{rank:"#",cand:"ํ›„๋ณด",user:"์ œ์ถœ์ž",who:"๋ชจ๋ธ",date:"์ œ์ถœ์ผ",
326
+ oxidation:"์‚ฐํ™”",li_stability:"Li์•ˆ์ •",migration:"์ด๋™",novelty:"์‹ ๊ทœ",total:"์ด์ "},
327
+ counts:(a,b,h)=>`์ฑ„์  ${a} ยท ๊ธฐ์ค€๋ฌผ์งˆ ${b}` + (h ? ` ยท ๋ฏธ์‚ฐ์ถœ ${h}` : ""),
328
+ prange:(a,b,n)=>`${a.toLocaleString()}โ€“${b.toLocaleString()} / ์ „์ฒด ${n.toLocaleString()}`,
329
+ empty:"์•„์ง ์ฑ„์ ๋œ ์ œ์ถœ์ด ์—†์Šต๋‹ˆ๋‹ค.",
330
+ fail:"์ˆœ์œ„ํ‘œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค: ",
331
+ ok:(id,q)=>`์ ‘์ˆ˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ›„๋ณด ID <b>${id}</b> ยท ๋Œ€๊ธฐ ${q}๊ฑด`,
332
+ need:"์กฐ์„ฑ๊ณผ ํ‘œ์‹œ ID๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.",
333
+ hold:"๋ฏธ์‚ฐ์ถœ",
334
+ holds:{need_structure:"๊ตฌ์กฐ ํ•„์š”", no_reference:"๋น„๊ต์ž๋ฃŒ ๋ถ€์กฑ", no_value:"์‚ฐ์ถœ ๋ถˆ๊ฐ€"},
335
+ holdnote:"์•„๋ž˜ ์š”๊ฑด์„ ๊ฐ–์ถฐ ๋‹ค์‹œ ์ œ์ถœํ•˜์‹œ๋ฉด ์ฑ„์ ๋ฉ๋‹ˆ๋‹ค."
336
+ },
337
+ en:{
338
+ sub:"Open problems, worked on together โ€” materials discovery anyone can join",
339
+ about_h:"What this is",
340
+ about:`<p>A solid-state battery replaces the liquid electrolyte of a lithium-ion cell with a solid.
341
+ It can be safer and last longer, but finding a material that is <b>solid and still lets lithium through</b>
342
+ remains unsolved.</p>
343
+ <p>This challenge looks for candidates. You submit <b>one composition</b> โ€” for example <code>Li3YCl6</code>.
344
+ We score it computationally and place it on the board. There is no prize.</p>`,
345
+ honest:`<b>What this season scores.</b> <b>Electrochemical robustness</b>: whether the material holds up at
346
+ high voltage, survives contact with lithium metal, and has a path for lithium to move through.
347
+ <b>Ionic conductivity is not a scored axis this season.</b> A highly conductive family therefore still
348
+ scores low if its oxidation window is narrow or it reacts with lithium metal โ€” those two are the problem
349
+ this season puts to you.
350
+ Every value is a <b>computational estimate</b> and implies nothing about real performance or safety.`,
351
+ guide_h:"How to take part",
352
+ guide_lead:`In a solid-state cell the lithium ion has to travel <b>through a solid</b>. That same solid
353
+ must <b>block electrons</b>, hold up at the charging voltage, and survive contact with the
354
+ <b>lithium metal</b> anode without decomposing. Meeting all four in one material is the open problem.`,
355
+ facts:[
356
+ ["Target", "A solid with a path for lithium to move through. It must contain lithium."],
357
+ ["Get past this", "If electrons pass, the cell simply shorts. Electronic insulation is a precondition."],
358
+ ["Hardest part", "Oxidation stability and lithium-metal stability pull against each other. Holding both is the task."],
359
+ ["Submission", "One composition. A structure (CIF) is optional and makes scoring faster and more accurate."]],
360
+ guide_how:`<p style="margin:14px 0 2px">Paste a prompt below into the model you use. Hit <b>Copy</b>,
361
+ then change the italicised part to something of your own โ€” otherwise your candidates will collide with
362
+ other entrants'. Submit the compositions it returns, one at a time, on the right.</p>`,
363
+ models_h:"By model",
364
+ models_lead:`Which model produced the <b>best candidate</b> (bar) and <b>how often it is used</b> (right).
365
+ Being used a lot is not the same as doing well, so the two are shown separately.`,
366
+ mempty:"Model standings appear here once scored entries accumulate.",
367
+ mcounts:(m,n)=>`${m} models ยท ${n} entries`,
368
+ mlegend:`<span><i></i>Best score</span><span><u></u>Mean</span><span>Entries</span>`,
369
+ tabs:{board:"Challenge ยท Board", guide:"How to take part", models:"By model"},
370
+ divs:{all:"All", fluoride:"Fluoride", halide:"Chloride / bromide / iodide", sulfide:"Sulfide",
371
+ oxide:"Oxide", nitride:"Nitride", hydride:"Hydride", other:"Other"},
372
+ divnote:"Divisions follow the anion framework. <b>Scores are identical across divisions</b> - the split is there so you can compare within a chemical family.",
373
+ xlink:`๐Ÿงช <b>Open Discovery Challenge</b> <em>โ€” the sister challenge, for drug candidates</em> โ†—`,
374
+ xlink2:`๐ŸŽฏ <b>LEADBOARD</b> <em>โ€” the benchmark for drug prediction tools</em> โ†—`,
375
+ sinfo:(o,c)=>[`Season <b>${o} โ€“ ${c}</b>`,`Prize <b>none</b>`,`Submit <b>one composition</b>`],
376
+ axhelp:[
377
+ ["Oxidation","How well the electrolyte itself resists decomposing as the cell voltage rises."],
378
+ ["Li-metal stability","How well it survives contact with a lithium-metal anode."],
379
+ ["Use novelty","Higher when the composition has not been reported as a solid electrolyte."],
380
+ ["Lithium pathway","Not a score but an <b>entry condition</b>: without a percolating path for lithium, an entry is not accepted."]],
381
+ limits:(L)=>`Limits โ€” lithium required ยท at most ${L.max_atoms} atoms in the reduced composition ยท
382
+ at most 6 elements. Re-submitting the same material as an integer multiple counts as the same entry.`,
383
+ detail_h:"How this was scored",
384
+ board_h:"Leaderboard",
385
+ boardnote:`<b>Reference materials (amber rows)</b> are scored but hold no rank. They are there so you can see
386
+ where materials in actual use land.<br>
387
+ Private entries show <b>elements only</b>; the composition is held back.<br>
388
+ <b>Structure needed / no reference data</b> means the requirements for scoring are not yet met.
389
+ Nothing is recorded as zero and no rank is assigned - an unmeasured entry is not given a standing.
390
+ <b>Most cases are scored once a structure file (CIF) is attached and the entry resubmitted.</b>
391
+ Click the row to see what is required.<br>
392
+ Click a column header to sort.`,
393
+ submit_h:"Submit",
394
+ l_formula:"Composition (formula)", l_name:"Display ID (name, affiliation or handle)",
395
+ l_model:"Model used (optional)", l_cif:"Structure file, CIF (optional)",
396
+ l_why:"Design rationale (optional)", l_vis:"Visibility",
397
+ cifnote:`Including a structure makes scoring faster and more accurate. Without one we estimate the
398
+ structure; where that is not possible the entry is marked <b>structure needed</b> and is scored
399
+ once a structure is attached and it is resubmitted.`,
400
+ priv:"๐Ÿ”’ Private (default)", pub:"๐Ÿ”“ Show composition",
401
+ go:"Submit",
402
+ gate:"Submitting requires a <b>Hugging Face sign-in</b>. Your account appears alongside the entry, which stops anyone posting under another person's name and keeps the per-model standings trustworthy.",
403
+ signin:"Sign in with Hugging Face", signout:"Sign out", signed_as:"Signed in as",
404
+ broker_h:"Record of submission, and third-party contact",
405
+ broker:`<p>Entries are recorded with a timestamp in our ledger. A <b>private</b> composition stays with us and
406
+ is not disclosed unless you choose to publish it. This record may serve as a reference later, but it
407
+ <b>is not a patent filing and carries no guaranteed legal effect.</b> Consult a professional before filing.</p>
408
+ <p>If a third party asks to discuss a specific entry, we pass the request along. We never share a
409
+ submitter's identity or contact details <b>without their consent.</b></p>`,
410
+ cols:{rank:"#",cand:"Entry",user:"Submitter",who:"Model",date:"Date",
411
+ oxidation:"Oxid.",li_stability:"Li-stab.",migration:"Migration",novelty:"Novelty",total:"Total"},
412
+ counts:(a,b,h)=>`${a} scored ยท ${b} references` + (h ? ` ยท ${h} not scored` : ""),
413
+ prange:(a,b,n)=>`${a.toLocaleString()}โ€“${b.toLocaleString()} of ${n.toLocaleString()}`,
414
+ empty:"No entries have been scored yet.",
415
+ fail:"Could not load the leaderboard: ",
416
+ ok:(id,q)=>`Accepted. Entry <b>${id}</b> ยท ${q} in queue`,
417
+ need:"Please enter a composition and a display ID.",
418
+ hold:"not scored",
419
+ holds:{need_structure:"structure needed", no_reference:"no reference data", no_value:"no value"},
420
+ holdnote:"Meet the requirement below and resubmit; the entry will then be scored."
421
+ }
422
+ };
423
+
424
+ // ํ”„๋กฌํ”„ํŠธ๋Š” **๋ชฉํ‘œ**๋งŒ ๋งํ•œ๋‹ค. ๋ฌด์—‡์„ ์–ด๋–ป๊ฒŒ ์žฌ๋Š”์ง€๋Š” ์ ์ง€ ์•Š๋Š”๋‹ค - ์ ์œผ๋ฉด ๋ฌผ์งˆ์ด ์•„๋‹ˆ๋ผ
425
+ // ์ฑ„์ ๊ธฐ๋ฅผ ๊ฒจ๋ƒฅํ•œ ์ œ์ถœ์ด ๋“ค์–ด์˜จ๋‹ค.
426
+ const PROMPTS_BY_SEASON = {
427
+ 1: [
428
+ {id:"A", ko:["๊ธฐ๋ณธํ˜•","์ฒ˜์Œ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด ์ด๊ฒƒ๋ถ€ํ„ฐ"], en:["Starter","Begin here"],
429
+ body:`You are proposing candidate solid electrolytes for an all-solid-state lithium battery,
430
+ for an open materials challenge.
431
+
432
+ Requirements for every candidate:
433
+ - Contains lithium, with a plausible connected pathway for Li+ to migrate through the
434
+ lattice.
435
+ - An electronic insulator. If electrons conduct, the cell short-circuits; this is a
436
+ precondition, not a trade-off.
437
+ - Wide electrochemical window: stable against oxidation at high cell voltage.
438
+ - Stable in contact with lithium metal at the anode, or decomposing only into a passivating
439
+ layer rather than an electronically conductive one.
440
+ - Plausibly synthesisable: a composition close to a stable phase, not an exotic guess.
441
+
442
+ Propose 8 candidate compositions as a JSON array:
443
+ [{"formula":"...","name":"...","rationale":"why lithium should move through it, why it
444
+ should not conduct electrons, and how it behaves against lithium metal"}]
445
+
446
+ Use plain chemical formulae, e.g. Li3YCl6 or LiZr2(PO4)3.
447
+
448
+ <em>VARY THIS: name a chemical family you want to explore (halides, oxides, phosphates,
449
+ oxyhalides, anti-perovskites, โ€ฆ) or a constraint of your own, so your set does not collide
450
+ with other entrants'. Identical submissions are rejected.</em>`},
451
+
452
+ {id:"B", ko:["์‚ฐํ™” ์•ˆ์ •์„ฑ","๋†’์€ ์ „์••์„ ๊ฒฌ๋””๋Š” ์„ค๊ณ„ (40์ )"], en:["Oxidation","Holding up at high voltage (40 pts)"],
453
+ body:`Propose solid lithium-ion electrolytes designed specifically for a WIDE oxidation
454
+ window, so they survive against a high-voltage cathode.
455
+
456
+ Reason from this:
457
+ - The anion is usually what oxidises first. Sulfide frameworks conduct well but oxidise at
458
+ low potential; more electronegative anions push the oxidation limit higher.
459
+ - The counter-cation matters: a cation already in a high oxidation state has less room to
460
+ be oxidised further.
461
+ - A material that resists oxidation but has no lithium pathway is worthless. A connected
462
+ migration path is a precondition, not a trade-off.
463
+
464
+ For each candidate state explicitly: which anion framework you chose and why you expect it
465
+ to resist oxidation, and how lithium still moves through it.
466
+
467
+ Propose 8 candidates as JSON: [{"formula","name","rationale"}]
468
+
469
+ <em>VARY THIS: commit to ONE anion chemistry and build the whole set around it, rather than
470
+ eight unrelated guesses.</em>`},
471
+
472
+ {id:"C", ko:["๋ฆฌํŠฌ๊ธˆ์† ์•ˆ์ •์„ฑ","์Œ๊ทน์—์„œ ๋ฒ„ํ‹ฐ๋Š” ์„ค๊ณ„ (35์ )"], en:["Lithium-metal stability","Surviving the anode (35 pts)"],
473
+ body:`Propose solid lithium-ion electrolytes designed to survive direct contact with
474
+ LITHIUM METAL.
475
+
476
+ Reason from this:
477
+ - Lithium metal is strongly reducing. Any cation in the electrolyte that can be reduced
478
+ will be. Transition metals in high oxidation states are the classic failure: they reduce,
479
+ the interface becomes electronically conductive, and the reaction never stops.
480
+ - The useful case is a decomposition product that is itself an insulator, so the interface
481
+ passivates and the reaction halts.
482
+ - Wide oxidation window alone does not help if the anode side fails. Both ends of the
483
+ window matter.
484
+
485
+ For each candidate state explicitly: which element you expect lithium metal to attack, and
486
+ why the interface should stop reacting rather than keep going.
487
+
488
+ Propose 8 candidates as JSON: [{"formula","name","rationale"}]
489
+
490
+ <em>VARY THIS: choose one strategy โ€” reduction-proof cations, or a self-passivating
491
+ decomposition product โ€” and build the set around it.</em>`},
492
+
493
+ {id:"D", ko:["์šฉ๋„ ์‹ ๊ทœ์„ฑ","๊ฐ€์žฅ ํฐ ์ ์ˆ˜ ์—ฌ์ง€ (25์ )"], en:["Use novelty","Where the headroom is (25 pts)"],
494
+ body:`Propose lithium-containing compositions that are NOT already reported as solid
495
+ electrolytes.
496
+
497
+ Important distinction: the composition does not have to be brand new. What matters is
498
+ whether anyone has proposed it FOR THIS USE. A known compound that nobody has evaluated as
499
+ a lithium electrolyte is exactly the target; a well-studied electrolyte family is not.
500
+
501
+ So avoid the ones already worked over โ€” the common sulfide, garnet, NASICON and
502
+ argyrodite electrolyte families โ€” and look at lithium compounds studied for other reasons
503
+ entirely, or not studied much at all.
504
+
505
+ Every candidate must still meet the basics: a lithium migration path, electronic
506
+ insulation, and reasonable stability at both electrodes. Novelty with no function scores
507
+ nothing.
508
+
509
+ For each candidate state: what the composition is normally known for (if anything), and
510
+ why it might work as an electrolyte.
511
+
512
+ Propose 8 candidates as JSON: [{"formula","name","rationale"}]
513
+
514
+ <em>VARY THIS: pick one source of overlooked compounds โ€” a mineral class, a family studied
515
+ for optics or ionics elsewhere, a ternary system that is sparsely mapped โ€” and work it.</em>`}
516
+ ]
517
+ };
518
+
519
+ const $ = s => document.querySelector(s);
520
+ const COLS = ["rank","cand","user","who","date","oxidation","li_stability","novelty","total"];
521
+ // ํ‘œ๊ฐ€ ์ปค์ง€๋ฉด ํ•œ๊บผ๋ฒˆ์— ๊ทธ๋ฆฌ์ง€ ์•Š๊ณ  ํ•œ ํŽ˜์ด์ง€์”ฉ ๊ทธ๋ฆฐ๋‹ค.
522
+ const PAGE_SIZE = 500;
523
+ let LANG = "ko", DATA = null, SEASONS = [], SEASON = 1;
524
+ let sortKey = "total", sortDir = -1, page = 0, DIV = "all";
525
+ const t = () => T[LANG];
526
+
527
+ let ME = null;
528
+
529
+ function renderAuth(){
530
+ const d = t(), g = $("#gate"), m = $("#me");
531
+ if(!ME || !ME.oauth_configured){ g.style.display="none"; m.innerHTML=""; return; }
532
+ if(ME.signed_in && ME.user){
533
+ g.style.display = "none";
534
+ const u = ME.user;
535
+ const pic = u.picture ? `<img src="${esc(u.picture)}" alt="">` : "๐Ÿค—";
536
+ m.innerHTML = `${pic}<span>${d.signed_as} ${hfProfile(u.name)}</span>`
537
+ + `<a class="signin out" href="/logout" style="margin-left:auto">${esc(d.signout)}</a>`;
538
+ } else {
539
+ g.style.display = "block";
540
+ g.innerHTML = d.gate;
541
+ m.innerHTML = `<a class="signin" href="/login">๐Ÿค— ${esc(d.signin)}</a>`;
542
+ }
543
+ }
544
+
545
+ function hfProfile(user){
546
+ if(!user) return "";
547
+ const url = `https://huggingface.co/${encodeURIComponent(user)}`;
548
+ return `<a class="hf-user" href="${url}" target="_blank" rel="noopener noreferrer"`
549
+ + ` title="Hugging Face: ${esc(user)}">๐Ÿค— ${esc(user)}</a>`;
550
+ }
551
+
552
+ function esc(s){ return String(s ?? "").replace(/[&<>"']/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c])); }
553
+
554
+ function setLang(l){
555
+ LANG = l;
556
+ document.documentElement.lang = l;
557
+ document.querySelectorAll("#langbar button").forEach(b=>b.classList.toggle("on", b.dataset.lang===l));
558
+ const d = t();
559
+ $("#t_sub").textContent = d.sub;
560
+ $("#t_about_h").textContent = d.about_h;
561
+ $("#t_about").innerHTML = d.about;
562
+ $("#t_honest").innerHTML = d.honest;
563
+ $("#t_board_h").textContent = d.board_h;
564
+ $("#t_boardnote").innerHTML = d.boardnote;
565
+ $("#t_submit_h").textContent = d.submit_h;
566
+ $("#t_broker_h").textContent = d.broker_h;
567
+ $("#t_broker").innerHTML = d.broker;
568
+ $("#t_cifnote").innerHTML = d.cifnote;
569
+ $("#xlink").innerHTML = d.xlink;
570
+ { const x2 = document.querySelector("#xlink2"); if(x2 && d.xlink2) x2.innerHTML = d.xlink2; }
571
+ renderAuth();
572
+ $("#t_guide_h").textContent = d.guide_h;
573
+ $("#t_guide_lead").innerHTML = d.guide_lead;
574
+ $("#t_guide_how").innerHTML = d.guide_how;
575
+ $("#t_models_h").textContent = d.models_h;
576
+ $("#t_models_lead").innerHTML = d.models_lead;
577
+ renderFacts();
578
+ renderPrompts();
579
+ renderTabs();
580
+ renderSeasonInfo();
581
+ renderAxHelp();
582
+ $("#t_priv").textContent = d.priv;
583
+ $("#t_pub").textContent = d.pub;
584
+ $("#go").textContent = d.go;
585
+ for(const k of ["formula","name","model","cif","why","vis"]) $("#l_"+k).textContent = d["l_"+k];
586
+ const g = $("#gate"); if(g.style.display !== "none") g.innerHTML = d.gate;
587
+ renderSeasonBar();
588
+ if(DATA) render();
589
+ }
590
+ document.querySelectorAll("#langbar button").forEach(b=>b.onclick=()=>setLang(b.dataset.lang));
591
+
592
+ function renderSeasonBar(){
593
+ $("#seasonbar").innerHTML = SEASONS.slice().sort((a,b)=>b.number-a.number).map(s=>{
594
+ const nm = LANG==="ko" ? (s.topic_ko||s.topic) : s.topic;
595
+ return `<button data-season="${s.number}" class="${s.number===SEASON?"on":""}">
596
+ #${s.number} ${esc(nm)}</button>`;
597
+ }).join("");
598
+ document.querySelectorAll("#seasonbar button").forEach(b=>
599
+ b.onclick=()=>{ SEASON=parseInt(b.dataset.season,10); page=0;
600
+ renderSeasonBar(); renderPrompts(); renderSeasonInfo(); renderAxHelp();
601
+ MODELS_LOADED = false; load(); if(TAB==="models"){ MODELS_LOADED=true; loadModels(); } });
602
+ }
603
+
604
+ function sortVal(e,k){
605
+ if(k==="rank") return e.rank ?? 1e9;
606
+ if(k==="cand") return String(e.candidate_id||"").toLowerCase();
607
+ if(k==="user") return String(e.hf_user||e.display_name||"").toLowerCase();
608
+ if(k==="who") return String(e.model_name||"").toLowerCase();
609
+ if(k==="date") return e.submitted_at ?? 0;
610
+ if(k==="total") return e.total ?? -1;
611
+ return (e.axes||{})[k] ?? -1;
612
+ }
613
+
614
+ let TAB = "board";
615
+
616
+ function renderTabs(){
617
+ const d = t();
618
+ $("#tabbar").innerHTML = ["board","guide","models"].map(k=>
619
+ `<button data-tab="${k}" class="${k===TAB?"on":""}">${esc(d.tabs[k])}</button>`).join("");
620
+ $("#tabbar").querySelectorAll("button").forEach(b=>b.onclick=()=>{
621
+ TAB = b.dataset.tab; renderTabs(); showTab();
622
+ window.scrollTo({top:0,behavior:"smooth"});
623
+ });
624
+ }
625
+
626
+ function showTab(){
627
+ document.querySelectorAll("section[data-tab]").forEach(sec=>{
628
+ sec.hidden = sec.dataset.tab !== TAB;
629
+ });
630
+ // ๋ชจ๋ธ ์ง‘๊ณ„๋Š” ๊ทธ ํƒญ์„ ์—ด ๋•Œ ์ฒ˜์Œ ๋ถ€๋ฅธ๋‹ค. ์•ˆ ๋ณด๋Š” ํ™”๋ฉด์„ ์œ„ํ•ด ๋งค๋ฒˆ ๋ฐ›์•„์˜ฌ ์ด์œ ๊ฐ€ ์—†๋‹ค.
631
+ if(TAB==="models" && !MODELS_LOADED){ MODELS_LOADED = true; loadModels(); }
632
+ }
633
+ let MODELS_LOADED = false;
634
+
635
+ function seasonInfo(){ return SEASONS.find(x=>x.number===SEASON) || SEASONS[0] || {}; }
636
+
637
+ function renderSeasonInfo(){
638
+ const si = seasonInfo(), d = t();
639
+ if(!si.opens){ $("#sinfo").innerHTML=""; return; }
640
+ $("#sinfo").innerHTML = d.sinfo(si.opens, si.closes).map(x=>`<span>${x}</span>`).join("");
641
+ }
642
+
643
+ function renderAxHelp(){
644
+ const d = t();
645
+ $("#axhelp").innerHTML = (d.axhelp||[]).map(([k,v])=>
646
+ `<div><b>${esc(k)}</b> โ€” ${esc(v)}</div>`).join("");
647
+ const L = (seasonInfo().limits)||{};
648
+ $("#t_limits").innerHTML = L.max_atoms ? d.limits(L) : "";
649
+ }
650
+
651
+ function promptsFor(){ return PROMPTS_BY_SEASON[SEASON] || PROMPTS_BY_SEASON[1]; }
652
+
653
+ function renderPrompts(){
654
+ const d = t(), host = $("#prompts");
655
+ if(!host) return;
656
+ host.innerHTML = promptsFor().map((p,i)=>{
657
+ const [title,sub] = (LANG==="ko" ? p.ko : p.en);
658
+ return `<div class="pcard">
659
+ <div class="phead"><span class="ptag">${p.id}</span><b>${esc(title)}</b><span>${esc(sub)}</span>
660
+ <button class="pcopy" data-i="${i}">${LANG==="ko"?"๋ณต์‚ฌ":"Copy"}</button></div>
661
+ <div class="pbody">${p.body.trim()}</div></div>`;
662
+ }).join("");
663
+ host.querySelectorAll(".pcopy").forEach(b=>b.onclick=async()=>{
664
+ // ๊ฐ•์กฐ ํ‘œ์‹œ๋Š” ํ™”๋ฉด์šฉ์ด๋‹ค. ํด๋ฆฝ๋ณด๋“œ์—๋Š” ๊นจ๋—ํ•œ ๋ณธ๋ฌธ๋งŒ ๋„ฃ๋Š”๋‹ค.
665
+ const raw = promptsFor()[+b.dataset.i].body.replace(/<\/?em>/g,"").trim();
666
+ try{ await navigator.clipboard.writeText(raw); }
667
+ catch(_){ const ta=document.createElement("textarea"); ta.value=raw;
668
+ document.body.appendChild(ta); ta.select(); document.execCommand("copy"); ta.remove(); }
669
+ const was=b.textContent;
670
+ b.textContent = LANG==="ko" ? "๋ณต์‚ฌ๋จ โœ“" : "Copied โœ“";
671
+ setTimeout(()=>{ b.textContent=was; },1500);
672
+ });
673
+ }
674
+
675
+ function renderFacts(){
676
+ const d = t();
677
+ $("#facts").innerHTML = (d.facts||[]).map(([k,v])=>
678
+ `<div class="fact"><b>${esc(k)}</b>${esc(v)}</div>`).join("");
679
+ }
680
+
681
+ function renderModels(m){
682
+ const d = t(), host = $("#models");
683
+ const rows = (m && m.models) || [];
684
+ $("#mcounts").textContent = d.mcounts((m&&m.counts&&m.counts.models)||0,
685
+ (m&&m.counts&&m.counts.entries)||0);
686
+ $("#t_mlegend").innerHTML = d.mlegend;
687
+ if(!rows.length){ host.innerHTML = `<div class="note">${d.mempty}</div>`; return; }
688
+ const max = Math.max(...rows.map(r=>r.best), 1);
689
+ host.innerHTML = rows.slice(0,14).map(r=>`
690
+ <div class="mrow">
691
+ <div class="mname" title="${esc(r.model)}">${esc(r.model)}</div>
692
+ <div class="mbar"><i style="width:${(r.best/max*100).toFixed(1)}%"></i>
693
+ <u style="left:${(r.mean/max*100).toFixed(1)}%"></u></div>
694
+ <div class="mnum">${r.best.toFixed(1)} ยท ${r.n}</div>
695
+ </div>`).join("");
696
+ }
697
+
698
+ async function loadModels(){
699
+ try{ renderModels(await (await fetch(`/api/models?season=${SEASON}`)).json()); }
700
+ catch(e){ renderModels(null); }
701
+ }
702
+
703
+ function renderDivBar(){
704
+ const d = t(), host = $("#divbar");
705
+ const tally = (DATA && DATA.divisions) || {};
706
+ const keys = Object.keys(tally).sort((a,b)=>(tally[b]||0)-(tally[a]||0));
707
+ if(!keys.length){ host.innerHTML=""; return; }
708
+ const total = Object.values(tally).reduce((a,b)=>a+b,0);
709
+ const btn = (k,n)=>`<button data-d="${k}" class="${k===DIV?"on":""}">${esc(d.divs[k]||k)}<span class="dn">${n}</span></button>`;
710
+ host.innerHTML = btn("all",total) + keys.map(k=>btn(k,tally[k])).join("");
711
+ host.querySelectorAll("button[data-d]").forEach(b=>b.onclick=()=>{
712
+ DIV=b.dataset.d; page=0; render();
713
+ });
714
+ }
715
+
716
+ function renderPager(total,pages){
717
+ const host = $("#pager"), d = t();
718
+ if(pages<=1){ host.innerHTML=""; return; }
719
+ const from = page*PAGE_SIZE+1, to = Math.min(total,(page+1)*PAGE_SIZE);
720
+ let nums=[];
721
+ if(pages<=9){ for(let i=0;i<pages;i++) nums.push(i); }
722
+ else{
723
+ const near=[page-1,page,page+1].filter(i=>i>0&&i<pages-1);
724
+ nums=[...new Set([0,...near,pages-1])].sort((a,b)=>a-b);
725
+ }
726
+ let out=`<button ${page===0?"disabled":""} data-p="${page-1}">โ€น</button>`, prev=-1;
727
+ for(const i of nums){
728
+ if(i-prev>1) out+=`<span class="gap">โ€ฆ</span>`;
729
+ out+=`<button class="${i===page?"on":""}" data-p="${i}">${i+1}</button>`; prev=i;
730
+ }
731
+ out+=`<button ${page>=pages-1?"disabled":""} data-p="${page+1}">โ€บ</button>`;
732
+ out+=`<span class="pinfo">${d.prange(from,to,total)}</span>`;
733
+ host.innerHTML=out;
734
+ host.querySelectorAll("button[data-p]").forEach(b=>b.onclick=()=>{
735
+ if(b.disabled) return;
736
+ page=parseInt(b.dataset.p,10); render();
737
+ const c=document.querySelector(".card .scroll");
738
+ if(c) window.scrollTo({top:c.getBoundingClientRect().top+window.scrollY-80,behavior:"smooth"});
739
+ });
740
+ }
741
+
742
+ function render(){
743
+ const d = t(), W = (DATA.season && DATA.season.weights) || {};
744
+ $("#wts").innerHTML = Object.entries(W)
745
+ .map(([k,v])=>`<span>${esc(d.cols[k]||k)} <b>${v}</b></span>`).join("");
746
+ $("#counts").textContent = d.counts(DATA.counts.scored, DATA.counts.anchors, DATA.counts.held || 0);
747
+
748
+ $("#head").innerHTML = COLS.map(k=>{
749
+ const on = sortKey===k, ar = on ? (sortDir<0?"โ–ผ":"โ–ฒ") : "โ–พ";
750
+ return `<th data-k="${k}" class="${on?"sorted":""}">${esc(d.cols[k]||k)}<span class="ar">${ar}</span></th>`;
751
+ }).join("");
752
+ document.querySelectorAll("#head th").forEach(th=>th.onclick=()=>{
753
+ const k=th.dataset.k;
754
+ if(sortKey===k) sortDir=-sortDir;
755
+ else { sortKey=k; sortDir=(k==="rank"||k==="cand"||k==="who")?1:-1; }
756
+ page=0; render();
757
+ });
758
+
759
+ renderDivBar();
760
+ // ๋ถ€๋ฌธ์„ ๊ณ ๋ฅด๋ฉด ๊ทธ ๋ถ€๋ฌธ + ๊ธฐ์ค€๋ฌผ์งˆ๋งŒ ๋‚จ๊ธด๋‹ค. ๊ธฐ์ค€๋ฌผ์งˆ์€ ์ฒ™๋„๋ผ ํ•ญ์ƒ ๋ณด์—ฌ์•ผ ํ•œ๋‹ค.
761
+ const pool = DIV==="all" ? DATA.entries
762
+ : DATA.entries.filter(e=>e.is_anchor || e.division===DIV);
763
+ const all = pool.slice().sort((a,b)=>{
764
+ const x=sortVal(a,sortKey), y=sortVal(b,sortKey);
765
+ if(x<y) return -sortDir; if(x>y) return sortDir; return 0;
766
+ });
767
+ const pages = Math.max(1, Math.ceil(all.length/PAGE_SIZE));
768
+ if(page>=pages) page=pages-1;
769
+ if(page<0) page=0;
770
+ const rows = all.slice(page*PAGE_SIZE, page*PAGE_SIZE+PAGE_SIZE);
771
+ renderPager(all.length, pages);
772
+
773
+ { const bn = $("#t_boardnote"); if(bn) bn.innerHTML = d.boardnote + "<br>" + d.divnote; }
774
+ $("#rows").innerHTML = rows.length ? rows.map(e=>{
775
+ const a = e.axes||{};
776
+ const unscored = !e.is_anchor && (e.total == null || (e.held_axes||[]).length > 0);
777
+ const cls = [e.is_anchor?"anchor":"", unscored?"held":""].join(" ").trim();
778
+ const who = e.is_anchor ? esc(e.display_name)
779
+ : (e.hf_user ? hfProfile(e.hf_user)
780
+ : `<span title="${esc(e.display_name||"")}">${esc(e.display_name||"โ€“")}</span>`);
781
+ const num = k => {
782
+ const v = a[k];
783
+ return `<td class="num">${v==null?`<span class="pill">${d.hold}</span>`:v.toFixed(1)}</td>`;
784
+ };
785
+ const dt = e.submitted_at ? new Date(e.submitted_at*1000).toISOString().slice(0,10) : "";
786
+ const hk = e.hold_kind && d.holds[e.hold_kind];
787
+ const tot = e.total==null ? `<span class="pill warn">${esc(hk || d.hold)}</span>`
788
+ : `${e.total.toFixed(1)}<span class="sub" style="font-size:11px"> /${e.total_max||100}</span>`
789
+ + (unscored ? ` <span class="pill warn">${esc(hk || d.hold)}</span>` : "");
790
+ const has = (e.detail && Object.keys(e.detail).length) || (unscored && e.gate);
791
+ return `<tr class="${cls}${has?" pick":""}"${has?` data-i="${e.candidate_id}"`:""}>
792
+ <td class="num">${(DIV==="all" ? e.rank : e.div_rank) ?? "โ€”"}</td>
793
+ <td>${esc(e.formula||e.candidate_id||"")}${e.masked?' <span class="pill">๐Ÿ”’</span>':""}</td>
794
+ <td>${who}</td><td>${esc(e.model_name||"")}</td><td>${dt}</td>
795
+ ${num("oxidation")}${num("li_stability")}${num("novelty")}
796
+ <td class="num"><b>${tot}</b></td></tr>`;
797
+ }).join("") : `<tr><td colspan="${COLS.length}" class="sub">${d.empty}</td></tr>`;
798
+
799
+ // ์ฑ„์  ๊ทผ๊ฑฐ๋Š” ์ด๋ฏธ ์‘๋‹ต์— ๋“ค์–ด ์žˆ๋Š”๋ฐ ํ‘œ์—๋Š” ์•ˆ ๋ณด์˜€๋‹ค. ํ–‰์„ ๋ˆ„๋ฅด๋ฉด ์•„๋ž˜๋กœ ํŽผ์นœ๋‹ค.
800
+ const byId = {}; rows.forEach(e=>{ if(e.candidate_id) byId[e.candidate_id]=e; });
801
+ $("#rows").querySelectorAll("tr.pick").forEach(tr=>tr.onclick=()=>{
802
+ const nxt = tr.nextElementSibling;
803
+ if(nxt && nxt.classList.contains("det")){ nxt.remove(); return; }
804
+ $("#rows").querySelectorAll("tr.det").forEach(x=>x.remove());
805
+ const e = byId[tr.dataset.i]; if(!e) return;
806
+ const items = Object.entries(e.detail||{})
807
+ .map(([k,v])=>`<li><b>${esc(d.cols[k]||k)}</b> โ€” ${esc(v)}</li>`).join("")
808
+ || (e.gate ? `<li>${esc(e.gate)}</li>` : "");
809
+ const extra = (e.notes||[]).map(n=>`<li>${esc(n)}</li>`).join("");
810
+ const note = e.note ? `<div style="margin-top:6px">${esc(e.note)}</div>`
811
+ : (extra ? `<ul>${extra}</ul>` : "");
812
+ const row = document.createElement("tr");
813
+ row.className = "det";
814
+ row.innerHTML = `<td colspan="${COLS.length}"><b>${esc(d.detail_h)}</b><ul>${items}</ul>${note}</td>`;
815
+ tr.after(row);
816
+ });
817
+ }
818
+
819
+ async function load(){
820
+ try{
821
+ const r = await fetch(`/api/leaderboard?season=${SEASON}`);
822
+ DATA = await r.json();
823
+ render();
824
+ }catch(e){
825
+ $("#rows").innerHTML = `<tr><td colspan="${COLS.length}" class="sub">${t().fail}${esc(e)}</td></tr>`;
826
+ }
827
+ }
828
+
829
+ document.querySelectorAll('input[name="vis"]').forEach(r=>r.onchange=()=>{
830
+ document.querySelectorAll("#visbox label").forEach(l=>l.classList.toggle("on", l.querySelector("input").checked));
831
+ });
832
+
833
+ $("#go").onclick = async () => {
834
+ const d = t(), m = $("#msg");
835
+ const formula = $("#f_formula").value.trim(), name = $("#f_name").value.trim();
836
+ if(!formula || !name){ m.className="msg bad"; m.textContent=d.need; return; }
837
+ $("#go").disabled = true;
838
+ try{
839
+ const r = await fetch("/api/submit",{method:"POST",headers:{"Content-Type":"application/json"},
840
+ body:JSON.stringify({formula, display_name:name, model_name:$("#f_model").value.trim(),
841
+ rationale:$("#f_why").value.trim(), structure:$("#f_cif").value.trim(),
842
+ visibility:document.querySelector('input[name="vis"]:checked').value, season:SEASON})});
843
+ const j = await r.json();
844
+ if(!r.ok){ m.className="msg bad"; m.textContent = j.detail || ("HTTP "+r.status); }
845
+ else{ m.className="msg ok"; m.innerHTML = d.ok(j.candidate_id, j.queue_position);
846
+ $("#f_formula").value=""; $("#f_cif").value=""; load(); MODELS_LOADED=false; }
847
+ }catch(e){ m.className="msg bad"; m.textContent=String(e); }
848
+ $("#go").disabled = false;
849
+ };
850
+
851
+ (async function boot(){
852
+ try{
853
+ const s = await (await fetch("/api/seasons")).json();
854
+ SEASONS = s.seasons || [];
855
+ const open = SEASONS.filter(x=>x.open);
856
+ SEASON = (open.length?open:SEASONS).slice(-1)[0]?.number || 1;
857
+ }catch(e){}
858
+ try{ ME = await (await fetch("/api/me")).json(); }catch(e){ ME = null; }
859
+ renderAuth();
860
+ setLang("ko");
861
+ showTab();
862
+ await load();
863
+ setInterval(load, 20000);
864
+ setInterval(()=>{ if(TAB==="models") loadModels(); }, 600000);
865
+ })();
866
+ </script>
867
+ </body>
868
+ </html>