prts-moonlit 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gacha.html CHANGED
@@ -1030,14 +1030,198 @@ document.addEventListener('pointerdown',function(){ac()},{once:true});
1030
1030
  function kick(){if(ctx&&ctx.state!=='running'&&ctx.resume){try{ctx.resume()}catch(e){}}if(!want||playing())return;if(bURL)ensure();else pend=1}
1031
1031
  document.addEventListener('pointerdown',kick,true);
1032
1032
  au.addEventListener('playing',function(){document.removeEventListener('pointerdown',kick,true)});
1033
- fetch('bgm.mp3').then(function(r){return r.arrayBuffer()}).then(function(a){
1034
- abuf=a;bURL=URL.createObjectURL(new Blob([a],{type:'audio/mpeg'}));
1035
- if(elemTried&&want){warmOnly=1;toWA()}
1036
- if(want&&!playing()){pend=0;ensure()}
1037
- }).catch(function(){});
1033
+ var _ld=0;
1034
+ function loadBgm(){if(_ld)return;_ld=1;
1035
+ fetch('bgm.mp3').then(function(r){return r.arrayBuffer()}).then(function(a){
1036
+ abuf=a;bURL=URL.createObjectURL(new Blob([a],{type:'audio/mpeg'}));
1037
+ if(elemTried&&want){warmOnly=1;toWA()}
1038
+ if(want&&!playing()){pend=0;ensure()}
1039
+ }).catch(function(){});
1040
+ }
1041
+ setTimeout(loadBgm,2500);
1042
+ document.addEventListener('pointerdown',loadBgm,true);
1038
1043
  if(want){setTimeout(function(){if(!playing()&&bURL){ensure()}},400)}
1039
1044
  window.__bgmFade=function(){savePos();try{if(node&&gn){var g0=gn.gain.value,t0=Date.now();var iv=setInterval(function(){var k=Math.max(0,1-(Date.now()-t0)/500);gn.gain.value=g0*k;if(k<=0)clearInterval(iv)},60)}}catch(e){}};
1040
1045
  })();
1041
1046
  </script>
