/** * PK10 Betting Logic * Depends on: pk10-sound.js, pk10-race.js * Globals expected: GAME_ID, selectedChip, bets, periodData, historyCache, * rankNames, dtPairs, I18N, curMissRank */ function formatBetLabel(type,value){ var m; if(type==='rank'&&(m=value.match(/^rank(\d+)_(\d+)$/))){return(rankNames[+m[1]]||I18N.rank_prefix+m[1])+' #'+m[2];} if(type==='bs'&&(m=value.match(/^rank(\d+)_(big|small)$/))){return(rankNames[+m[1]]||I18N.rank_prefix+m[1])+' '+(m[2]==='big'?I18N.big:I18N.small);} if(type==='oe'&&(m=value.match(/^rank(\d+)_(odd|even)$/))){return(rankNames[+m[1]]||I18N.rank_prefix+m[1])+' '+(m[2]==='odd'?I18N.odd:I18N.even);} if(type==='dt'&&(m=value.match(/^dt(\d+)_(dragon|tiger)$/))){var p=dtPairs[+m[1]]||[0,0];return(rankNames[p[0]]||p[0])+'vs'+(rankNames[p[1]]||p[1])+' '+(m[2]==='dragon'?I18N.dragon:I18N.tiger);} if(type==='sum'&&(m=value.match(/^sum_(\d+)$/))){return I18N.sum+' '+m[1];} if(type==='sum_bs'){var sm={sum_big:I18N.sum_big,sum_small:I18N.sum_small,sum_odd:I18N.sum_odd,sum_even:I18N.sum_even};return sm[value]||value;} return type+':'+value; } function selectChip(a,el){selectedChip=a;document.querySelectorAll('.amount-btn').forEach(function(c){c.classList.remove('active');});if(el)el.classList.add('active'); var ci=document.getElementById('customAmount');if(ci)ci.value=a;} function toggleCustomInput(){var row=document.getElementById('customInputRow');if(row)row.style.display=row.style.display==='none'?'flex':'none';} function applyCustomChip(){var v=parseInt(document.getElementById('customAmount').value);if(!v||v<=0){showToast(I18N.error+': > 0','error');return;}selectedChip=v;document.querySelectorAll('.amount-btn').forEach(function(c){c.classList.remove('active');});} function addBet(type,target,el){if(periodData&&periodData.status!=='pending'){showToast(I18N.period_closed,'error');return;}var key=type+'_'+target;if(!bets[key])bets[key]={type:type,value:target,amount:0,el:el};bets[key].amount+=selectedChip;el.classList.add('selected');var badge=el.querySelector('.bet-amount-badge');if(!badge){badge=document.createElement('span');badge.className='bet-amount-badge';el.appendChild(badge);}badge.textContent=bets[key].amount>=1000?(bets[key].amount/1000).toFixed(1)+'k':bets[key].amount;updateBetSummary();} function clearBets(){bets={};document.querySelectorAll('.bet-btn.selected,.bet-cell.selected').forEach(function(e){e.classList.remove('selected');var b=e.querySelector('.bet-amount-badge');if(b)b.remove();});updateBetSummary();} function updateBetSummary(){var total=0,count=0;Object.values(bets).forEach(function(b){total+=b.amount;count++;});document.getElementById('betCount').textContent=count; var badge=document.getElementById('betFloatBadge');if(badge)badge.classList.toggle('hide',count===0);} function toggleBetPanel(){/* placeholder */} function submitBets(){var arr=Object.values(bets);if(!arr.length){showToast(I18N.place_bet,'error');return;}if(!periodData||!periodData.period_number){showToast(I18N.waiting,'error');return;}fetch('/api/bet',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({game_id:GAME_ID,period_number:periodData.period_number,bets:arr})}).then(function(r){return r.json();}).then(function(d){if(d.success){showToast(d.message,'ok');document.getElementById('balanceDisplay').textContent=parseFloat(d.new_balance).toFixed(2);clearBets();pollPeriod();}else{showToast(d.message,'error');}}).catch(function(e){showToast(I18N.net_err,'error');});} function showBetTab(tab,btn){['Rank','Bs','Sum','Quick','Dragon','Miss'].forEach(function(t){var p=document.getElementById('panel'+t);if(p)p.classList.toggle('hidden',t.toLowerCase()!==tab);});document.querySelectorAll('.side-menu .mi').forEach(function(m){m.classList.remove('active');});if(btn)btn.classList.add('active');if(tab==='dragon')renderDragonStreak();if(tab==='miss')renderMissPanel();} // ===== Quick bet ===== function quickBet(type,side){ if(periodData&&periodData.status!=='pending'){showToast(I18N.period_closed,'error');return;} var count=0; if(type==='bs'||type==='oe'){ for(var r=1;r<=10;r++){ var target='rank'+r+'_'+side; var key=type+'_'+target; if(!bets[key])bets[key]={type:type,value:target,amount:0}; bets[key].amount+=selectedChip;count++; syncBetCellUI(key,bets[key].amount); } } else if(type==='dt'){ for(var r=1;r<=5;r++){ var target='dt'+r+'_'+side; var key='dt_'+target; if(!bets[key])bets[key]={type:'dt',value:target,amount:0}; bets[key].amount+=selectedChip;count++; syncBetCellUI(key,bets[key].amount); } } else if(type==='sum_bs'){ var key='sum_bs_'+side; if(!bets[key])bets[key]={type:'sum_bs',value:side,amount:0}; bets[key].amount+=selectedChip;count=1; syncBetCellUI(key,bets[key].amount); } updateBetSummary(); showToast(count+I18N.bets_added,'ok'); } function syncBetCellUI(key,amount){ var parts=key.split('_');var type=parts[0]; var value=key.substring(type.length+1); if(type==='sum'){type='sum_bs';value=key.substring(7);} var cells=document.querySelectorAll('.bet-cell,.bet-btn'); for(var i=0;i-1){ cells[i].classList.add('selected'); var badge=cells[i].querySelector('.bet-amount-badge'); if(!badge){badge=document.createElement('span');badge.className='bet-amount-badge';cells[i].appendChild(badge);} badge.textContent=amount>=1000?(amount/1000).toFixed(1)+'k':amount; break; } } } // ===== Miss stats ===== function switchMissRank(idx,el){ curMissRank=idx; document.querySelectorAll('#missTabs .miss-tab').forEach(function(t){t.classList.remove('active');}); if(el)el.classList.add('active'); renderMissPanel(); } function renderMissPanel(){ var D=historyCache; var grid=document.getElementById('missGrid'); var tsBox=document.getElementById('missTwoSide'); if(!grid||!tsBox)return; if(!D||!D.length){grid.innerHTML='
'+I18N.no_bets+'
';tsBox.innerHTML='';return;} var r=curMissRank+1; var html=''; for(var num=1;num<=10;num++){ var miss=-1; for(var i=0;i=5)cls='cold'; html+='
'+num+'
'+val+'
'; } grid.innerHTML=html; var v0=+D[0]['rank_'+r]; var sides=[ {name:I18N.big,check:function(v){return v>5;}}, {name:I18N.small,check:function(v){return v<=5;}}, {name:I18N.odd,check:function(v){return v%2===1;}}, {name:I18N.even,check:function(v){return v%2===0;}} ]; if(r<=5){ sides.push({name:I18N.dragon,check:function(v,row){return +row['rank_'+r]>+row['rank_'+(11-r)];}}); sides.push({name:I18N.tiger,check:function(v,row){return +row['rank_'+r]<+row['rank_'+(11-r)];}}); } var tsHtml=''; sides.forEach(function(sd){ var miss=-1; for(var i=0;i'+val+''; }); tsBox.innerHTML=tsHtml; } // ===== Dragon streak stats ===== function renderDragonStreak(){ var box=document.getElementById('dragonStreakList'); if(!box)return; var D=historyCache; if(!D||D.length<2){box.innerHTML='
'+I18N.no_bets+'
';return;} var streaks=[]; var COLORS={big:'#e74c3c',small:'#3498db',odd:'#f39c12',even:'#9b59b6',dragon:'#e74c3c',tiger:'#3498db'}; var LABELS={big:I18N.big,small:I18N.small,odd:I18N.odd,even:I18N.even,dragon:I18N.dragon,tiger:I18N.tiger}; for(var r=1;r<=10;r++){ var v0=+D[0]['rank_'+r];if(!v0)continue; var bs0=v0>5?'big':'small',bsCnt=1; for(var i=1;i5?'big':'small')===bs0)bsCnt++;else break;} if(bsCnt>=2)streaks.push({rank:rankNames[r],key:bs0,color:COLORS[bs0],label:LABELS[bs0],count:bsCnt}); var oe0=v0%2?'odd':'even',oeCnt=1; for(var i=1;i=2)streaks.push({rank:rankNames[r],key:oe0,color:COLORS[oe0],label:LABELS[oe0],count:oeCnt}); if(r<=5){ var a=+D[0]['rank_'+r],b=+D[0]['rank_'+(11-r)]; var dt0=a>b?'dragon':'tiger',dtCnt=1; for(var i=1;ib2?'dragon':'tiger')===dt0)dtCnt++;else break;} if(dtCnt>=2)streaks.push({rank:rankNames[r],key:dt0,color:COLORS[dt0],label:LABELS[dt0],count:dtCnt}); } } var s0=(+D[0].rank_1)+(+D[0].rank_2); if(s0){ var sbs0=s0>=12?'big':'small',sbsCnt=1; for(var i=1;i=12?'big':'small')===sbs0)sbsCnt++;else break;} if(sbsCnt>=2)streaks.push({rank:I18N.sum,key:sbs0,color:COLORS[sbs0],label:LABELS[sbs0],count:sbsCnt}); var soe0=s0%2?'odd':'even',soeCnt=1; for(var i=1;i=2)streaks.push({rank:I18N.sum,key:soe0,color:COLORS[soe0],label:LABELS[soe0],count:soeCnt}); } streaks.sort(function(a,b){return b.count-a.count;}); if(!streaks.length){box.innerHTML='
'+I18N.no_bets+'
';return;} var maxCnt=streaks[0].count; var html=''; streaks.forEach(function(s){ var pct=Math.round(s.count/Math.max(maxCnt,1)*100); var fire=s.count>=5?'🔥':s.count>=3?'💨':''; html+='
' +''+s.rank+'' +''+s.label+'' +'
' +''+s.count+'' +(fire?''+fire+'':'') +'
'; }); box.innerHTML=html; } // ===== Render result ===== function renderResult(result,container){if(!result)return;var el=document.getElementById(container);el.innerHTML='';['rank_1','rank_2','rank_3','rank_4','rank_5','rank_6','rank_7','rank_8','rank_9','rank_10'].forEach(function(k){var v=result[k];if(!v)return;var d=document.createElement('div');d.className='car c'+v;d.style.cssText='width:28px;height:28px;font-size:11px';d.textContent=v;el.appendChild(d);}); var tags=document.getElementById('lastResultTags');if(!tags)return;tags.innerHTML='';var r1=+result.rank_1,r2=+result.rank_2;if(r1&&r2){var sum=r1+r2;var items=[sum,(sum>=12?I18N.big:I18N.small),(sum%2?I18N.odd:I18N.even)];for(var i=1;i<=5;i++){var a=+result['rank_'+i],b=+result['rank_'+(11-i)];if(a&&b)items.push(a>b?I18N.dragon:I18N.tiger);}items.forEach(function(t){var s=document.createElement('span');s.textContent=t;tags.appendChild(s);}); var badge=document.getElementById('sumHotBadge');if(badge){badge.textContent=sum;badge.style.display='inline-flex';}}} // ===== Render my bets ===== function renderMyBets(myBets){var list=document.getElementById('myBetsList');var countEl=document.getElementById('myBetsCount');if(!myBets||!myBets.length){list.innerHTML='
'+I18N.no_bets+'
';countEl.textContent='0';return;}countEl.textContent=myBets.length;var total=0,html='';myBets.forEach(function(b){var label=formatBetLabel(b.bet_type,b.bet_value);var amt=parseFloat(b.amount);total+=amt;var sl=b.status==='pending'?''+I18N.draw+'':b.status==='win'?'+'+parseFloat(b.win_amount).toFixed(0)+'':'-'+amt.toFixed(0)+'';html+='
'+label+''+amt.toFixed(0)+' x'+b.odds+''+sl+'
';});html+='
'+I18N.total+''+total.toFixed(0)+'
';list.innerHTML=html;} function renderLastMyBets(lastMyBets){var panel=document.getElementById('lastResultPanel');var list=document.getElementById('lastMyBetsList');var profitEl=document.getElementById('lastProfitDisplay');if(!lastMyBets||!lastMyBets.length){panel.classList.add('hidden');return;}panel.classList.remove('hidden');var totalWin=0,totalBet=0,html='';lastMyBets.forEach(function(b){var label=formatBetLabel(b.bet_type,b.bet_value);var amt=parseFloat(b.amount);totalBet+=amt;if(b.status==='win'){var win=parseFloat(b.win_amount);totalWin+=win+amt;html+='
'+label+'+'+win.toFixed(0)+'
';}else{html+='
'+label+'-'+amt.toFixed(0)+'
';}});list.innerHTML=html;var profit=totalWin-totalBet;if(profit>0){profitEl.style.color='var(--success)';profitEl.textContent='+'+profit.toFixed(0);}else if(profit<0){profitEl.style.color='var(--danger)';profitEl.textContent=profit.toFixed(0);}else{profitEl.style.color='var(--text3)';profitEl.textContent='0';}} // ===== Toast & Lang ===== function showToast(msg,type){var t=document.createElement('div');t.style.cssText='position:fixed;top:80px;left:50%;transform:translateX(-50%);padding:10px 24px;border-radius:24px;font-size:13px;z-index:999;color:#fff;box-shadow:0 4px 16px rgba(0,0,0,.15)';t.style.background=type==='ok'?'var(--success)':'var(--danger)';t.textContent=msg;document.body.appendChild(t);setTimeout(function(){t.remove();},2500);} function setLang(l){fetch('/api/set-lang',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({lang:l})}).then(function(){location.reload();});}