Update index.html
Browse files- index.html +42 -2
index.html
CHANGED
|
@@ -74,6 +74,10 @@ table{width:100%;border-collapse:collapse;font-size:13px}th,td{text-align:left;p
|
|
| 74 |
.vh{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px;margin-bottom:18px}.vh h2{font-size:30px}
|
| 75 |
.set{display:grid;gap:18px;max-width:560px}.set input[type=range]{width:100%;accent-color:var(--a)}
|
| 76 |
#toast{position:fixed;left:50%;bottom:calc(20px + env(safe-area-inset-bottom,0px));transform:translate(-50%,30px);background:var(--p2);border:1px solid var(--a);padding:10px 18px;border-radius:99px;font-size:13px;opacity:0;transition:.3s;z-index:90;pointer-events:none}#toast.on{opacity:1;transform:translate(-50%,0)}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
@media(max-width:980px){aside{transform:translateX(-100%);transition:.25s}aside.open{transform:none;box-shadow:0 0 0 100vmax #0009}main{margin-left:0;padding:62px 16px 30px}.menu{display:block}.hero{grid-template-columns:1fr}.art{display:none}.kpis{grid-template-columns:repeat(2,1fr)}.c5,.c7,.c4,.c6,.c8{grid-column:span 12}}
|
| 78 |
@media print{aside,.menu,.tools,.btn{display:none!important}main{margin:0}body{background:#fff;color:#000}.card{background:#fff;border-color:#999}}
|
| 79 |
</style>
|
|
@@ -151,6 +155,8 @@ table{width:100%;border-collapse:collapse;font-size:13px}th,td{text-align:left;p
|
|
| 151 |
<div class="sec">Diğer olası sınıflar</div><div class="oth" id="o"></div>
|
| 152 |
<div class="sec">Özet</div><div class="sum" id="sm">Analiz için bir belge yükleyin.</div>
|
| 153 |
<div class="sec">Çıkarılan bilgiler</div><div class="row" id="en" style="margin-top:6px"><span class="chip">–</span></div>
|
|
|
|
|
|
|
| 154 |
</div>
|
| 155 |
<div class="card c4"><h3><svg class="i"><use href="#bar"/></svg>Sınıf Dağılımı</h3><div class="donut"><div class="ring" id="ring"><span id="rt2">0</span></div><div class="lg" id="lg"></div></div></div>
|
| 156 |
<div class="card c4"><h3><svg class="i"><use href="#cal"/></svg>Son 7 Gün</h3><div class="days" id="days"></div></div>
|
|
@@ -185,6 +191,11 @@ table{width:100%;border-collapse:collapse;font-size:13px}th,td{text-align:left;p
|
|
| 185 |
<div class="card"><div class="set">
|
| 186 |
<div><label for="th">GÜVEN EŞİĞİ: <b id="thv">50</b>%</label><input type="range" id="th" min="30" max="95" value="50"></div>
|
| 187 |
<div><label for="tm">VURGU RENGİ</label><select id="tm"><option value="gold">Altın</option><option value="violet">Mor</option></select></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
<div><button class="btn o" onclick="clearH()">Geçmişi Temizle</button></div></div></div></div>
|
| 189 |
</main>
|
| 190 |
<div id="toast"></div>
|
|
@@ -211,6 +222,7 @@ const SAMPLES={
|
|
| 211 |
const USERS0=[{u:"admin",p:"admin123",r:"Yönetici"}];
|
| 212 |
const LS={get(k,d){try{return JSON.parse(localStorage.getItem(k))??d}catch(e){return d}},set(k,v){try{localStorage.setItem(k,JSON.stringify(v))}catch(e){}}};
|
| 213 |
let H=LS.get("lx_h",[]),EXTRA=LS.get("lx_u",[]),ST=LS.get("lx_s",{th:50,tm:"gold"}),ME=null;
|
|
|
|
| 214 |
const esc=s=>String(s).replace(/[&<>"]/g,c=>({"&":"&","<":"<",">":">",'"':"""}[c]));
|
| 215 |
const pc=v=>(v*100).toFixed(1);
|
| 216 |
function toast(m){const t=$("toast");t.textContent=m;t.classList.add("on");setTimeout(()=>t.classList.remove("on"),2200)}
|
|
@@ -358,7 +370,7 @@ function analyze(text,name){
|
|
| 358 |
const t0=performance.now();const r=classify(text);if(!r)return null;
|
| 359 |
const e=entities(text);const ms=+(((performance.now()-t0)/1000)+.5+Math.random()*.5).toFixed(1);
|
| 360 |
const rec={d:Date.now(),n:name||text.split("\n")[0].slice(0,48),l:r.label,c:r.conf,ms,tc:e.tc};
|
| 361 |
-
H.unshift(rec);H=H.slice(0,400);LS.set("lx_h",H);return{r,e,rec,sum:summary(text)};
|
| 362 |
}
|
| 363 |
function show(a){const{r,e}=a;const low=r.conf*100<ST.th;
|
| 364 |
$("rl").textContent=r.label;$("rc").textContent="Güven: %"+pc(r.conf);$("rb").style.width=r.conf*100+"%";
|
|
@@ -367,7 +379,7 @@ function show(a){const{r,e}=a;const low=r.conf*100<ST.th;
|
|
| 367 |
$("sm").textContent=a.sum;
|
| 368 |
const ch=[...e.dates.map(x=>"📅 "+x),...e.amt.map(x=>"💰 "+x),...e.cases.map(x=>"⚖️ "+x)].map(x=>`<span class="chip a">${esc(x)}</span>`);
|
| 369 |
if(e.tc)ch.push('<span class="chip w">⚠ KVKK: 11 haneli kimlik no tespit edildi</span>');
|
| 370 |
-
$("en").innerHTML=ch.join("")||'<span class="chip">Varlık bulunamadı</span>';refresh()}
|
| 371 |
function reset(){$("rl").textContent="Belge bekleniyor";$("rc").textContent="Güven: –";$("rb").style.width=0;$("rt").innerHTML=$("o").innerHTML="";$("sm").textContent="Analiz için bir belge yükleyin.";$("en").innerHTML='<span class="chip">–</span>'}
|
| 372 |
function run(name){const x=$("txt").value.trim();if(!x){toast("Önce metin girin veya dosya yükleyin");return}
|
| 373 |
const a=analyze(x,name);if(!a){reset();$("rl").textContent="Belirlenemedi";toast("Daha belirgin bir metin deneyin");return}show(a)}
|
|
@@ -396,6 +408,34 @@ function delH(d){H=H.filter(h=>h.d!==d);LS.set("lx_h",H);refresh()}
|
|
| 396 |
$("th").oninput=e=>{ST.th=+e.target.value;$("thv").textContent=ST.th;LS.set("lx_s",ST)};
|
| 397 |
$("tm").onchange=e=>{ST.tm=e.target.value;document.documentElement.dataset.theme=ST.tm;LS.set("lx_s",ST)};
|
| 398 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 399 |
function bars(el,rows,tot){el.innerHTML=rows.map(([k,n])=>`<div class="r" style="grid-template-columns:130px 1fr 52px"><span>${esc(k)}</span><div class="bar"><i style="width:${tot?n/tot*100:0}%"></i></div><span>${n}</span></div>`).join("")}
|
| 400 |
function refresh(){
|
| 401 |
const n=H.length,day=new Date().toDateString();
|
|
|
|
| 74 |
.vh{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px;margin-bottom:18px}.vh h2{font-size:30px}
|
| 75 |
.set{display:grid;gap:18px;max-width:560px}.set input[type=range]{width:100%;accent-color:var(--a)}
|
| 76 |
#toast{position:fixed;left:50%;bottom:calc(20px + env(safe-area-inset-bottom,0px));transform:translate(-50%,30px);background:var(--p2);border:1px solid var(--a);padding:10px 18px;border-radius:99px;font-size:13px;opacity:0;transition:.3s;z-index:90;pointer-events:none}#toast.on{opacity:1;transform:translate(-50%,0)}
|
| 77 |
+
.qw{margin-top:6px;padding:13px 15px;border-radius:12px;border:1px solid var(--ln);background:#090b1c;font-size:14px;line-height:1.65;color:#d7d9f2;white-space:pre-wrap;min-height:48px}
|
| 78 |
+
.qw.load:after{content:"▍";color:var(--a);animation:bl 1s steps(2) infinite}@keyframes bl{50%{opacity:0}}
|
| 79 |
+
.qw.er{color:var(--r)}.qh{display:flex;justify-content:space-between;align-items:center;gap:8px}.qh .sec{margin-top:14px}
|
| 80 |
+
.ck{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--tx);margin:0}.ck input{width:auto}
|
| 81 |
@media(max-width:980px){aside{transform:translateX(-100%);transition:.25s}aside.open{transform:none;box-shadow:0 0 0 100vmax #0009}main{margin-left:0;padding:62px 16px 30px}.menu{display:block}.hero{grid-template-columns:1fr}.art{display:none}.kpis{grid-template-columns:repeat(2,1fr)}.c5,.c7,.c4,.c6,.c8{grid-column:span 12}}
|
| 82 |
@media print{aside,.menu,.tools,.btn{display:none!important}main{margin:0}body{background:#fff;color:#000}.card{background:#fff;border-color:#999}}
|
| 83 |
</style>
|
|
|
|
| 155 |
<div class="sec">Diğer olası sınıflar</div><div class="oth" id="o"></div>
|
| 156 |
<div class="sec">Özet</div><div class="sum" id="sm">Analiz için bir belge yükleyin.</div>
|
| 157 |
<div class="sec">Çıkarılan bilgiler</div><div class="row" id="en" style="margin-top:6px"><span class="chip">–</span></div>
|
| 158 |
+
<div class="qh"><div class="sec">🤖 Qwen Yorumu</div><button class="chip k" id="qb" onclick="qwenAgain()" style="margin-top:12px">Yenile</button></div>
|
| 159 |
+
<div class="qw" id="qw">Sınıflandırmadan sonra Qwen burada yorum yapacak.</div>
|
| 160 |
</div>
|
| 161 |
<div class="card c4"><h3><svg class="i"><use href="#bar"/></svg>Sınıf Dağılımı</h3><div class="donut"><div class="ring" id="ring"><span id="rt2">0</span></div><div class="lg" id="lg"></div></div></div>
|
| 162 |
<div class="card c4"><h3><svg class="i"><use href="#cal"/></svg>Son 7 Gün</h3><div class="days" id="days"></div></div>
|
|
|
|
| 191 |
<div class="card"><div class="set">
|
| 192 |
<div><label for="th">GÜVEN EŞİĞİ: <b id="thv">50</b>%</label><input type="range" id="th" min="30" max="95" value="50"></div>
|
| 193 |
<div><label for="tm">VURGU RENGİ</label><select id="tm"><option value="gold">Altın</option><option value="violet">Mor</option></select></div>
|
| 194 |
+
<div><label class="ck"><input type="checkbox" id="qo"> Sınıflandırmadan sonra Qwen yorumu</label></div>
|
| 195 |
+
<div><label for="qm">QWEN MODEL</label><input type="text" id="qm" placeholder="Qwen/Qwen2.5-7B-Instruct"></div>
|
| 196 |
+
<div><label for="qe">API ADRESİ (OpenAI uyumlu)</label><input type="text" id="qe"></div>
|
| 197 |
+
<div><label for="qt">HUGGING FACE TOKEN (hf_…)</label><input type="password" id="qt" autocomplete="off" placeholder="hf_xxxxxxxx"></div>
|
| 198 |
+
<div style="font-size:12px;color:var(--mu);line-height:1.6">Token yalnızca bu tarayıcıda saklanır. Yorum için belgenin ilk ~3000 karakteri seçtiğiniz API'ye gönderilir.</div>
|
| 199 |
<div><button class="btn o" onclick="clearH()">Geçmişi Temizle</button></div></div></div></div>
|
| 200 |
</main>
|
| 201 |
<div id="toast"></div>
|
|
|
|
| 222 |
const USERS0=[{u:"admin",p:"admin123",r:"Yönetici"}];
|
| 223 |
const LS={get(k,d){try{return JSON.parse(localStorage.getItem(k))??d}catch(e){return d}},set(k,v){try{localStorage.setItem(k,JSON.stringify(v))}catch(e){}}};
|
| 224 |
let H=LS.get("lx_h",[]),EXTRA=LS.get("lx_u",[]),ST=LS.get("lx_s",{th:50,tm:"gold"}),ME=null;
|
| 225 |
+
ST=Object.assign({qo:true,qe:"https://router.huggingface.co/v1/chat/completions",qm:"Qwen/Qwen2.5-7B-Instruct",qt:""},ST);
|
| 226 |
const esc=s=>String(s).replace(/[&<>"]/g,c=>({"&":"&","<":"<",">":">",'"':"""}[c]));
|
| 227 |
const pc=v=>(v*100).toFixed(1);
|
| 228 |
function toast(m){const t=$("toast");t.textContent=m;t.classList.add("on");setTimeout(()=>t.classList.remove("on"),2200)}
|
|
|
|
| 370 |
const t0=performance.now();const r=classify(text);if(!r)return null;
|
| 371 |
const e=entities(text);const ms=+(((performance.now()-t0)/1000)+.5+Math.random()*.5).toFixed(1);
|
| 372 |
const rec={d:Date.now(),n:name||text.split("\n")[0].slice(0,48),l:r.label,c:r.conf,ms,tc:e.tc};
|
| 373 |
+
H.unshift(rec);H=H.slice(0,400);LS.set("lx_h",H);return{r,e,rec,sum:summary(text),text};
|
| 374 |
}
|
| 375 |
function show(a){const{r,e}=a;const low=r.conf*100<ST.th;
|
| 376 |
$("rl").textContent=r.label;$("rc").textContent="Güven: %"+pc(r.conf);$("rb").style.width=r.conf*100+"%";
|
|
|
|
| 379 |
$("sm").textContent=a.sum;
|
| 380 |
const ch=[...e.dates.map(x=>"📅 "+x),...e.amt.map(x=>"💰 "+x),...e.cases.map(x=>"⚖️ "+x)].map(x=>`<span class="chip a">${esc(x)}</span>`);
|
| 381 |
if(e.tc)ch.push('<span class="chip w">⚠ KVKK: 11 haneli kimlik no tespit edildi</span>');
|
| 382 |
+
$("en").innerHTML=ch.join("")||'<span class="chip">Varlık bulunamadı</span>';refresh();LAST=a;if(ST.qo)qwen(a)}
|
| 383 |
function reset(){$("rl").textContent="Belge bekleniyor";$("rc").textContent="Güven: –";$("rb").style.width=0;$("rt").innerHTML=$("o").innerHTML="";$("sm").textContent="Analiz için bir belge yükleyin.";$("en").innerHTML='<span class="chip">–</span>'}
|
| 384 |
function run(name){const x=$("txt").value.trim();if(!x){toast("Önce metin girin veya dosya yükleyin");return}
|
| 385 |
const a=analyze(x,name);if(!a){reset();$("rl").textContent="Belirlenemedi";toast("Daha belirgin bir metin deneyin");return}show(a)}
|
|
|
|
| 408 |
$("th").oninput=e=>{ST.th=+e.target.value;$("thv").textContent=ST.th;LS.set("lx_s",ST)};
|
| 409 |
$("tm").onchange=e=>{ST.tm=e.target.value;document.documentElement.dataset.theme=ST.tm;LS.set("lx_s",ST)};
|
| 410 |
|
| 411 |
+
/* Qwen yorumu */
|
| 412 |
+
let LAST=null,QAC=null;
|
| 413 |
+
function qwenAgain(){if(LAST)qwen(LAST,true);else toast("Önce bir belge analiz edin")}
|
| 414 |
+
async function qwen(a,force){
|
| 415 |
+
const box=$("qw");
|
| 416 |
+
if(!ST.qt){box.className="qw er";box.textContent="Qwen için Ayarlar'dan Hugging Face token girin.";return}
|
| 417 |
+
if(QAC)QAC.abort();QAC=new AbortController();
|
| 418 |
+
box.className="qw load";box.textContent="";
|
| 419 |
+
const{r,e}=a;
|
| 420 |
+
const info=`Sınıf: ${r.label} (güven %${pc(r.conf)})\nAnahtar kelimeler: ${r.kw.join(", ")||"-"}\nTarihler: ${e.dates.join(", ")||"-"}\nTutarlar: ${e.amt.join(", ")||"-"}\nDosya no: ${e.cases.join(", ")||"-"}\nKimlik no tespit edildi: ${e.tc?"evet":"hayır"}`;
|
| 421 |
+
const body={model:ST.qm,stream:true,max_tokens:350,temperature:.3,messages:[
|
| 422 |
+
{role:"system",content:"Sen Türk hukuku konusunda yardımcı bir asistansın. Bir sınıflandırıcının sonucunu ve belge metnini alırsın. Türkçe, en fazla 120 kelimeyle yorumla: 1) Belge ne ve sınıflandırma makul mü, 2) Dikkat edilmesi gereken noktalar/riskler, 3) Önerilen sonraki adım. Kısa maddeler kullan. Kesin hukuki tavsiye verme."},
|
| 423 |
+
{role:"user",content:info+"\n\nBelge metni:\n"+a.text.slice(0,3000)}]};
|
| 424 |
+
try{
|
| 425 |
+
const res=await fetch(ST.qe,{method:"POST",signal:QAC.signal,headers:{"Content-Type":"application/json",Authorization:"Bearer "+ST.qt},body:JSON.stringify(body)});
|
| 426 |
+
if(!res.ok){let m="";try{m=(await res.json()).error;m=m.message||m}catch(x){}throw new Error("HTTP "+res.status+(m?" – "+m:""))}
|
| 427 |
+
const rd=res.body.getReader(),dc=new TextDecoder();let buf="",out="";
|
| 428 |
+
for(;;){const{done,value}=await rd.read();if(done)break;buf+=dc.decode(value,{stream:true});
|
| 429 |
+
const ls=buf.split("\n");buf=ls.pop();
|
| 430 |
+
for(const l of ls){if(!l.startsWith("data:"))continue;const d=l.slice(5).trim();if(d==="[DONE]")continue;
|
| 431 |
+
try{const t=JSON.parse(d).choices[0].delta.content;if(t){out+=t;box.textContent=out}}catch(x){}}}
|
| 432 |
+
box.className="qw";if(!out)box.textContent="Boş yanıt geldi."
|
| 433 |
+
}catch(err){if(err.name==="AbortError")return;box.className="qw er";box.textContent="Qwen hatası: "+err.message}
|
| 434 |
+
}
|
| 435 |
+
$("qo").checked=!!ST.qo;$("qm").value=ST.qm;$("qe").value=ST.qe;$("qt").value=ST.qt;
|
| 436 |
+
$("qo").onchange=e=>{ST.qo=e.target.checked;LS.set("lx_s",ST)};
|
| 437 |
+
[["qm","qm"],["qe","qe"],["qt","qt"]].forEach(([i,k])=>$(i).onchange=e=>{ST[k]=e.target.value.trim();LS.set("lx_s",ST);toast("Kaydedildi")});
|
| 438 |
+
|
| 439 |
function bars(el,rows,tot){el.innerHTML=rows.map(([k,n])=>`<div class="r" style="grid-template-columns:130px 1fr 52px"><span>${esc(k)}</span><div class="bar"><i style="width:${tot?n/tot*100:0}%"></i></div><span>${n}</span></div>`).join("")}
|
| 440 |
function refresh(){
|
| 441 |
const n=H.length,day=new Date().toDateString();
|