1047
+
1048
+ <!-- ===== SYSTEM LOGIN 云存档 ===== -->
1049
+ <script>
1050
+ /* ===== SYSTEM LOGIN · 云存档同步引擎 v1 ===== */
1051
+ (function(){
1052
+ var TK=['whale.tasks.v1','minis_ledger_v1','minis_ledger_trash_v1','whale.bgm'];
1053
+ var BASE='https://textdb.dev/api/data/prts-acct-';
1054
+ var LS='whale.acct',LT='whale.sync.t';
1055
+ var acct=null;try{acct=JSON.parse(localStorage.getItem(LS)||'null')}catch(e){}
1056
+ var _si=localStorage.setItem.bind(localStorage),_app=0,pq=0,box=null,_dirty=0;
1057
+
1058
+ function sha(msg){
1059
+ function r(v,n){return (v>>>n)|(v<<(32-n));}
1060
+ var i,j,K=[],H=[0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19],W=new Array(64),ml=msg.length*8;
1061
+ (function(){var p=2;function pr(x){for(var d=2;d*d<=x;d++){if(x%d===0)return false}return true;}
1062
+ while(K.length<64){if(pr(p)){K.push(Math.floor(Math.pow(p,1/3)*4294967296)%4294967296);}p++;}})();
1063
+ var b=[];
1064
+ for(i=0;i<msg.length;i++){var c=msg.charCodeAt(i);
1065
+ if(c<128)b.push(c);
1066
+ else if(c<2048){b.push(192|(c>>6),128|(c&63));}
1067
+ else{b.push(224|(c>>12),128|((c>>6)&63),128|(c&63));}}
1068
+ b.push(0x80);while(b.length%64!==56)b.push(0);
1069
+ for(i=7;i>=0;i--)b.push(Math.floor(ml/Math.pow(2,i*8))&255);
1070
+ for(i=0;i<b.length;i+=64){
1071
+ for(j=0;j<16;j++)W[j]=(b[i+j*4]<<24)|(b[i+j*4+1]<<16)|(b[i+j*4+2]<<8)|b[i+j*4+3];
1072
+ for(j=16;j<64;j++){var s0=r(W[j-15],7)^r(W[j-15],18)^(W[j-15]>>>3),s1=r(W[j-2],17)^r(W[j-2],19)^(W[j-2]>>>10);W[j]=(W[j-16]+s0+W[j-7]+s1)|0;}
1073
+ var a=H[0],bb=H[1],cc=H[2],d=H[3],e=H[4],f=H[5],g=H[6],h=H[7];
1074
+ for(j=0;j<64;j++){
1075
+ var S1=r(e,6)^r(e,11)^r(e,25),ch=(e&f)^(~e&g),t1=(h+S1+ch+K[j]+W[j])|0,
1076
+ S0=r(a,2)^r(a,13)^r(a,22),mj=(a&bb)^(a&cc)^(bb&cc),t2=(S0+mj)|0;
1077
+ h=g;g=f;f=e;e=(d+t1)|0;d=cc;cc=bb;bb=a;a=(t1+t2)|0;
1078
+ }
1079
+ H[0]=(H[0]+a)|0;H[1]=(H[1]+bb)|0;H[2]=(H[2]+cc)|0;H[3]=(H[3]+d)|0;H[4]=(H[4]+e)|0;H[5]=(H[5]+f)|0;H[6]=(H[6]+g)|0;H[7]=(H[7]+h)|0;
1080
+ }
1081
+ var o='';for(i=0;i<8;i++)o+=('00000000'+(H[i]>>>0).toString(16)).slice(-8);
1082
+ return o;
1083
+ }
1084
+ function snap(){var d={};for(var i=0;i<TK.length;i++){var v=localStorage.getItem(TK[i]);if(v!==null)d[TK[i]]=v;}return d;}
1085
+ function url(){return BASE+acct.k;}
1086
+ function st(m){if(box&&box.st)box.st.textContent=m;}
1087
+ function clock(){var d=new Date();function p(n){return(n<10?'0':'')+n}return p(d.getHours())+':'+p(d.getMinutes());}
1088
+ function apply(rb){
1089
+ _app=1;try{for(var k in rb.data){_si(k,rb.data[k]);}}finally{_app=0;}
1090
+ _si(LT,String(rb.t||Date.now()));
1091
+ st('✔ 已从云端同步 '+clock()+',即将刷新…');
1092
+ setTimeout(function(){location.reload();},800);
1093
+ }
1094
+ function push(){
1095
+ if(!acct||!acct.k)return;
1096
+ _dirty=0;var t=Date.now();_si(LT,String(t));
1097
+ st('↻ 同步中…');
1098
+ fetch(url(),{method:'POST',mode:'no-cors',body:JSON.stringify({v:1,u:acct.u,t:t,data:snap()})})
1099
+ .then(function(){setTimeout(function(){verify(t)},1800);})
1100
+ .catch(function(){st('⚠ 云同步暂不可用(可用存档码手动搬)');});
1101
+ }
1102
+ function verify(t){
1103
+ fetch(url()+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
1104
+ x=(x||'').replace(/=$/,'');
1105
+ try{var rb=JSON.parse(x);if(rb.t===t){st('✔ 已同步 '+clock());return;}}catch(e){}
1106
+ if(!window.__pv){window.__pv=1;setTimeout(function(){window.__pv=0;push();},1500);}
1107
+ else{st('⚠ 云端回读不一致,稍后自动重试');}
1108
+ }).catch(function(){st('⚠ 校验失败(可能网络受限)');});
1109
+ }
1110
+ function pull(manual){
1111
+ if(!acct||!acct.k)return;
1112
+ fetch(url()+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
1113
+ x=(x||'').replace(/=$/,'');
1114
+ if(!x){if(manual)st('☁ 云端暂时没有存档——点「立即同步」上传本机数据');return;}
1115
+ var rb;try{rb=JSON.parse(x)}catch(e){st('⚠ 云端数据格式异常');return;}
1116
+ var lt=Number(localStorage.getItem(LT)||0);
1117
+ if((rb.t||0)>lt){
1118
+ var same=1;for(var kk in rb.data){if(localStorage.getItem(kk)!==rb.data[kk]){same=0;break;}}
1119
+ if(same){_si(LT,String(rb.t));if(manual)st('✔ 已是最新 '+clock());}
1120
+ else{apply(rb);}
1121
+ }
1122
+ else if(manual){
1123
+ var same2=1;for(var k2 in rb.data){if(localStorage.getItem(k2)!==rb.data[k2]){same2=0;break;}}
1124
+ if(same2){st('✔ 已是最新 '+clock());}else{push();}
1125
+ }
1126
+ else{st('✔ 已是云端最新');}
1127
+ }).catch(function(){st('⚠ 云端连接失败');});
1128
+ }
1129
+ function logout(){localStorage.removeItem(LS);acct=null;}
1130
+ var CSS='.acWrap{position:fixed;inset:0;z-index:9998;background:rgba(3,6,14,.66);display:none;align-items:center;justify-content:center}.acWrap.on{display:flex}'+
1131
+ '.acBox{width:min(86vw,360px);max-height:86vh;overflow:auto;background:rgba(7,12,24,.97);border:2px solid #4cc9ff;box-shadow:6px 6px 0 rgba(18,115,200,.45);padding:16px;font-family:ui-monospace,Menlo,monospace;color:#eef7ff}'+
1132
+ '.acBox h3{margin:0 0 4px;font-size:15px;letter-spacing:.12em;color:#8fe0ff}.acBox .sub{font-size:10px;opacity:.65;margin-bottom:10px}'+
1133
+ '.acBox input{width:100%;box-sizing:border-box;background:#0a1322;border:1.5px solid #2b4a66;color:#eef7ff;font-family:inherit;font-size:13px;padding:8px;margin:5px 0}'+
1134
+ '.acBox button{background:#0a1322;border:1.5px solid #4cc9ff;color:#4cc9ff;font-family:inherit;font-size:12px;padding:7px 10px;margin:6px 6px 0 0;cursor:pointer;letter-spacing:.08em}'+
1135
+ '.acBox button.pri{background:#4cc9ff;color:#06121f;font-weight:700}'+
1136
+ '.acBox .st{font-size:11px;margin-top:10px;min-height:14px;color:#9fe9a0;line-height:1.5;word-break:break-all}'+
1137
+ '.acBox textarea{width:100%;box-sizing:border-box;height:70px;background:#0a1322;border:1.5px solid #2b4a66;color:#9fd8ff;font-size:10px;font-family:inherit;margin-top:8px;display:none}'+
1138
+ '.acBox textarea.on{display:block}';
1139
+ var sEl=document.createElement('style');sEl.textContent=CSS;document.head.appendChild(sEl);
1140
+ var wrap=document.createElement('div');wrap.className='acWrap';document.body.appendChild(wrap);
1141
+ function esc(s){return String(s).replace(/[<>&"]/g,function(c){return{'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}[c]})}
1142
+ function render(){
1143
+ var h='<div class="acBox"><h3>SYSTEM LOGIN · 云存档</h3><div class="sub">同一账号 · 多设备同步(鱼干/任务/券/小账本)</div>';
1144
+ if(acct){
1145
+ h+='<div style="font-size:12px;margin:6px 0 2px">当前账号:<b style="color:#ffd23f">'+esc(acct.u)+'</b></div>'+
1146
+ '<button class="pri" id="acSync">↻ 立即同步</button><button id="acOut">退出登录</button>';
1147
+ }else{
1148
+ h+='<input id="acU" placeholder="用户名(自己起,例如 yanliang27)" autocomplete="username">'+
1149
+ '<input id="acP" type="password" placeholder="密码(≥4位,丢了找不回!)" autocomplete="current-password">'+
1150
+ '<button class="pri" id="acGo">登录 / 创建</button>';
1151
+ }
1152
+ h+='<button id="acExp">📤 存档码</button><button id="acImp">📥 导入</button>'+
1153
+ '<div class="st" id="acSt"></div><textarea id="acTa" spellcheck="false"></textarea>'+
1154
+ '<div style="font-size:10px;opacity:.5;margin-top:9px;line-height:1.5">密钥由「用户名+密码」派生;同一账号在任意设备登录即接回数据。忘记密码=新仓库(旧数据找不回)</div>'+
1155
+ '<button id="acX" style="border-color:#2b4a66;color:#8ea6bf;margin-top:10px">关闭 / CLOSE</button></div>';
1156
+ wrap.innerHTML=h;
1157
+ box={st:wrap.querySelector('#acSt'),ta:wrap.querySelector('#acTa')};
1158
+ bind();
1159
+ }
1160
+ function bind(){
1161
+ var g=function(id){return wrap.querySelector(id)};
1162
+ var go=g('#acGo');
1163
+ if(go)go.onclick=function(){
1164
+ var b=go,u=(g('#acU').value||'').trim(),p=g('#acP').value||'';
1165
+ if(u.length<2||p.length<4){st('用户名≥2位、密码≥4位哦');return;}
1166
+ var k=sha('prts-moonlit|'+u+'|'+p);
1167
+ if(b.getAttribute('data-mode')==='create'){
1168
+ acct={u:u,k:k};_si(LS,JSON.stringify(acct));_si(LT,String(Date.now()));
1169
+ st('✦ 仓库已创建,正在上传本机数据…');render();push();return;
1170
+ }
1171
+ st('↻ 查找云端仓库…');
1172
+ fetch(BASE+k+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
1173
+ x=(x||'').replace(/=$/,'');
1174
+ if(x&&x.length>2){
1175
+ acct={u:u,k:k};_si(LS,JSON.stringify(acct));
1176
+ var rb=null;try{rb=JSON.parse(x)}catch(e){}
1177
+ if(rb&&(rb.t||0)>Number(localStorage.getItem(LT)||0)){apply(rb);}
1178
+ else{_si(LT,String((rb&&rb.t)||Date.now()));st('✔ 已登录,云端仓库已连接 '+clock());render();}
1179
+ }else{
1180
+ b.setAttribute('data-mode','create');b.textContent='✦ 没找到仓库——点此以本机数据创建';
1181
+ st('(如果是新账号,创建后本机数据会上传成初始存档)');
1182
+ }
1183
+ }).catch(function(){st('⚠ 云端连接失败,稍后再试');});
1184
+ };
1185
+ var sy=g('#acSync');if(sy)sy.onclick=function(){pull(true)};
1186
+ var o=g('#acOut');if(o)o.onclick=function(){
1187
+ if(o.getAttribute('data-c')){logout();st('已退出登录(本机数据保留)');render();}
1188
+ else{o.setAttribute('data-c','1');o.textContent='⚠ 再点一次 = 退出登录';}};
1189
+ var e1=g('#acExp');if(e1)e1.onclick=function(){
1190
+ var b=JSON.stringify({v:1,u:acct?acct.u:'anon',t:Date.now(),data:snap()});
1191
+ var ta=g('#acTa');ta.classList.add('on');
1192
+ ta.value=btoa(unescape(encodeURIComponent(b)));ta.select();
1193
+ st('已生成存档码——全选复制保存,换设备时用「导入」');};
1194
+ var i1=g('#acImp');if(i1)i1.onclick=function(){
1195
+ var ta=g('#acTa');ta.classList.add('on');
1196
+ if(i1.getAttribute('data-c')){
1197
+ var v=ta.value.trim();
1198
+ if(!v){st('先把存档码粘到下面框里');return;}
1199
+ try{var rb=JSON.parse(decodeURIComponent(escape(atob(v))));apply(rb);}
1200
+ catch(e){st('⚠ 存档码无效');}
1201
+ return;}
1202
+ i1.setAttribute('data-c','1');ta.value='';
1203
+ st('把另一台设备的存档码粘到下方,再点一次「导入」');};
1204
+ var x=g('#acX');if(x)x.onclick=function(){wrap.classList.remove('on')};
1205
+ wrap.onclick=function(e){if(e.target===wrap)wrap.classList.remove('on')};
1206
+ }
1207
+ function open(){render();wrap.classList.add('on')}
1208
+ var _orig=localStorage.setItem;
1209
+ localStorage.setItem=function(k,v){_orig.call(localStorage,k,v);if(!_app&&acct&&acct.k&&TK.indexOf(k)>=0&&k!==LT){_dirty=1;clearTimeout(pq);pq=setTimeout(push,2200);}};
1210
+ window.addEventListener('pagehide',function(){
1211
+ if(acct&&acct.k&&_dirty){try{_dirty=0;_si(LT,String(Date.now()));
1212
+ fetch(url(),{method:'POST',mode:'no-cors',keepalive:true,body:JSON.stringify({v:1,u:acct.u,t:Date.now(),data:snap()})});}catch(e){}}
1213
+ });
1214
+ document.addEventListener('visibilitychange',function(){if(!document.hidden&&acct&&acct.k){pull(false);}});
1215
+ var btn=document.createElement('div');
1216
+ var ci=document.querySelector('.corner-ics');
1217
+ if(ci){btn.className='ci';btn.textContent='@';ci.appendChild(btn);}
1218
+ else{btn.textContent='@';btn.style.cssText='position:fixed;right:14px;bottom:60px;z-index:120;width:38px;height:38px;display:flex;align-items:center;justify-content:center;border:2px solid #4cc9ff;background:rgba(7,12,24,.92);color:#4cc9ff;font-size:17px;cursor:pointer;user-select:none;box-shadow:3px 3px 0 rgba(0,0,0,.45)';document.body.appendChild(btn);}
1219
+ btn.id='acctBtn';btn.title='云存档';
1220
+ if(acct)btn.style.background='rgba(76,201,255,.28)';
1221
+ btn.addEventListener('click',open);
1222
+ if(acct&&acct.k){setTimeout(function(){pull(false);},1600);}
1223
+ window.__shaT=sha;
1224
+ })();
1225
+ </script>
1042
1226
  </body>
