File size: 3,915 Bytes
a828eeb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from ime import IME

app = FastAPI()
ime = IME()


@app.get("/suggest")
def suggest(q: str, k: int = 5):
    return {"input": q, "suggestions": ime.suggest(q, k=k)}


PAGE = """
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Manglish → Malayalam IME</title>
<style>
 :root{
   --bg:#0f1115; --panel:#171a21; --panel2:#1e222b;
   --text:#e6e8ec; --muted:#8b93a1; --accent:#4f8cff;
   --accent-soft:#22314f; --border:#2a2f3a; --chip:#232833;
 }
 *{box-sizing:border-box}
 body{
   font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
   background:var(--bg); color:var(--text);
   margin:0; min-height:100vh;
   display:flex; align-items:flex-start; justify-content:center;
 }
 .wrap{width:100%; max-width:680px; padding:56px 20px}
 h1{font-size:22px; font-weight:600; margin:0 0 4px}
 .sub{color:var(--muted); font-size:14px; margin:0 0 28px}
 #out{
   font-size:26px; line-height:1.5; min-height:52px;
   background:var(--panel); border:1px solid var(--border);
   border-radius:12px; padding:14px 16px; margin-bottom:16px;
   word-break:break-word;
 }
 #out:empty::before{content:"Your Malayalam text appears here…"; color:var(--muted); font-size:17px}
 input{
   width:100%; font-size:22px; padding:14px 16px;
   background:var(--panel2); color:var(--text);
   border:1px solid var(--border); border-radius:12px; outline:none;
   transition:border-color .15s;
 }
 input:focus{border-color:var(--accent)}
 input::placeholder{color:var(--muted)}
 #sug{margin-top:12px; min-height:52px; display:flex; flex-wrap:wrap; gap:8px}
 .s{
   padding:9px 16px; background:var(--chip); color:var(--text);
   border:1px solid var(--border); border-radius:10px;
   font-size:22px; cursor:pointer; user-select:none;
   transition:background .12s, border-color .12s;
 }
 .s:hover{background:#2b313d}
 .s:first-child{background:var(--accent-soft); border-color:var(--accent)}
 .hint{color:var(--muted); font-size:13px; margin-top:18px; line-height:1.6}
 .hint b{color:var(--text); font-weight:600}
</style>
</head>
<body>
<div class="wrap">
  <h1>Manglish → Malayalam IME</h1>
  <p class="sub">Type Malayalam using English letters.</p>

  <div id="out"></div>
  <input id="inp" placeholder="type manglish… e.g. ente veedu" autocomplete="off" autofocus>
  <div id="sug"></div>

  <p class="hint">
    <b>space</b> or <b>enter</b> = accept first suggestion ·
    <b>click</b> a chip to pick ·
    <b>backspace</b> on empty input deletes last word
  </p>
</div>

<script>
const inp=document.getElementById('inp'),
      sug=document.getElementById('sug'),
      out=document.getElementById('out');
let timer=null,current=[],ctr=0;

inp.addEventListener('input',()=>{clearTimeout(timer);timer=setTimeout(fetchSug,110)});

async function fetchSug(){
  const q=inp.value.trim();
  if(!q){sug.innerHTML='';current=[];return}
  const my=++ctr;
  try{
    const r=await fetch('/suggest?q='+encodeURIComponent(q));
    const j=await r.json();
    if(my!==ctr)return;               // ignore stale responses
    current=j.suggestions;
    sug.innerHTML=current.map(s=>`<span class="s">${s}</span>`).join('');
    [...sug.children].forEach((el,i)=>el.onclick=()=>pick(current[i]));
  }catch(e){/* ignore */}
}
function pick(s){
  out.textContent+=s+' ';
  inp.value='';sug.innerHTML='';current=[];inp.focus();
}
inp.addEventListener('keydown',e=>{
  if((e.key===' '||e.key==='Enter')&&current.length){
    e.preventDefault();pick(current[0]);
  }else if(e.key==='Backspace'&&!inp.value){
    e.preventDefault();
    out.textContent=out.textContent.trimEnd().split(' ').slice(0,-1).join(' ');
    if(out.textContent)out.textContent+=' ';
  }
});
</script>
</body>
</html>
"""


@app.get("/", response_class=HTMLResponse)
def index():
    return PAGE