export const RESUME_KEY='variant:campaign-200-r2:v1:resume'; export function readResume(storage){try{const value=JSON.parse(storage.getItem(RESUME_KEY)||'null');return value?.version===1&&typeof value.levelId==='string'?value:null;}catch{return null;}} export function resumeTarget(levels,completed,saved,legacyId){ const done=new Set(completed),savedIndex=levels.findIndex(l=>l.id===saved?.levelId),legacy=levels.findIndex(l=>l.id===legacyId); if(savedIndex>=0&&!done.has(levels[savedIndex].id))return {index:savedIndex,path:Array.isArray(saved.path)?saved.path:[]}; const from=savedIndex>=0?savedIndex:legacy; if(from>=0&&!done.has(levels[from].id))return {index:from,path:[]}; for(let step=1;step<=levels.length;step++){const i=(Math.max(-1,from)+step)%levels.length;if(!done.has(levels[i].id))return {index:i,path:[]};} return {index:Math.max(0,from),path:[]}; } export function validResumePath(level,route,canAppend){ if(!Array.isArray(route)||route.length>level.cells.length)return []; const restored=[];for(const id of route){if(typeof id!=='string'||!canAppend(level,restored,id))return [];restored.push(id);}return restored; } export function writeResume(storage,levels,completed,current,path,cleared){ const previous=readResume(storage),done=new Set(completed); // Replaying a completed level must not replace the last unfinished level. if(done.has(current.id)&&!cleared&&previous&&!done.has(previous.levelId)&&levels.some(l=>l.id===previous.levelId))return; const next=cleared||done.has(current.id)?resumeTarget(levels,completed,null,current.id):{index:levels.indexOf(current),path:[...path]}; const value=JSON.stringify({version:1,levelId:levels[next.index].id,path:next.path}); try{if(storage.getItem(RESUME_KEY)!==value)storage.setItem(RESUME_KEY,value);}catch{} }