1043
1227
  </html>
package/index.html CHANGED
@@ -679,11 +679,16 @@ img.av{filter:saturate(1.1) contrast(1.05) -webkit-user-drag:none}
679
679
  function kick(){if(ctx&&ctx.state!=='running'&&ctx.resume){try{ctx.resume()}catch(e){}}if(!want||playing())return;if(bURL)ensure();else pend=1}
680
680
  document.addEventListener('pointerdown',kick,true);
681
681
  au.addEventListener('playing',function(){document.removeEventListener('pointerdown',kick,true)});
682
- fetch('bgm.mp3').then(function(r){return r.arrayBuffer()}).then(function(a){
683
- abuf=a;bURL=URL.createObjectURL(new Blob([a],{type:'audio/mpeg'}));
684
- if(elemTried&&want){warmOnly=1;toWA()}
685
- if(want&&!playing()){pend=0;ensure()}
686
- }).catch(function(){});
682
+ var _ld=0;
683
+ function loadBgm(){if(_ld)return;_ld=1;
684
+ fetch('bgm.mp3').then(function(r){return r.arrayBuffer()}).then(function(a){
685
+ abuf=a;bURL=URL.createObjectURL(new Blob([a],{type:'audio/mpeg'}));
686
+ if(elemTried&&want){warmOnly=1;toWA()}
687
+ if(want&&!playing()){pend=0;ensure()}
688
+ }).catch(function(){});
689
+ }
690
+ setTimeout(loadBgm,2500);
691
+ document.addEventListener('pointerdown',loadBgm,true);
687
692
  if(want){setTimeout(function(){if(!playing()&&bURL){ensure()}},400)}
688
693
  window.__bgmFade=function(){savePos();try{if(node&&gn){var g0=gn.gain.value,t0=Date.now();var iv=setInterval(function(){var k=Math.max(0,1-(Date.now()-t0)/500);gn.gain.value=g0*k;if(k<=0)clearInterval(iv)},60)}}catch(e){}};
689
694
  })();
@@ -2250,8 +2255,8 @@ V.ledger=function(){LG.load();LG.paint()};
2250
2255
  /* ================= 战绩数据(WHALE_STATS)=================
2251
2256
  本块由 /var/minis/shared/whale/sync_record_stats.py 从 战绩簿 自动生成。
2252
2257
  更新流程:改 shared/whale/战绩.md → 跑 sync_record_stats.py → 本块自动重写 */
