Chotto.app
Login
Sign Up
ES
App Name
kuyawa / reversi
App Icon in SVG
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" fill="none"> <!-- Rounded Base (The App Icon Shape) --> <rect x="0" y="0" width="128" height="128" rx="28" ry="28" fill="#166534"/> <!-- Simplified 4x4 Grid Overlay (Central part of the 8x8 board) --> <g stroke="#15803D" stroke-width="2"> <line x1="16" y1="48" x2="112" y2="48"/> <line x1="16" y1="80" x2="112" y2="80"/> <line x1="48" y1="16" x2="48" y2="112"/> <line x1="80" y1="16" x2="80" y2="112"/> </g> <!-- Central Discs (Classic Dynamic Start Position) --> <!-- Top Left: White Disc --> <circle cx="48" cy="48" r="16" fill="#FFFFFF" stroke="#000000" stroke-width="1.5"/> <!-- Top Right: Black Disc --> <circle cx="80" cy="48" r="16" fill="#000000" stroke="#FFFFFF" stroke-width="0.5"/> <!-- Bottom Left: Black Disc --> <circle cx="48" cy="80" r="16" fill="#000000" stroke="#FFFFFF" stroke-width="0.5"/> <!-- Bottom Right: White Disc --> <circle cx="80" cy="80" r="16" fill="#FFFFFF" stroke="#000000" stroke-width="1.5"/> </svg>
HTML Content
<!DOCTYPE html> <html lang="en" data-theme="dark"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Reversi</title> <style> *,*::before,*::after{margin:0;padding:0;box-sizing:border-box} :root{--flip-half:0.2s;--stagger:40ms} [data-theme="dark"]{ --bg:#0b0d13;--bg2:#12151f;--fg:#e4e2dc;--muted:#6e717a; --board:#1d7f47;--board-line:#13603a;--board-shadow:rgba(0,0,0,0.55); --accent:#e4a63a;--accent-dim:rgba(228,166,58,0.1);--accent-glow:rgba(228,166,58,0.22); --valid:rgba(228,166,58,0.32);--card:#161923;--card-b:#232738; --btn:#232738;--btn-h:#2f3450;--btn-t:#c4c2bc; --overlay:rgba(11,13,19,0.88);--piece-sh:rgba(0,0,0,0.5); --bk1:#2c2c2c;--bk2:#0a0a0a;--wh1:#ffffff;--wh2:#d6d2c9; --last:rgba(228,166,58,0.45);--preview-b:rgba(30,30,30,0.35);--preview-w:rgba(240,236,228,0.35); } [data-theme="light"]{ --bg:#f0ece3;--bg2:#e5e0d5;--fg:#1a1a1a;--muted:#7a7a7a; --board:#2e8d50;--board-line:#237a40;--board-shadow:rgba(0,0,0,0.14); --accent:#c4872a;--accent-dim:rgba(196,135,42,0.08);--accent-glow:rgba(196,135,42,0.18); --valid:rgba(196,135,42,0.28);--card:#ffffff;--card-b:#d6d1c6; --btn:#ddd8cc;--btn-h:#cfc9bd;--btn-t:#3a3a3a; --overlay:rgba(240,236,227,0.92);--piece-sh:rgba(0,0,0,0.22); --bk1:#333;--bk2:#111;--wh1:#fff;--wh2:#dbd6cc; --last:rgba(196,135,42,0.38);--preview-b:rgba(30,30,30,0.2);--preview-w:rgba(255,255,255,0.5); } body{ background:var(--bg);color:var(--fg); font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; min-height:100vh;display:flex;flex-direction:column;align-items:center; transition:background .35s,color .35s;overflow-x:hidden; } body::before{ content:'';position:fixed;inset:0;pointer-events:none;z-index:-1; background:radial-gradient(ellipse at 15% 0%,var(--accent-dim) 0%,transparent 55%), radial-gradient(ellipse at 85% 100%,var(--accent-dim) 0%,transparent 55%); } header{width:100%;max-width:600px;padding:22px 20px 0;display:flex;align-items:center;justify-content:space-between} .logo{font-size:26px;font-weight:800;letter-spacing:3px;text-transform:uppercase} .logo span{color:var(--accent)} .theme-btn{ width:44px;height:44px;border-radius:11px;border:1px solid var(--card-b); background:var(--btn);cursor:pointer;display:flex;align-items:center;justify-content:center; transition:background .2s,border-color .2s,transform .15s;position:relative;overflow:hidden; } .theme-btn:hover{background:var(--btn-h);transform:scale(1.06)} .theme-btn:active{transform:scale(.94)} .icon-wrap{width:20px;height:20px;position:relative} .sun{position:absolute;inset:0;border-radius:50%;background:var(--accent); box-shadow:0 0 0 2.5px var(--btn),0 0 0 4.5px var(--accent);transition:opacity .3s,transform .3s} .moon{position:absolute;inset:-1px;border-radius:50%;background:var(--fg); box-shadow:inset -5px -2px 0 0 var(--btn);transition:opacity .3s,transform .3s} [data-theme="dark"] .sun{opacity:0;transform:rotate(90deg) scale(.4)} [data-theme="dark"] .moon{opacity:1;transform:rotate(0) scale(1)} [data-theme="light"] .sun{opacity:1;transform:rotate(0) scale(1)} [data-theme="light"] .moon{opacity:0;transform:rotate(-90deg) scale(.4)} main{width:100%;max-width:600px;padding:18px 16px;display:flex;flex-direction:column;align-items:center;gap:16px;flex:1} .scores{display:flex;width:100%;gap:10px;justify-content:center} .sc{flex:1;max-width:190px;background:var(--card);border:1px solid var(--card-b); border-radius:13px;padding:12px 16px;display:flex;align-items:center;gap:11px; transition:background .3s,border-color .3s,box-shadow .35s} .sc.on{border-color:var(--accent);box-shadow:0 0 18px var(--accent-glow)} .sc-dot{width:34px;height:34px;border-radius:50%;flex-shrink:0} .sc-dot.bk{background:radial-gradient(circle at 36% 34%,var(--bk1),var(--bk2));box-shadow:0 2px 5px var(--piece-sh)} .sc-dot.wh{background:radial-gradient(circle at 36% 34%,var(--wh1),var(--wh2));box-shadow:0 2px 5px var(--piece-sh)} .sc-info{display:flex;flex-direction:column} .sc-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1.6px;color:var(--muted)} .sc-val{font-size:26px;font-weight:800;line-height:1.15} .board-wrap{position:relative;width:100%;max-width:480px;aspect-ratio:1} .board{ width:100%;height:100%;background:var(--board-line);border-radius:10px; display:grid;grid-template-columns:repeat(8,1fr);grid-template-rows:repeat(8,1fr); padding:4px;gap:2px; box-shadow:0 8px 36px var(--board-shadow),inset 0 1px 0 rgba(255,255,255,.04); border:3px solid var(--board-line); } .cell{ background:var(--board);border-radius:2px;position:relative; display:flex;align-items:center;justify-content:center;cursor:default; transition:background .12s; } .cell.ok{cursor:pointer} .cell.ok::after{ content:'';width:28%;height:28%;border-radius:50%;background:var(--valid); transition:transform .18s,background .18s;position:absolute;z-index:1; } .cell.ok:hover{background:var(--board-line)} .cell.ok:hover::after{transform:scale(1.5);background:var(--accent)} .cell.ok:hover::before{ content:'';width:76%;height:76%;border-radius:50%;position:absolute;z-index:0; transition:opacity .15s; } .board.tb .cell.ok:hover::before{background:var(--preview-b);opacity:1} .board.tw .cell.ok:hover::before{background:var(--preview-w);opacity:1} .cell.lm{box-shadow:inset 0 0 0 2px var(--last)} .piece{ width:80%;height:80%;border-radius:50%;position:absolute;z-index:2; will-change:transform; } .piece.bk{ background:radial-gradient(circle at 38% 34%,var(--bk1),var(--bk2)); box-shadow:0 3px 7px var(--piece-sh),inset 0 1px 2px rgba(255,255,255,.08); } .piece.wh{ background:radial-gradient(circle at 38% 34%,var(--wh1),var(--wh2)); box-shadow:0 3px 7px var(--piece-sh),inset 0 -1px 2px rgba(0,0,0,.08); } .piece.fo{animation:flipO var(--flip-half) ease-in forwards} .piece.fi{animation:flipI var(--flip-half) ease-out forwards} .piece.pop{animation:popIn .22s ease-out} @keyframes flipO{0%{transform:scaleX(1) scaleY(1)}100%{transform:scaleX(0) scaleY(1.12)}} @keyframes flipI{0%{transform:scaleX(0) scaleY(1.12)}100%{transform:scaleX(1) scaleY(1)}} @keyframes popIn{0%{transform:scale(0);opacity:0}55%{transform:scale(1.18)}100%{transform:scale(1);opacity:1}} .status{width:100%;max-width:480px;text-align:center;min-height:24px} .stxt{font-size:13.5px;font-weight:500;color:var(--muted);transition:color .3s} .stxt.hl{color:var(--accent);font-weight:700} .ctrls{display:flex;gap:8px;flex-wrap:wrap;justify-content:center} .btn{ padding:9px 18px;border-radius:9px;border:1px solid var(--card-b); background:var(--btn);color:var(--btn-t);font-size:12.5px;font-weight:600; letter-spacing:.4px;cursor:pointer;user-select:none; transition:background .2s,border-color .2s,transform .14s,box-shadow .2s; } .btn:hover{background:var(--btn-h);border-color:var(--accent);box-shadow:0 0 10px var(--accent-glow)} .btn:active{transform:scale(.95)} .btn.act{background:var(--accent);color:#0a0a0a;border-color:var(--accent)} .btn.act:hover{filter:brightness(1.12);box-shadow:0 0 14px var(--accent-glow)} .overlay{ position:fixed;inset:0;background:var(--overlay);display:flex;align-items:center;justify-content:center; z-index:100;opacity:0;pointer-events:none;transition:opacity .4s;backdrop-filter:blur(8px); } .overlay.show{opacity:1;pointer-events:all} .ov-card{ background:var(--card);border:1px solid var(--card-b);border-radius:18px; padding:36px 44px;text-align:center; transform:scale(.88) translateY(24px);transition:transform .45s cubic-bezier(.16,1,.3,1); box-shadow:0 20px 50px var(--board-shadow); } .overlay.show .ov-card{transform:scale(1) translateY(0)} .ov-t{font-size:30px;font-weight:800;margin-bottom:6px} .ov-s{font-size:15px;color:var(--muted);margin-bottom:26px} .ov-scores{display:flex;justify-content:center;gap:36px;margin-bottom:28px} .ov-sc{display:flex;flex-direction:column;align-items:center;gap:7px} .ov-dot{width:42px;height:42px;border-radius:50%} .ov-num{font-size:34px;font-weight:800} .ov-num.w{color:var(--accent)} .toast{ position:fixed;bottom:28px;left:50%; transform:translateX(-50%) translateY(90px); background:var(--card);border:1px solid var(--card-b);color:var(--fg); padding:11px 22px;border-radius:11px;font-size:13.5px;font-weight:500; box-shadow:0 6px 28px var(--board-shadow); transition:transform .4s cubic-bezier(.16,1,.3,1);z-index:200;pointer-events:none; } .toast.show{transform:translateX(-50%) translateY(0)} footer{padding:14px 20px 18px;text-align:center;font-size:11px;color:var(--muted);letter-spacing:.3px} @media(max-width:480px){ header{padding:14px 14px 0} .logo{font-size:20px;letter-spacing:2px} main{padding:12px 10px;gap:12px} .sc{padding:9px 12px;gap:8px;border-radius:10px} .sc-dot{width:28px;height:28px} .sc-val{font-size:22px} .board{padding:3px;gap:1.5px;border-width:2px;border-radius:8px} .ov-card{padding:26px 22px;margin:0 14px} .ov-t{font-size:24px} .ov-num{font-size:28px} .btn{padding:8px 14px;font-size:11.5px} } @media(prefers-reduced-motion:reduce){ *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important} } </style> </head> <body> <header> <div class="logo">Re<span>versi</span></div> <button class="theme-btn" id="themeBtn" aria-label="Toggle theme"> <div class="icon-wrap"><div class="sun"></div><div class="moon"></div></div> </button> </header> <main> <div class="scores"> <div class="sc" id="bkCard"><div class="sc-dot bk"></div><div class="sc-info"><span class="sc-lbl">Black</span><span class="sc-val" id="bkVal">2</span></div></div> <div class="sc" id="whCard"><div class="sc-dot wh"></div><div class="sc-info"><span class="sc-lbl">White</span><span class="sc-val" id="whVal">2</span></div></div> </div> <div class="board-wrap"><div class="board" id="board" role="grid" aria-label="Reversi board"></div></div> <div class="status"><span class="stxt" id="stxt">Black's turn</span></div> <div class="ctrls"> <button class="btn" id="newBtn">New Game</button> <button class="btn act" id="pvpBtn">vs Player</button> <button class="btn" id="aiBtn">vs Computer</button> </div> </main> <div class="overlay" id="ov"> <div class="ov-card"> <div class="ov-t" id="ovT">Game Over</div> <div class="ov-s" id="ovS">Final score</div> <div class="ov-scores"> <div class="ov-sc"> <div class="ov-dot bk" style="background:radial-gradient(circle at 38% 34%,var(--bk1),var(--bk2));box-shadow:0 3px 7px var(--piece-sh)"></div> <span class="ov-num" id="ovBk">0</span> </div> <div class="ov-sc"> <div class="ov-dot wh" style="background:radial-gradient(circle at 38% 34%,var(--wh1),var(--wh2));box-shadow:0 3px 7px var(--piece-sh)"></div> <span class="ov-num" id="ovWh">0</span> </div> </div> <button class="btn" id="againBtn" style="padding:11px 30px;font-size:14px">Play Again</button> </div> </div> <div class="toast" id="toast"></div> <footer>Place pieces to outflank your opponent</footer> <script> /* ── Constants ── */ const E=0,B=1,W=2,SZ=8; const DR=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]; const WT=[ [120,-20,20,5,5,20,-20,120],[-20,-40,-5,-5,-5,-5,-40,-20], [20,-5,15,3,3,15,-5,20],[5,-5,3,3,3,3,-5,5], [5,-5,3,3,3,3,-5,5],[20,-5,15,3,3,15,-5,20], [-20,-40,-5,-5,-5,-5,-40,-20],[120,-20,20,5,5,20,-20,120] ]; /* ── State ── */ let bd,cur,over,aiOn,busy,lastM,passes; /* ── DOM refs ── */ const $=id=>document.getElementById(id); const boardEl=$('board'),bkVal=$('bkVal'),whVal=$('whVal'); const bkCard=$('bkCard'),whCard=$('whCard'),stxt=$('stxt'); const ov=$('ov'),ovT=$('ovT'),ovS=$('ovS'),ovBk=$('ovBk'),ovWh=$('ovWh'); const toastEl=$('toast'); /* ── Core logic ── */ function inB(r,c){return r>=0&&r<SZ&&c>=0&&c<SZ} function getFlips(b,r,c,p){ if(b[r][c]!==E)return[]; const o=p===B?W:B;let all=[]; for(const[dr,dc]of DR){ let f=[],nr=r+dr,nc=c+dc; while(inB(nr,nc)&&b[nr][nc]===o){f.push([nr,nc]);nr+=dr;nc+=dc} if(f.length&&inB(nr,nc)&&b[nr][nc]===p)all.push(...f); } return all; } function validMoves(b,p){ let m=[]; for(let r=0;r<SZ;r++)for(let c=0;c<SZ;c++)if(getFlips(b,r,c,p).length)m.push([r,c]); return m; } function cloneB(b){return b.map(r=>[...r])} function applyMove(b,r,c,p){ const nb=cloneB(b),fl=getFlips(b,r,c,p); nb[r][c]=p;for(const[fr,fc]of fl)nb[fr][fc]=p; return{board:nb,flips:fl}; } function countP(b){let n=0;for(let r=0;r<SZ;r++)for(let c=0;c<SZ;c++)if(b[r][c]!==E)n++;return n} function isFull(b){return countP(b)===SZ*SZ} /* ── Rendering ── */ function render(){ boardEl.innerHTML=''; boardEl.className='board '+(cur===B?'tb':'tw'); const vm=over?[]:validMoves(bd,cur); const vs=new Set(vm.map(([r,c])=>r+','+c)); for(let r=0;r<SZ;r++)for(let c=0;c<SZ;c++){ const d=document.createElement('div'); d.className='cell';d.dataset.r=r;d.dataset.c=c; d.setAttribute('role','gridcell'); if(vs.has(r+','+c)){ d.classList.add('ok'); d.addEventListener('click',()=>onClick(r,c)); d.tabIndex=0; d.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();onClick(r,c)}}); d.setAttribute('aria-label','Valid move row '+(r+1)+' col '+(c+1)); } if(lastM&&lastM[0]===r&&lastM[1]===c)d.classList.add('lm'); if(bd[r][c]!==E){ const pc=document.createElement('div'); pc.className='piece '+(bd[r][c]===B?'bk':'wh'); pc.id='p'+r+'_'+c; d.appendChild(pc); } boardEl.appendChild(d); } } function scores(){ let b=0,w=0; for(let r=0;r<SZ;r++)for(let c=0;c<SZ;c++){if(bd[r][c]===B)b++;else if(bd[r][c]===W)w++} bkVal.textContent=b;whVal.textContent=w; return{b,w}; } function updStatus(){ if(over)return; const nm=cur===B?'Black':'White'; stxt.textContent=nm+"'s turn";stxt.classList.remove('hl'); } function updActive(){ bkCard.classList.toggle('on',cur===B&&!over); whCard.classList.toggle('on',cur===W&&!over); } /* ── Toast ── */ let toastTimer=0; function toast(msg,dur){ dur=dur||2200;clearTimeout(toastTimer); toastEl.textContent=msg;toastEl.classList.add('show'); toastTimer=setTimeout(()=>toastEl.classList.remove('show'),dur); } /* ── Move execution with animation ── */ async function onClick(r,c){ if(over||busy)return; if(aiOn&&cur===W)return; const fl=getFlips(bd,r,c,cur); if(!fl.length)return; await execMove(r,c,fl); } async function execMove(r,c,fl){ busy=true; const p=cur; const newCls=p===B?'bk':'wh',oldCls=p===B?'wh':'bk'; /* Remove valid indicators */ boardEl.querySelectorAll('.cell.ok').forEach(el=>{el.classList.remove('ok');el.style.cursor='default'}); /* Remove last-move marker from previous */ boardEl.querySelectorAll('.cell.lm').forEach(el=>el.classList.remove('lm')); /* Mark last move */ const idx=r*SZ+c; boardEl.children[idx].classList.add('lm'); /* Place new piece with pop animation */ const placed=document.createElement('div'); placed.className='piece '+newCls+' pop'; boardEl.children[idx].appendChild(placed); /* Animate flips */ const halfMs=200; const promises=fl.map(([fr,fc],i)=>new Promise(res=>{ setTimeout(()=>{ const pc=document.getElementById('p'+fr+'_'+fc); if(!pc){res();return} pc.classList.add('fo'); setTimeout(()=>{ pc.classList.remove(oldCls);pc.classList.add(newCls); pc.classList.remove('fo');pc.classList.add('fi'); setTimeout(()=>{pc.classList.remove('fi');res()},halfMs); },halfMs); },i*40); })); await Promise.all(promises); /* Update data model */ bd[r][c]=p;for(const[fr,fc]of fl)bd[fr][fc]=p; lastM=[r,c];passes=0; /* Sync DOM & scores */ render();scores(); busy=false; switchTurn(); } /* ── Turn switching ── */ function switchTurn(){ cur=cur===B?W:B; const vm=validMoves(bd,cur); if(!vm.length){ passes++; if(passes>=2||isFull(bd)){endGame();return} const nm=cur===B?'Black':'White'; toast(nm+' has no moves — turn passed'); cur=cur===B?W:B; const vm2=validMoves(bd,cur); if(!vm2.length){endGame();return} } render();scores();updStatus();updActive(); if(aiOn&&cur===W&&!over)setTimeout(aiTurn,350); } /* ── Game over ── */ function endGame(){ over=true; const{b,w}=scores();updActive(); ovBk.textContent=b;ovWh.textContent=w; ovBk.classList.toggle('w',b>w);ovWh.classList.toggle('w',w>b); if(b>w){ovT.textContent='Black Wins';ovS.textContent=b+' to '+w} else if(w>b){ovT.textContent='White Wins';ovS.textContent=w+' to '+b} else{ovT.textContent='Draw';ovS.textContent=b+' to '+w} stxt.textContent='Game over';stxt.classList.add('hl'); setTimeout(()=>ov.classList.add('show'),550); } /* ── AI: Minimax with alpha-beta ── */ function aiTurn(){ if(over||busy)return; const vm=validMoves(bd,W);if(!vm.length)return; const tp=countP(bd); const depth=tp>54?8:tp>50?6:tp>44?5:4; let best=-Infinity,bestM=vm[0]; for(const[r,c]of vm){ const{board:nb}=applyMove(bd,r,c,W); const sc=mm(nb,depth-1,-Infinity,Infinity,false); if(sc>best){best=sc;bestM=[r,c]} } const fl=getFlips(bd,bestM[0],bestM[1],W); execMove(bestM[0],bestM[1],fl); } function mm(b,d,a,bt,mx){ if(d===0)return evalB(b); const p=mx?W:B,mv=validMoves(b,p); if(!mv.length){ const op=mx?B:W; if(!validMoves(b,op).length)return evalFinal(b); return mm(b,d,a,bt,!mx); } if(mx){ let v=-Infinity; for(const[r,c]of mv){ const{board:nb}=applyMove(b,r,c,W); v=Math.max(v,mm(nb,d-1,a,bt,false)); a=Math.max(a,v);if(bt<=a)break; } return v; }else{ let v=Infinity; for(const[r,c]of mv){ const{board:nb}=applyMove(b,r,c,B); v=Math.min(v,mm(nb,d-1,a,bt,true)); bt=Math.min(bt,v);if(bt<=a)break; } return v; } } function evalB(b){ let sc=0;const tp=countP(b); const ew=Math.min(1,tp/62); /* Position weights */ for(let r=0;r<SZ;r++)for(let c=0;c<SZ;c++){ if(b[r][c]===W)sc+=WT[r][c];else if(b[r][c]===B)sc-=WT[r][c]; } /* Mobility */ const wm=validMoves(b,W).length,bm=validMoves(b,B).length; sc+=(wm-bm)*(10-ew*8); /* Piece count in endgame */ let wc=0,bc=0; for(let r=0;r<SZ;r++)for(let c=0;c<SZ;c++){if(b[r][c]===W)wc++;else if(b[r][c]===B)bc++} sc+=(wc-bc)*ew*5; /* Corner bonus */ for(const[cr,cc]of[[0,0],[0,7],[7,0],[7,7]]){ if(b[cr][cc]===W)sc+=45;else if(b[cr][cc]===B)sc-=45; } return sc; } function evalFinal(b){ let w=0,bl=0; for(let r=0;r<SZ;r++)for(let c=0;c<SZ;c++){if(b[r][c]===W)w++;else if(b[r][c]===B)bl++} if(w>bl)return 10000+(w-bl);if(bl>w)return-10000-(bl-w);return 0; } /* ── Init ── */ function init(){ bd=Array.from({length:SZ},()=>Array(SZ).fill(E)); bd[3][3]=W;bd[3][4]=B;bd[4][3]=B;bd[4][4]=W; cur=B;over=false;busy=false;lastM=null;passes=0; ov.classList.remove('show'); render();scores();updStatus();updActive(); } /* ── Event listeners ── */ $('themeBtn').addEventListener('click',()=>{ const h=document.documentElement; h.setAttribute('data-theme',h.getAttribute('data-theme')==='dark'?'light':'dark'); }); $('pvpBtn').addEventListener('click',()=>{ aiOn=false;$('pvpBtn').classList.add('act');$('aiBtn').classList.remove('act');init(); }); $('aiBtn').addEventListener('click',()=>{ aiOn=true;$('aiBtn').classList.add('act');$('pvpBtn').classList.remove('act');init(); }); $('newBtn').addEventListener('click',init); $('againBtn').addEventListener('click',init); /* ── Start ── */ init(); </script> </body> </html>
Cancel