2253
- /*WHALE_STATS:BEGIN —— 由 sync_record_stats.py 自动生成于 2026-09-27 01:19;改数据请改 战绩.md 后重跑本脚本 */
2254
- var WHALE_STATS={"updated":"2026-09-27","stats":[["报备次数","5"],["累计抽数","22,113"],["累计六星","663"],["综合出率","2.998%"],["违约","0 次"],["单发最欧","1 抽"]],"reports":[{"d":"2026-09-26","pool":"池子未确认(主人「好像半周年」)","n":"10,000","six":"288","rate":"2.88%","gap":"34.7 抽","note":"✅ 数据有效——6★ 基础率与池子无关;理论 2.889% / 34.61 抽,偏差仅 −0.009pp ✅ 后来由数字反推:2.88% 更贴近非联动池(2.889%)而非联动池(3.00%)→ 主人的直觉正确"},{"d":"2026-09-26","pool":"彩虹六号联动(井 5/120)","n":"10,000","six":"321","rate":"3.21%","gap":"31.1 抽","note":"联动池理论 ~3.02%(含 120 硬保底),+1.1σ ✓ 正常;最欧 1 抽(一发入魂);5★ 767 个 = 7.67%(理论 8%,−3.7σ ⚠️ 偏门样本或抄录误差;20 万抽对照实测 7.985%,系统无问题)"},{"d":"2026-09-26","pool":"标准寻访(模拟器一键报备)","n":"13","six":"1","rate":"7.69%","gap":"13.0 抽","note":"🍀 唯一一彩恰落第 13 抽(未触软保底,纯运气);期望 0.26~0.38 个 → +1~1.5σ 小欧;5★×2(期望 1.04)"},{"d":"2026-09-26","pool":"P3R 联动(井 15/120)","n":"600","six":"16","rate":"2.67%","gap":"36.6 抽","note":"联动池理论 ~3.02%(含 120 硬保底);期望 18.12 个 → −0.51σ 正常波动(略非);5★ 45 个 = 7.50%(理论 8%,−0.45σ);最非 66 抽(未触软保底)· 最欧 4 抽;注:16 个六星里若有 UP 需主人补报是哪位干员"},{"d":"2026-09-27","pool":"标准寻访(模拟器)","n":"1,500","six":"37","rate":"2.47%","gap":"39.1 抽","note":"标准池理论 ~2.89%(2% 基础+软保底),期望 43.3 个 → −0.97σ 正常偏非;5★ 127 个 = 8.47%(理论 8%,+0.67σ ✓);最非 70 抽(刷新最非记录,前值 66,仍未触 99 硬保底)· 最欧 2 抽(单发总记录仍是 1 抽)"},{"d":"2026-09-26","pool":"彩虹六号联动(1 亿抽大样本)","n":"100,000,000","six":"3,036,676","rate":"3.03668%","gap":"—","note":"五批 × 2000 万,共约 76 秒。保底触发 248,381 次(0.248%)。概率再分配账目精确守恒:6★ 多出 +1.03668pp = 5★ −0.0193pp + 4★ −0.13008pp + 3★ −0.8873pp"}],"mine":[{"d":"2026-09-26","pool":"Ave Mujica 联动","n":"120","got":"丰川祥子(6★)","note":"踩中 120 硬保底最后一抽"},{"d":"2026-09-26","pool":"中坚寻访","n":"550","got":"斯卡蒂(6★)","note":"无 UP 无井,纯抽;期望 1660"},{"d":"2026-09-26","pool":"周年限定","n":"70","got":"可露希尔 + 凯尔希·思衡托","note":"70 抽两个六星,全 UP 组"}]};
2258
+ /*WHALE_STATS:BEGIN —— 由 sync_record_stats.py 自动生成于 2026-09-27 02:16;改数据请改 战绩.md 后重跑本脚本 */
2259
+ var WHALE_STATS={"updated":"2026-09-27","stats":[["报备次数","6"],["累计抽数","22,613"],["累计六星","681"],["综合出率","3.012%"],["违约","0 次"],["单发最欧","1 抽"]],"reports":[{"d":"2026-09-26","pool":"池子未确认(主人「好像半周年」)","n":"10,000","six":"288","rate":"2.88%","gap":"34.7 抽","note":"✅ 数据有效——6★ 基础率与池子无关;理论 2.889% / 34.61 抽,偏差仅 −0.009pp ✅ 后来由数字反推:2.88% 更贴近非联动池(2.889%)而非联动池(3.00%)→ 主人的直觉正确"},{"d":"2026-09-26","pool":"彩虹六号联动(井 5/120)","n":"10,000","six":"321","rate":"3.21%","gap":"31.1 抽","note":"联动池理论 ~3.02%(含 120 硬保底),+1.1σ ✓ 正常;最欧 1 抽(一发入魂);5★ 767 个 = 7.67%(理论 8%,−3.7σ ⚠️ 偏门样本或抄录误差;20 万抽对照实测 7.985%,系统无问题)"},{"d":"2026-09-26","pool":"标准寻访(模拟器一键报备)","n":"13","six":"1","rate":"7.69%","gap":"13.0 抽","note":"🍀 唯一一彩恰落第 13 抽(未触软保底,纯运气);期望 0.26~0.38 个 → +1~1.5σ 小欧;5★×2(期望 1.04)"},{"d":"2026-09-26","pool":"P3R 联动(井 15/120)","n":"600","six":"16","rate":"2.67%","gap":"36.6 抽","note":"联动池理论 ~3.02%(含 120 硬保底);期望 18.12 个 → −0.51σ 正常波动(略非);5★ 45 个 = 7.50%(理论 8%,−0.45σ);最非 66 抽(未触软保底)· 最欧 4 抽;注:16 个六星里若有 UP 需主人补报是哪位干员"},{"d":"2026-09-27","pool":"标准寻访(模拟器)","n":"1,500","six":"37","rate":"2.47%","gap":"39.1 抽","note":"标准池理论 ~2.89%(2% 基础+软保底),期望 43.3 个 → −0.97σ 正常偏非;5★ 127 个 = 8.47%(理论 8%,+0.67σ ✓);最非 70 抽(刷新最非记录,前值 66,仍未触 99 硬保底)· 最欧 2 抽(单发总记录仍是 1 抽)"},{"d":"2026-09-27","pool":"Ave Mujica 联动(井 59/120)","n":"500","six":"18","rate":"3.60%","gap":"24.5 抽","note":"联动池理论 ~3.02%(含 120 硬保底),期望 15.1 个 → +0.76σ 正常偏欧;5★ 27 个 = 5.40%(理论 8%,−2.14σ ⚠️ 五星大非号角);最非 58 抽 · 最欧 2 抽(单发总记录仍 1 抽)"},{"d":"2026-09-26","pool":"彩虹六号联动(1 亿抽大样本)","n":"100,000,000","six":"3,036,676","rate":"3.03668%","gap":"—","note":"五批 × 2000 万,共约 76 秒。保底触发 248,381 次(0.248%)。概率再分配账目精确守恒:6★ 多出 +1.03668pp = 5★ −0.0193pp + 4★ −0.13008pp + 3★ −0.8873pp"}],"mine":[{"d":"2026-09-26","pool":"Ave Mujica 联动","n":"120","got":"丰川祥子(6★)","note":"踩中 120 硬保底最后一抽"},{"d":"2026-09-26","pool":"中坚寻访","n":"550","got":"斯卡蒂(6★)","note":"无 UP 无井,纯抽;期望 1660"},{"d":"2026-09-26","pool":"周年限定","n":"70","got":"可露希尔 + 凯尔希·思衡托","note":"70 抽两个六星,全 UP 组"}]};
2255
2260
  /*WHALE_STATS:END*/
2256
2261
 
2257
2262
  /* ================= VIEW: RECORDS(战绩)================= */
@@ -2658,8 +2663,8 @@ document.addEventListener('pointerdown',function(){ac()},{once:true});
2658
2663
 
2659
2664
  /* ================= INIT ================= */
2660
2665
  $('#home').classList.add('on');applyCrt();
2661
- ['hero','crew','card','boy','fig','face','grn','taro','scene'].forEach(function(n){
2662
- var i=new Image();i.src='assets/'+n+'.jpg';});
2666
+ setTimeout(function(){['hero','crew','card','boy','fig','face','grn','taro','scene'].forEach(function(n){
2667
+ var i=new Image();i.src='assets/'+n+'.jpg';});},4000);
2663
2668
  mkDeco();buildMenu();syncRes();updTopStats();setInterval(updTopStats,5000);pulse();
2664
2669
  requestAnimationFrame(loop);
2665
2670
  boot();
@@ -2753,5 +2758,184 @@ boot();
2753
2758
  })();
2754
2759
  </script>
2755
2760
  <div style="position:fixed;left:10px;bottom:5px;font-size:9px;letter-spacing:.14em;color:#4cc9ff;opacity:.5;z-index:45;font-family:ui-monospace,Menlo,monospace;pointer-events:none">BUILD v25</div>
2761
+
2762
+ <!-- ===== SYSTEM LOGIN 云存档 ===== -->
2763
+ <script>
2764
+ /* ===== SYSTEM LOGIN · 云存档同步引擎 v1 ===== */
2765
+ (function(){
2766
+ var TK=['whale.tasks.v1','minis_ledger_v1','minis_ledger_trash_v1','whale.bgm'];
2767
+ var BASE='https://textdb.dev/api/data/prts-acct-';
2768
+ var LS='whale.acct',LT='whale.sync.t';
2769
+ var acct=null;try{acct=JSON.parse(localStorage.getItem(LS)||'null')}catch(e){}
2770
+ var _si=localStorage.setItem.bind(localStorage),_app=0,pq=0,box=null,_dirty=0;
2771
+
2772
+ function sha(msg){
2773
+ function r(v,n){return (v>>>n)|(v<<(32-n));}
2774
+ var i,j,K=[],H=[0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19],W=new Array(64),ml=msg.length*8;
2775
+ (function(){var p=2;function pr(x){for(var d=2;d*d<=x;d++){if(x%d===0)return false}return true;}
2776
+ while(K.length<64){if(pr(p)){K.push(Math.floor(Math.pow(p,1/3)*4294967296)%4294967296);}p++;}})();
2777
+ var b=[];
2778
+ for(i=0;i<msg.length;i++){var c=msg.charCodeAt(i);
2779
+ if(c<128)b.push(c);
2780
+ else if(c<2048){b.push(192|(c>>6),128|(c&63));}
2781
+ else{b.push(224|(c>>12),128|((c>>6)&63),128|(c&63));}}
2782
+ b.push(0x80);while(b.length%64!==56)b.push(0);
2783
+ for(i=7;i>=0;i--)b.push(Math.floor(ml/Math.pow(2,i*8))&255);
2784
+ for(i=0;i<b.length;i+=64){
2785
+ for(j=0;j<16;j++)W[j]=(b[i+j*4]<<24)|(b[i+j*4+1]<<16)|(b[i+j*4+2]<<8)|b[i+j*4+3];
2786
+ for(j=16;j<64;j++){var s0=r(W[j-15],7)^r(W[j-15],18)^(W[j-15]>>>3),s1=r(W[j-2],17)^r(W[j-2],19)^(W[j-2]>>>10);W[j]=(W[j-16]+s0+W[j-7]+s1)|0;}
2787
+ var a=H[0],bb=H[1],cc=H[2],d=H[3],e=H[4],f=H[5],g=H[6],h=H[7];
2788
+ for(j=0;j<64;j++){
2789
+ var S1=r(e,6)^r(e,11)^r(e,25),ch=(e&f)^(~e&g),t1=(h+S1+ch+K[j]+W[j])|0,
2790
+ S0=r(a,2)^r(a,13)^r(a,22),mj=(a&bb)^(a&cc)^(bb&cc),t2=(S0+mj)|0;
2791
+ h=g;g=f;f=e;e=(d+t1)|0;d=cc;cc=bb;bb=a;a=(t1+t2)|0;
2792
+ }
2793
+ H[0]=(H[0]+a)|0;H[1]=(H[1]+bb)|0;H[2]=(H[2]+cc)|0;H[3]=(H[3]+d)|0;H[4]=(H[4]+e)|0;H[5]=(H[5]+f)|0;H[6]=(H[6]+g)|0;H[7]=(H[7]+h)|0;
2794
+ }
2795
+ var o='';for(i=0;i<8;i++)o+=('00000000'+(H[i]>>>0).toString(16)).slice(-8);
2796
+ return o;
2797
+ }
2798
+ function snap(){var d={};for(var i=0;i<TK.length;i++){var v=localStorage.getItem(TK[i]);if(v!==null)d[TK[i]]=v;}return d;}
2799
+ function url(){return BASE+acct.k;}
2800
+ function st(m){if(box&&box.st)box.st.textContent=m;}
2801
+ function clock(){var d=new Date();function p(n){return(n<10?'0':'')+n}return p(d.getHours())+':'+p(d.getMinutes());}
2802
+ function apply(rb){
2803
+ _app=1;try{for(var k in rb.data){_si(k,rb.data[k]);}}finally{_app=0;}
2804
+ _si(LT,String(rb.t||Date.now()));
2805
+ st('✔ 已从云端同步 '+clock()+',即将刷新…');
2806
+ setTimeout(function(){location.reload();},800);
2807
+ }
2808
+ function push(){
2809
+ if(!acct||!acct.k)return;
2810
+ _dirty=0;var t=Date.now();_si(LT,String(t));
2811
+ st('↻ 同步中…');
2812
+ fetch(url(),{method:'POST',mode:'no-cors',body:JSON.stringify({v:1,u:acct.u,t:t,data:snap()})})
2813
+ .then(function(){setTimeout(function(){verify(t)},1800);})
2814
+ .catch(function(){st('⚠ 云同步暂不可用(可用存档码手动搬)');});
2815
+ }
2816
+ function verify(t){
2817
+ fetch(url()+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
2818
+ x=(x||'').replace(/=$/,'');
2819
+ try{var rb=JSON.parse(x);if(rb.t===t){st('✔ 已同步 '+clock());return;}}catch(e){}
2820
+ if(!window.__pv){window.__pv=1;setTimeout(function(){window.__pv=0;push();},1500);}
2821
+ else{st('⚠ 云端回读不一致,稍后自动重试');}
2822
+ }).catch(function(){st('⚠ 校验失败(可能网络受限)');});
2823
+ }
2824
+ function pull(manual){
2825
+ if(!acct||!acct.k)return;
2826
+ fetch(url()+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
2827
+ x=(x||'').replace(/=$/,'');
2828
+ if(!x){if(manual)st('☁ 云端暂时没有存档——点「立即同步」上传本机数据');return;}
2829
+ var rb;try{rb=JSON.parse(x)}catch(e){st('⚠ 云端数据格式异常');return;}
2830
+ var lt=Number(localStorage.getItem(LT)||0);
2831
+ if((rb.t||0)>lt){
2832
+ var same=1;for(var kk in rb.data){if(localStorage.getItem(kk)!==rb.data[kk]){same=0;break;}}
2833
+ if(same){_si(LT,String(rb.t));if(manual)st('✔ 已是最新 '+clock());}
2834
+ else{apply(rb);}
2835
+ }
2836
+ else if(manual){
2837
+ var same2=1;for(var k2 in rb.data){if(localStorage.getItem(k2)!==rb.data[k2]){same2=0;break;}}
2838
+ if(same2){st('✔ 已是最新 '+clock());}else{push();}
2839
+ }
2840
+ else{st('✔ 已是云端最新');}
2841
+ }).catch(function(){st('⚠ 云端连接失败');});
2842
+ }
2843
+ function logout(){localStorage.removeItem(LS);acct=null;}
2844
+ var CSS='.acWrap{position:fixed;inset:0;z-index:9998;background:rgba(3,6,14,.66);display:none;align-items:center;justify-content:center}.acWrap.on{display:flex}'+
2845
+ '.acBox{width:min(86vw,360px);max-height:86vh;overflow:auto;background:rgba(7,12,24,.97);border:2px solid #4cc9ff;box-shadow:6px 6px 0 rgba(18,115,200,.45);padding:16px;font-family:ui-monospace,Menlo,monospace;color:#eef7ff}'+
2846
+ '.acBox h3{margin:0 0 4px;font-size:15px;letter-spacing:.12em;color:#8fe0ff}.acBox .sub{font-size:10px;opacity:.65;margin-bottom:10px}'+
2847
+ '.acBox input{width:100%;box-sizing:border-box;background:#0a1322;border:1.5px solid #2b4a66;color:#eef7ff;font-family:inherit;font-size:13px;padding:8px;margin:5px 0}'+
2848
+ '.acBox button{background:#0a1322;border:1.5px solid #4cc9ff;color:#4cc9ff;font-family:inherit;font-size:12px;padding:7px 10px;margin:6px 6px 0 0;cursor:pointer;letter-spacing:.08em}'+
2849
+ '.acBox button.pri{background:#4cc9ff;color:#06121f;font-weight:700}'+
2850
+ '.acBox .st{font-size:11px;margin-top:10px;min-height:14px;color:#9fe9a0;line-height:1.5;word-break:break-all}'+
2851
+ '.acBox textarea{width:100%;box-sizing:border-box;height:70px;background:#0a1322;border:1.5px solid #2b4a66;color:#9fd8ff;font-size:10px;font-family:inherit;margin-top:8px;display:none}'+
2852
+ '.acBox textarea.on{display:block}';
2853
+ var sEl=document.createElement('style');sEl.textContent=CSS;document.head.appendChild(sEl);
2854
+ var wrap=document.createElement('div');wrap.className='acWrap';document.body.appendChild(wrap);
2855
+ function esc(s){return String(s).replace(/[<>&"]/g,function(c){return{'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}[c]})}
2856
+ function render(){
2857
+ var h='<div class="acBox"><h3>SYSTEM LOGIN · 云存档</h3><div class="sub">同一账号 · 多设备同步(鱼干/任务/券/小账本)</div>';
2858
+ if(acct){
2859
+ h+='<div style="font-size:12px;margin:6px 0 2px">当前账号:<b style="color:#ffd23f">'+esc(acct.u)+'</b></div>'+
2860
+ '<button class="pri" id="acSync">↻ 立即同步</button><button id="acOut">退出登录</button>';
2861
+ }else{
2862
+ h+='<input id="acU" placeholder="用户名(自己起,例如 yanliang27)" autocomplete="username">'+
2863
+ '<input id="acP" type="password" placeholder="密码(≥4位,丢了找不回!)" autocomplete="current-password">'+
2864
+ '<button class="pri" id="acGo">登录 / 创建</button>';
2865
+ }
2866
+ h+='<button id="acExp">📤 存档码</button><button id="acImp">📥 导入</button>'+
2867
+ '<div class="st" id="acSt"></div><textarea id="acTa" spellcheck="false"></textarea>'+
2868
+ '<div style="font-size:10px;opacity:.5;margin-top:9px;line-height:1.5">密钥由「用户名+密码」派生;同一账号在任意设备登录即接回数据。忘记密码=新仓库(旧数据找不回)</div>'+
2869
+ '<button id="acX" style="border-color:#2b4a66;color:#8ea6bf;margin-top:10px">关闭 / CLOSE</button></div>';
2870
+ wrap.innerHTML=h;
2871
+ box={st:wrap.querySelector('#acSt'),ta:wrap.querySelector('#acTa')};
2872
+ bind();
2873
+ }
2874
+ function bind(){
2875
+ var g=function(id){return wrap.querySelector(id)};
2876
+ var go=g('#acGo');
2877
+ if(go)go.onclick=function(){
2878
+ var b=go,u=(g('#acU').value||'').trim(),p=g('#acP').value||'';
2879
+ if(u.length<2||p.length<4){st('用户名≥2位、密码≥4位哦');return;}
2880
+ var k=sha('prts-moonlit|'+u+'|'+p);
2881
+ if(b.getAttribute('data-mode')==='create'){
2882
+ acct={u:u,k:k};_si(LS,JSON.stringify(acct));_si(LT,String(Date.now()));
2883
+ st('✦ 仓库已创建,正在上传本机数据…');render();push();return;
2884
+ }
2885
+ st('↻ 查找云端仓库…');
2886
+ fetch(BASE+k+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
2887
+ x=(x||'').replace(/=$/,'');
2888
+ if(x&&x.length>2){
2889
+ acct={u:u,k:k};_si(LS,JSON.stringify(acct));
2890
+ var rb=null;try{rb=JSON.parse(x)}catch(e){}
2891
+ if(rb&&(rb.t||0)>Number(localStorage.getItem(LT)||0)){apply(rb);}
2892
+ else{_si(LT,String((rb&&rb.t)||Date.now()));st('✔ 已登录,云端仓库已连接 '+clock());render();}
2893
+ }else{
2894
+ b.setAttribute('data-mode','create');b.textContent='✦ 没找到仓库——点此以本机数据创建';
2895
+ st('(如果是新账号,创建后本机数据会上传成初始存档)');
2896
+ }
2897
+ }).catch(function(){st('⚠ 云端连接失败,稍后再试');});
2898
+ };
2899
+ var sy=g('#acSync');if(sy)sy.onclick=function(){pull(true)};
2900
+ var o=g('#acOut');if(o)o.onclick=function(){
2901
+ if(o.getAttribute('data-c')){logout();st('已退出登录(本机数据保留)');render();}
2902
+ else{o.setAttribute('data-c','1');o.textContent='⚠ 再点一次 = 退出登录';}};
2903
+ var e1=g('#acExp');if(e1)e1.onclick=function(){
2904
+ var b=JSON.stringify({v:1,u:acct?acct.u:'anon',t:Date.now(),data:snap()});
2905
+ var ta=g('#acTa');ta.classList.add('on');
2906
+ ta.value=btoa(unescape(encodeURIComponent(b)));ta.select();
2907
+ st('已生成存档码——全选复制保存,换设备时用「导入」');};
2908
+ var i1=g('#acImp');if(i1)i1.onclick=function(){
2909
+ var ta=g('#acTa');ta.classList.add('on');
2910
+ if(i1.getAttribute('data-c')){
2911
+ var v=ta.value.trim();
2912
+ if(!v){st('先把存档码粘到下面框里');return;}
2913
+ try{var rb=JSON.parse(decodeURIComponent(escape(atob(v))));apply(rb);}
2914
+ catch(e){st('⚠ 存档码无效');}
2915
+ return;}
2916
+ i1.setAttribute('data-c','1');ta.value='';
2917
+ st('把另一台设备的存档码粘到下方,再点一次「导入」');};
2918
+ var x=g('#acX');if(x)x.onclick=function(){wrap.classList.remove('on')};
2919
+ wrap.onclick=function(e){if(e.target===wrap)wrap.classList.remove('on')};
2920
+ }
2921
+ function open(){render();wrap.classList.add('on')}
2922
+ var _orig=localStorage.setItem;
2923
+ localStorage.setItem=function(k,v){_orig.call(localStorage,k,v);if(!_app&&acct&&acct.k&&TK.indexOf(k)>=0&&k!==LT){_dirty=1;clearTimeout(pq);pq=setTimeout(push,2200);}};
2924
+ window.addEventListener('pagehide',function(){
2925
+ if(acct&&acct.k&&_dirty){try{_dirty=0;_si(LT,String(Date.now()));
2926
+ fetch(url(),{method:'POST',mode:'no-cors',keepalive:true,body:JSON.stringify({v:1,u:acct.u,t:Date.now(),data:snap()})});}catch(e){}}
2927
+ });
2928
+ document.addEventListener('visibilitychange',function(){if(!document.hidden&&acct&&acct.k){pull(false);}});
2929
+ var btn=document.createElement('div');
2930
+ var ci=document.querySelector('.corner-ics');
2931
+ if(ci){btn.className='ci';btn.textContent='@';ci.appendChild(btn);}
2932
+ else{btn.textContent='@';btn.style.cssText='position:fixed;right:14px;bottom:60px;z-index:120;width:38px;height:38px;display:flex;align-items:center;justify-content:center;border:2px solid #4cc9ff;background:rgba(7,12,24,.92);color:#4cc9ff;font-size:17px;cursor:pointer;user-select:none;box-shadow:3px 3px 0 rgba(0,0,0,.45)';document.body.appendChild(btn);}
2933
+ btn.id='acctBtn';btn.title='云存档';
2934
+ if(acct)btn.style.background='rgba(76,201,255,.28)';
2935
+ btn.addEventListener('click',open);
2936
+ if(acct&&acct.k){setTimeout(function(){pull(false);},1600);}
2937
+ window.__shaT=sha;
2938
+ })();
2939
+ </script>
2756
2940
  </body>
2757
2941
  </html>
package/ledger.html CHANGED
@@ -793,7 +793,7 @@ window.LEDGER_BACKUP = [];
793
793
  function goHome() {
794
794
  try{window.__bgmFade&&window.__bgmFade()}catch(e){}
795
795
  var p = location.pathname || '';
796
- var u = 'index.html';
796
+ var u = /\/akp3\//.test(p) ? 'index.html' : 'index.html';
797
797
  setTimeout(function () { location.href = u; }, 380);
798
798
  }
799
799
 
@@ -990,14 +990,198 @@ window.LEDGER_BACKUP = [];
990
990
  function kick(){if(ctx&&ctx.state!=='running'&&ctx.resume){try{ctx.resume()}catch(e){}}if(!want||playing())return;if(bURL)ensure();else pend=1}
991
991
  document.addEventListener('pointerdown',kick,true);
992
992
  au.addEventListener('playing',function(){document.removeEventListener('pointerdown',kick,true)});
993
- fetch('bgm.mp3').then(function(r){return r.arrayBuffer()}).then(function(a){
994
- abuf=a;bURL=URL.createObjectURL(new Blob([a],{type:'audio/mpeg'}));
995
- if(elemTried&&want){warmOnly=1;toWA()}
996
- if(want&&!playing()){pend=0;ensure()}
997
- }).catch(function(){});
993
+ var _ld=0;
994
+ function loadBgm(){if(_ld)return;_ld=1;
995
+ fetch('bgm.mp3').then(function(r){return r.arrayBuffer()}).then(function(a){
996
+ abuf=a;bURL=URL.createObjectURL(new Blob([a],{type:'audio/mpeg'}));
997
+ if(elemTried&&want){warmOnly=1;toWA()}
998
+ if(want&&!playing()){pend=0;ensure()}
999
+ }).catch(function(){});
1000
+ }
1001
+ setTimeout(loadBgm,2500);
1002
+ document.addEventListener('pointerdown',loadBgm,true);
998
1003
  if(want){setTimeout(function(){if(!playing()&&bURL){ensure()}},400)}
999
1004
  window.__bgmFade=function(){savePos();try{if(node&&gn){var g0=gn.gain.value,t0=Date.now();var iv=setInterval(function(){var k=Math.max(0,1-(Date.now()-t0)/500);gn.gain.value=g0*k;if(k<=0)clearInterval(iv)},60)}}catch(e){}};
1000
1005
  })();
1001
1006
  </script>
1007
+
1008
+ <!-- ===== SYSTEM LOGIN 云存档 ===== -->
1009
+ <script>
1010
+ /* ===== SYSTEM LOGIN · 云存档同步引擎 v1 ===== */
1011
+ (function(){
1012
+ var TK=['whale.tasks.v1','minis_ledger_v1','minis_ledger_trash_v1','whale.bgm'];
1013
+ var BASE='https://textdb.dev/api/data/prts-acct-';
1014
+ var LS='whale.acct',LT='whale.sync.t';
1015
+ var acct=null;try{acct=JSON.parse(localStorage.getItem(LS)||'null')}catch(e){}
1016
+ var _si=localStorage.setItem.bind(localStorage),_app=0,pq=0,box=null,_dirty=0;
1017
+
1018
+ function sha(msg){
1019
+ function r(v,n){return (v>>>n)|(v<<(32-n));}
1020
+ var i,j,K=[],H=[0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19],W=new Array(64),ml=msg.length*8;
1021
+ (function(){var p=2;function pr(x){for(var d=2;d*d<=x;d++){if(x%d===0)return false}return true;}
1022
+ while(K.length<64){if(pr(p)){K.push(Math.floor(Math.pow(p,1/3)*4294967296)%4294967296);}p++;}})();
1023
+ var b=[];
1024
+ for(i=0;i<msg.length;i++){var c=msg.charCodeAt(i);
1025
+ if(c<128)b.push(c);
1026
+ else if(c<2048){b.push(192|(c>>6),128|(c&63));}
1027
+ else{b.push(224|(c>>12),128|((c>>6)&63),128|(c&63));}}
1028
+ b.push(0x80);while(b.length%64!==56)b.push(0);
1029
+ for(i=7;i>=0;i--)b.push(Math.floor(ml/Math.pow(2,i*8))&255);
1030
+ for(i=0;i<b.length;i+=64){
1031
+ for(j=0;j<16;j++)W[j]=(b[i+j*4]<<24)|(b[i+j*4+1]<<16)|(b[i+j*4+2]<<8)|b[i+j*4+3];
1032
+ for(j=16;j<64;j++){var s0=r(W[j-15],7)^r(W[j-15],18)^(W[j-15]>>>3),s1=r(W[j-2],17)^r(W[j-2],19)^(W[j-2]>>>10);W[j]=(W[j-16]+s0+W[j-7]+s1)|0;}
1033
+ var a=H[0],bb=H[1],cc=H[2],d=H[3],e=H[4],f=H[5],g=H[6],h=H[7];
1034
+ for(j=0;j<64;j++){
1035
+ var S1=r(e,6)^r(e,11)^r(e,25),ch=(e&f)^(~e&g),t1=(h+S1+ch+K[j]+W[j])|0,
1036
+ S0=r(a,2)^r(a,13)^r(a,22),mj=(a&bb)^(a&cc)^(bb&cc),t2=(S0+mj)|0;
1037
+ h=g;g=f;f=e;e=(d+t1)|0;d=cc;cc=bb;bb=a;a=(t1+t2)|0;
1038
+ }
1039
+ H[0]=(H[0]+a)|0;H[1]=(H[1]+bb)|0;H[2]=(H[2]+cc)|0;H[3]=(H[3]+d)|0;H[4]=(H[4]+e)|0;H[5]=(H[5]+f)|0;H[6]=(H[6]+g)|0;H[7]=(H[7]+h)|0;
1040
+ }
1041
+ var o='';for(i=0;i<8;i++)o+=('00000000'+(H[i]>>>0).toString(16)).slice(-8);
1042
+ return o;
1043
+ }
1044
+ function snap(){var d={};for(var i=0;i<TK.length;i++){var v=localStorage.getItem(TK[i]);if(v!==null)d[TK[i]]=v;}return d;}
1045
+ function url(){return BASE+acct.k;}
1046
+ function st(m){if(box&&box.st)box.st.textContent=m;}
1047
+ function clock(){var d=new Date();function p(n){return(n<10?'0':'')+n}return p(d.getHours())+':'+p(d.getMinutes());}
1048
+ function apply(rb){
1049
+ _app=1;try{for(var k in rb.data){_si(k,rb.data[k]);}}finally{_app=0;}
1050
+ _si(LT,String(rb.t||Date.now()));
1051
+ st('✔ 已从云端同步 '+clock()+',即将刷新…');
1052
+ setTimeout(function(){location.reload();},800);
1053
+ }
1054
+ function push(){
1055
+ if(!acct||!acct.k)return;
1056
+ _dirty=0;var t=Date.now();_si(LT,String(t));
1057
+ st('↻ 同步中…');
1058
+ fetch(url(),{method:'POST',mode:'no-cors',body:JSON.stringify({v:1,u:acct.u,t:t,data:snap()})})
1059
+ .then(function(){setTimeout(function(){verify(t)},1800);})
1060
+ .catch(function(){st('⚠ 云同步暂不可用(可用存档码手动搬)');});
1061
+ }
1062
+ function verify(t){
1063
+ fetch(url()+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
1064
+ x=(x||'').replace(/=$/,'');
1065
+ try{var rb=JSON.parse(x);if(rb.t===t){st('✔ 已同步 '+clock());return;}}catch(e){}
1066
+ if(!window.__pv){window.__pv=1;setTimeout(function(){window.__pv=0;push();},1500);}
1067
+ else{st('⚠ 云端回读不一致,稍后自动重试');}
1068
+ }).catch(function(){st('⚠ 校验失败(可能网络受限)');});
1069
+ }
1070
+ function pull(manual){
1071
+ if(!acct||!acct.k)return;
1072
+ fetch(url()+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
1073
+ x=(x||'').replace(/=$/,'');
1074
+ if(!x){if(manual)st('☁ 云端暂时没有存档——点「立即同步」上传本机数据');return;}
1075
+ var rb;try{rb=JSON.parse(x)}catch(e){st('⚠ 云端数据格式异常');return;}
1076
+ var lt=Number(localStorage.getItem(LT)||0);
1077
+ if((rb.t||0)>lt){
1078
+ var same=1;for(var kk in rb.data){if(localStorage.getItem(kk)!==rb.data[kk]){same=0;break;}}
1079
+ if(same){_si(LT,String(rb.t));if(manual)st('✔ 已是最新 '+clock());}
1080
+ else{apply(rb);}
1081
+ }
1082
+ else if(manual){
1083
+ var same2=1;for(var k2 in rb.data){if(localStorage.getItem(k2)!==rb.data[k2]){same2=0;break;}}
1084
+ if(same2){st('✔ 已是最新 '+clock());}else{push();}
1085
+ }
1086
+ else{st('✔ 已是云端最新');}
1087
+ }).catch(function(){st('⚠ 云端连接失败');});
1088
+ }
1089
+ function logout(){localStorage.removeItem(LS);acct=null;}
1090
+ var CSS='.acWrap{position:fixed;inset:0;z-index:9998;background:rgba(3,6,14,.66);display:none;align-items:center;justify-content:center}.acWrap.on{display:flex}'+
1091
+ '.acBox{width:min(86vw,360px);max-height:86vh;overflow:auto;background:rgba(7,12,24,.97);border:2px solid #4cc9ff;box-shadow:6px 6px 0 rgba(18,115,200,.45);padding:16px;font-family:ui-monospace,Menlo,monospace;color:#eef7ff}'+
1092
+ '.acBox h3{margin:0 0 4px;font-size:15px;letter-spacing:.12em;color:#8fe0ff}.acBox .sub{font-size:10px;opacity:.65;margin-bottom:10px}'+
1093
+ '.acBox input{width:100%;box-sizing:border-box;background:#0a1322;border:1.5px solid #2b4a66;color:#eef7ff;font-family:inherit;font-size:13px;padding:8px;margin:5px 0}'+
1094
+ '.acBox button{background:#0a1322;border:1.5px solid #4cc9ff;color:#4cc9ff;font-family:inherit;font-size:12px;padding:7px 10px;margin:6px 6px 0 0;cursor:pointer;letter-spacing:.08em}'+
1095
+ '.acBox button.pri{background:#4cc9ff;color:#06121f;font-weight:700}'+
1096
+ '.acBox .st{font-size:11px;margin-top:10px;min-height:14px;color:#9fe9a0;line-height:1.5;word-break:break-all}'+
1097
+ '.acBox textarea{width:100%;box-sizing:border-box;height:70px;background:#0a1322;border:1.5px solid #2b4a66;color:#9fd8ff;font-size:10px;font-family:inherit;margin-top:8px;display:none}'+
1098
+ '.acBox textarea.on{display:block}';
1099
+ var sEl=document.createElement('style');sEl.textContent=CSS;document.head.appendChild(sEl);
1100
+ var wrap=document.createElement('div');wrap.className='acWrap';document.body.appendChild(wrap);
1101
+ function esc(s){return String(s).replace(/[<>&"]/g,function(c){return{'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}[c]})}
1102
+ function render(){
1103
+ var h='<div class="acBox"><h3>SYSTEM LOGIN · 云存档</h3><div class="sub">同一账号 · 多设备同步(鱼干/任务/券/小账本)</div>';
1104
+ if(acct){
1105
+ h+='<div style="font-size:12px;margin:6px 0 2px">当前账号:<b style="color:#ffd23f">'+esc(acct.u)+'</b></div>'+
1106
+ '<button class="pri" id="acSync">↻ 立即同步</button><button id="acOut">退出登录</button>';
1107
+ }else{
1108
+ h+='<input id="acU" placeholder="用户名(自己起,例如 yanliang27)" autocomplete="username">'+
1109
+ '<input id="acP" type="password" placeholder="密码(≥4位,丢了找不回!)" autocomplete="current-password">'+
1110
+ '<button class="pri" id="acGo">登录 / 创建</button>';
1111
+ }
1112
+ h+='<button id="acExp">📤 存档码</button><button id="acImp">📥 导入</button>'+
1113
+ '<div class="st" id="acSt"></div><textarea id="acTa" spellcheck="false"></textarea>'+
1114
+ '<div style="font-size:10px;opacity:.5;margin-top:9px;line-height:1.5">密钥由「用户名+密码」派生;同一账号在任意设备登录即接回数据。忘记密码=新仓库(旧数据找不回)</div>'+
1115
+ '<button id="acX" style="border-color:#2b4a66;color:#8ea6bf;margin-top:10px">关闭 / CLOSE</button></div>';
1116
+ wrap.innerHTML=h;
1117
+ box={st:wrap.querySelector('#acSt'),ta:wrap.querySelector('#acTa')};
1118
+ bind();
1119
+ }
1120
+ function bind(){
1121
+ var g=function(id){return wrap.querySelector(id)};
1122
+ var go=g('#acGo');
1123
+ if(go)go.onclick=function(){
1124
+ var b=go,u=(g('#acU').value||'').trim(),p=g('#acP').value||'';
1125
+ if(u.length<2||p.length<4){st('用户名≥2位、密码≥4位哦');return;}
1126
+ var k=sha('prts-moonlit|'+u+'|'+p);
1127
+ if(b.getAttribute('data-mode')==='create'){
1128
+ acct={u:u,k:k};_si(LS,JSON.stringify(acct));_si(LT,String(Date.now()));
1129
+ st('✦ 仓库已创建,正在上传本机数据…');render();push();return;
1130
+ }
1131
+ st('↻ 查找云端仓库…');
1132
+ fetch(BASE+k+'?ts='+Date.now()).then(function(r){return r.text()}).then(function(x){
1133
+ x=(x||'').replace(/=$/,'');
1134
+ if(x&&x.length>2){
1135
+ acct={u:u,k:k};_si(LS,JSON.stringify(acct));
1136
+ var rb=null;try{rb=JSON.parse(x)}catch(e){}
1137
+ if(rb&&(rb.t||0)>Number(localStorage.getItem(LT)||0)){apply(rb);}
1138
+ else{_si(LT,String((rb&&rb.t)||Date.now()));st('✔ 已登录,云端仓库已连接 '+clock());render();}
1139
+ }else{
1140
+ b.setAttribute('data-mode','create');b.textContent='✦ 没找到仓库——点此以本机数据创建';
1141
+ st('(如果是新账号,创建后本机数据会上传成初始存档)');
1142
+ }
1143
+ }).catch(function(){st('⚠ 云端连接失败,稍后再试');});
1144
+ };
1145
+ var sy=g('#acSync');if(sy)sy.onclick=function(){pull(true)};
1146
+ var o=g('#acOut');if(o)o.onclick=function(){
1147
+ if(o.getAttribute('data-c')){logout();st('已退出登录(本机数据保留)');render();}
1148
+ else{o.setAttribute('data-c','1');o.textContent='⚠ 再点一次 = 退出登录';}};
1149
+ var e1=g('#acExp');if(e1)e1.onclick=function(){
1150
+ var b=JSON.stringify({v:1,u:acct?acct.u:'anon',t:Date.now(),data:snap()});
1151
+ var ta=g('#acTa');ta.classList.add('on');
1152
+ ta.value=btoa(unescape(encodeURIComponent(b)));ta.select();
1153
+ st('已生成存档码——全选复制保存,换设备时用「导入」');};
1154
+ var i1=g('#acImp');if(i1)i1.onclick=function(){
1155
+ var ta=g('#acTa');ta.classList.add('on');
1156
+ if(i1.getAttribute('data-c')){
1157
+ var v=ta.value.trim();
1158
+ if(!v){st('先把存档码粘到下面框里');return;}
1159
+ try{var rb=JSON.parse(decodeURIComponent(escape(atob(v))));apply(rb);}
1160
+ catch(e){st('⚠ 存档码无效');}
1161
+ return;}
1162
+ i1.setAttribute('data-c','1');ta.value='';
1163
+ st('把另一台设备的存档码粘到下方,再点一次「导入」');};
1164
+ var x=g('#acX');if(x)x.onclick=function(){wrap.classList.remove('on')};
1165
+ wrap.onclick=function(e){if(e.target===wrap)wrap.classList.remove('on')};
1166
+ }
1167
+ function open(){render();wrap.classList.add('on')}
1168
+ var _orig=localStorage.setItem;
1169
+ localStorage.setItem=function(k,v){_orig.call(localStorage,k,v);if(!_app&&acct&&acct.k&&TK.indexOf(k)>=0&&k!==LT){_dirty=1;clearTimeout(pq);pq=setTimeout(push,2200);}};
1170
+ window.addEventListener('pagehide',function(){
1171
+ if(acct&&acct.k&&_dirty){try{_dirty=0;_si(LT,String(Date.now()));
1172
+ fetch(url(),{method:'POST',mode:'no-cors',keepalive:true,body:JSON.stringify({v:1,u:acct.u,t:Date.now(),data:snap()})});}catch(e){}}
1173
+ });
1174
+ document.addEventListener('visibilitychange',function(){if(!document.hidden&&acct&&acct.k){pull(false);}});
1175
+ var btn=document.createElement('div');
1176
+ var ci=document.querySelector('.corner-ics');
1177
+ if(ci){btn.className='ci';btn.textContent='@';ci.appendChild(btn);}
1178
+ else{btn.textContent='@';btn.style.cssText='position:fixed;right:14px;bottom:60px;z-index:120;width:38px;height:38px;display:flex;align-items:center;justify-content:center;border:2px solid #4cc9ff;background:rgba(7,12,24,.92);color:#4cc9ff;font-size:17px;cursor:pointer;user-select:none;box-shadow:3px 3px 0 rgba(0,0,0,.45)';document.body.appendChild(btn);}
1179
+ btn.id='acctBtn';btn.title='云存档';
1180
+ if(acct)btn.style.background='rgba(76,201,255,.28)';
1181
+ btn.addEventListener('click',open);
1182
+ if(acct&&acct.k){setTimeout(function(){pull(false);},1600);}
1183
+ window.__shaT=sha;
1184
+ })();
1185
+ </script>
1002
1186
  </body>
1003
1187
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prts-moonlit",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "ARKNIGHTS x P3R Moonlit PRTS terminal (personal toy site)",
5
5
  "license": "MIT"
6
- }
6
+ }