のタグは不要(中身だけ貼る) ============================================================ */ var QUESTIONS = [ {id:'0-1', section:'基本情報', type:'select', text:'平日の起床時間(だいたいでOK)', options:['4:00以前','4:30','5:00','5:30','6:00','6:30','7:00','7:30','8:00以降']}, {id:'0-2', section:'基本情報', type:'select', text:'平日の就寝(消灯)時間', options:['21:00以前','21:30','22:00','22:30','23:00','23:30','0:00','0:30以降']}, {id:'0-3', section:'基本情報', type:'multi', text:'帰宅時間(よくある時間帯を全部タップ・複数選択)', options:['17:00以前','17:30','18:00','18:30','19:00','19:30','20:00','20:30','21:00','21:30以降'], hint:'例:火・木は18時、水・金は19時など、曜日でズレる方は該当するものを全部タップしてください'}, {id:'0-4', section:'基本情報', type:'text', text:'子どもの人数・年齢、保育園・仕事の状況(自由記述)', required:true}, {id:'0-5', section:'基本情報', type:'radio', text:'シフト勤務などで、起床時間が毎日変わりますか?', options:[{label:'はい', flag:'shiftYes'},{label:'いいえ'}]}, {id:'A1', section:'A. やる理由', text:'自分時間で「やりたいこと」はありますか?', options:[{label:'はっきりある', score:2},{label:'ぼんやりある', score:1},{label:'思いつかない', score:0}]}, {id:'A2', section:'A. やる理由', text:'その時間を「何に使いたいか」を言葉にできますか?', options:[{label:'できる', score:2},{label:'なんとなく', score:1},{label:'できない', score:0}]}, {id:'A3', section:'A. やる理由', text:'時間・お金・家族などの制約をいったん外して、やりたいことを書き出したことはありますか?', options:[{label:'ある', score:1},{label:'ない', score:0}]}, {id:'A4', section:'A. やる理由', text:'「自分時間を取るのは我がままでは?」と感じることがありますか?', options:[{label:'よく感じる', score:0},{label:'少し感じる', score:1},{label:'感じない', score:2}]}, {id:'B1', section:'B. 置き場所', text:'朝のほうが調子が出ますか、夜のほうが調子が出ますか?', options:[{label:'朝型', score:2},{label:'どちらでもない', score:1},{label:'夜型', score:0}]}, {id:'B2', section:'B. 置き場所', text:'休日の起床時間は、平日と比べてどのくらいズレますか?', options:[{label:'1時間以内', score:2},{label:'1〜2時間', score:1},{label:'2時間以上', score:0}]}, {id:'C1', section:'C. 夜の構造', text:'帰宅時間は、毎日だいたい同じくらいですか?', options:[{label:'ほぼ一定', score:2},{label:'曜日で異なるが予測できる', score:1},{label:'バラバラ', score:0}]}, {id:'C2', section:'C. 夜の構造', text:'帰宅から消灯までにやるタスクは、いくつくらいありますか?(ざっくりでOK)', options:[{label:'5個以下', score:2},{label:'6〜9個', score:1},{label:'10個以上', score:0}]}, {id:'C3', section:'C. 夜の構造', text:'夜のタスクを「書き出して見える化」したことはありますか?', options:[{label:'ある', score:2},{label:'頭の中で把握している', score:1},{label:'していない', score:0}]}, {id:'C4', section:'C. 夜の構造', text:'夜のタスクのうち、翌朝や日中・週末に「移せそう」なものはありますか?(洗濯を朝干す等)', options:[{label:'いくつもある', score:2},{label:'少しある', score:1},{label:'思いつかない', score:0}]}, {id:'C5', section:'C. 夜の構造', text:'家事や育児を、家族やサービス(宅配・外食・家電など)に任せられる余地はありますか?', options:[{label:'ある', score:2},{label:'少しある', score:1},{label:'ない', score:0}]}, {id:'C6', section:'C. 夜の構造', text:'夜に「スマホ・動画・晩酌」で、気づいたら時間が経っていることはありますか?', options:[{label:'よくある', score:0},{label:'ときどき', score:1},{label:'ほとんどない', score:2}]}, {id:'C7', section:'C. 夜の構造', text:'それらを「完全にやめる」のではなく「別の時間に移動する」イメージを持てますか?', options:[{label:'持てる', score:2},{label:'難しい', score:0}]}, {id:'C8', section:'C. 夜の構造', text:'夜のタスクの中で「一番やりたくない・気が重い」ものは分かっていますか?', options:[{label:'分かっている', score:1},{label:'分からない', score:0}]}, {id:'D1', section:'D. 7時間逆算', text:'今より15〜30分早い時間に起きることは、現実的にできそうですか?', options:[{label:'できそう', score:2},{label:'難しい', score:0}]}, {id:'D2', section:'D. 7時間逆算', text:'起きたい時間から「7時間逆算」した消灯時間(例:6時起き→23時消灯)に、眠れる見込みはありますか?', options:[{label:'ありそう', score:2},{label:'ぎりぎり', score:1},{label:'なさそう', score:0}]}, {id:'D3', section:'D. 7時間逆算', text:'夜中に起こされることはどのくらいありますか?(夜泣き・看病など)', options:[{label:'ほとんどない', score:2},{label:'週に数回', score:1},{label:'ほぼ毎晩', score:0}]}, {id:'D4', section:'D. 7時間逆算', text:'寝かしつけには、時間にしてどのくらいかかりますか?', options:[{label:'30分以内', score:2},{label:'30分〜1時間', score:1},{label:'1時間以上', score:0}]}, {id:'D5', section:'D. 7時間逆算', text:'寝かしつけ後は「そのまま一緒に寝る」タイプですか、「起き直して作業する」タイプですか?', options:[{label:'一緒に寝られる', score:2},{label:'起き直すが朝がつらい', score:1},{label:'起き直して夜に作業している', score:0}]}, {id:'E1', section:'E. 眠気の貯金', text:'昼寝や仮眠は取りますか? その長さは?', options:[{label:'取らない/15分以内', score:2},{label:'30分くらい', score:1},{label:'1時間以上', score:0}]}, {id:'E2', section:'E. 眠気の貯金', text:'日中、体を動かす時間(外出・歩く・階段・家事で動く)はありますか?', options:[{label:'十分ある', score:2},{label:'少しある', score:1},{label:'ほぼない', score:0}]}, {id:'E3', section:'E. 眠気の貯金', text:'カフェイン(コーヒー・緑茶・エナジードリンク)を、夕方以降に取ることがありますか?', options:[{label:'ほとんどない', score:2},{label:'ときどき', score:1},{label:'よく取る', score:0}]}, {id:'F1', section:'F. 朝の立ち上げ', text:'朝、起きたあとに布団に戻ったり、スマホを見て止まってしまうことはありますか?', options:[{label:'よくある', score:0},{label:'ときどき', score:1},{label:'ない', score:2}]}, {id:'F2', section:'F. 朝の立ち上げ', text:'朝に「光を浴びる→白湯を飲む→顔を洗う→軽く動く」のような決まった流れはありますか?', options:[{label:'ある', score:2},{label:'部分的にある', score:1},{label:'ない', score:0}]}, {id:'F3', section:'F. 朝の立ち上げ', text:'起きられなかった朝、どんな気持ちになりますか?', options:[{label:'原因を考える方', score:2},{label:'なんとなく落ち込む', score:1},{label:'自分を責める', score:0}]}, {id:'G1', section:'G. 戻れる仕組み', text:'朝活や習慣が崩れたとき、「また自分は意志が弱い」と思うことが多いですか?', options:[{label:'よく思う', score:0},{label:'思うことがある', score:1},{label:'思わない', score:2}]}, {id:'G2', section:'G. 戻れる仕組み', text:'「続く」とは「毎日途切れないこと」だと思いますか? それとも「崩れても戻れること」だと思いますか?', options:[{label:'戻れること', score:2},{label:'分からない', score:1},{label:'途切れないこと', score:0}]}, {id:'G3', section:'G. 戻れる仕組み', text:'崩れた日の原因を「性格・意志」ではなく「設計(どこがずれたか・何を変えれば戻りやすいか)」として見られると思いますか?', options:[{label:'見られる', score:2},{label:'難しいかも', score:1},{label:'分からない', score:0}]}, {id:'G4', section:'G. 戻れる仕組み', text:'生活のイレギュラー(夜泣き・発熱・看病など)はどのくらいありますか?', options:[{label:'ほとんどない', score:2},{label:'ときどき', score:1},{label:'よくある', score:0}]} /* 削除:H1, I1, I2 */ ]; var SCORING_IDS = ['A1','A2','A3','A4','B1','B2','C1','C2','C3','C4','C5','C6','C7','C8','D1','D2','D3','D4','D5','E1','E2','E3','F1','F2','F3','G1','G2','G3','G4']; var MAX_SCORE = SCORING_IDS.reduce(function(sum,id){ var q = QUESTIONS.find(function(x){return x.id===id;}); var mx = 0; q.options.forEach(function(o){ if(o.score>mx) mx=o.score; }); return sum + mx; },0); function computeResult(answers, meta){ var total = 0; SCORING_IDS.forEach(function(id){ total += (answers[id]||0); }); var pct = Math.round(total/MAX_SCORE*100); var flags = []; var shiftYes = !!(meta && meta.shiftYes); var d2Zero = answers['D2'] === 0; var noPurpose = answers['A1'] === 0 && answers['A2'] === 0; var c4Zero = answers['C4'] === 0; var grade, reason; if (shiftYes){ grade='C'; reason='起床時間が毎日変わる環境では、まず時期の見極めが必要です。単発添削で夜の整理から始めるのがおすすめです。'; flags.push('シフト勤務・不定起床'); } else if (d2Zero){ grade='C'; reason='「7時間逆算」の枠が今の生活では取りにくいようです。先に夜の構造を整えるところから始めましょう。'; flags.push('7時間逆算の枠が取れない'); } else if (pct >= 80){ grade='A'; if (noPurpose){ grade='B'; reason='土台は整っています。まず「なぜ自分時間がほしいか」の目的づくり(PHASE 0)から始めるのがおすすめです。'; flags.push('目的の言葉化がまだ'); } else if (c4Zero){ grade='B'; reason='土台はありますが、夜から外せるタスクを見つける「夜の整理」が最優先です。'; flags.push('夜のタスク外しがまだ'); } else { reason='土台◎ あなたは逆算の枠が取れる状態です。この3ヶ月で、夜の余白と朝の自分時間を設計するのにぴったりの段階。無料面談では、あなたの数値から夜スケジュールの一部を実際に作ってみます。'; } } else if (pct >= 50){ grade='B'; reason='あなたは「夜の整理」から始める段階です。3ヶ月プログラムの1ヶ月目がまさにあなたのスタート地点。まずは夜タスクの見える化から、一緒に進めましょう。'; } else { grade='C'; reason='今は「時期が違うだけ」。子育て期はリズムが何度でも崩れます。まずは単発の夜スケジュール添削やマガジンで、土台づくりから始めるのがおすすめです。無理に進める必要はありません。'; } return {total:total, max:MAX_SCORE, pct:pct, grade:grade, reason:reason, flags:flags}; } var NEXT_STEP = { A:{title:'A判定|土台◎。3ヶ月本プログラムへ', body:'あなたの生活は、逆算の枠が取れて夜の余白も確保できる状態です。面談では、あなたの「起きたい時間・帰宅時間・固定予定」をもとに、ChatGPTで夜スケジュールの第一ドラフトを一緒に作ります。', points:['目的(PHASE 0)の言語化 → 自分時間リストへの落とし込み','ストレス度×所要時間で夜タスクを再配置','朝15分の「日中ロス見直し」で帰宅時間を前倒しにする']}, B:{title:'B判定|部分的な整備不足。夜の整理が先', body:'3ヶ月プログラムのうち「1ヶ月目(土台設計)」がまさにあなたのスタート地点です。面談では、現状の夜のタスクを書き出し、「夜でなくてもいいもの」を一緒に仕分けします。', points:['夜タスク全部出し → 削る/翌朝に移す/任せるの3分類','固定予定(習い事など)を入れた「30分ブロック夜スケジュール」の作成','「うまくいかない日」の自責を「設計の言葉」へ言い換えるワーク']}, C:{title:'C判定|時期尚早。今は別の入り口から', body:'今は3ヶ月を始めるタイミングではないかもしれません。無理に進めず、まずは夜の整理を1回やってみるのがおすすめです。面談では「今はここを整えれば、次の一歩が見えます」をお伝えします。', points:['不規則勤務/7時間逆算が取れない/目的が未言語化 のいずれかを確認','単発「夜スケジュール添削」またはマガジン購読への案内','3〜6ヶ月後、生活が落ち着いたタイミングで再検討']} }; var SHEET_COLUMNS = [ '日時','氏名','判定','スコア(%)','内訳','シフト勤務', '起床時間','就寝時間','帰宅時間','子どもの状況','起床の変動', 'A1_やりたいこと','A2_言葉にできる','A3_書き出し経験','A4_我がまま感', 'B1_朝or夜','B2_休日ズレ', 'C1_帰宅の安定','C2_タスク数','C3_見える化','C4_移せるもの','C5_任せられる','C6_スマホ時間泥棒','C7_楽しみ移動','C8_重い家事の自覚', 'D1_15-30分早起き','D2_7h逆算','D3_夜間割り込み','D4_寝かしつけ時間','D5_寝かしつけ後', 'E1_昼寝','E2_日中活動量','E3_カフェイン時刻', 'F1_布団スマホ','F2_朝の流れ','F3_気持ち', 'G1_自責傾向','G2_続く定義','G3_設計視点','G4_イレギュラー' ]; var idx = 0, answers = {}, labels = {}, meta = {shiftYes:false}; var qArea = null, navArea = null, btnBack = null, btnNext = null; function cur(){ return QUESTIONS[idx]; } function labelOf(id){ var v = labels[id]; if (v == null) return ''; if (Array.isArray(v)) return v.join('/'); return v; } function sanitize(s){ return String(s).replace(/\t/g,' ').replace(/\r?\n/g,' '); } function render(){ var q = cur(); var html = '
' + q.section + '
'; html += '
' + q.text + '
'; var saved = labels[q.id]; var savedArr = Array.isArray(saved) ? saved : (saved ? [saved] : []); if (q.type === 'select'){ html += ''; } else if (q.type === 'text'){ html += ''; } else if (q.type === 'multi'){ html += '
'; q.options.forEach(function(o){ var sel = savedArr.indexOf(o) >= 0 ? ' sel' : ''; html += ''; }); html += '
'; if (q.hint){ html += '
' + q.hint + '
'; } } else { html += '
'; q.options.forEach(function(o, i){ var sel = (labels[q.id]===o.label) ? ' sel' : ''; html += ''; }); html += '
'; } qArea.innerHTML = html; if (q.type === 'select'){ var sl = document.getElementById('inp'); if (labels[q.id]) sl.value = labels[q.id]; sl.addEventListener('change', function(){ sl.classList.add('sel'); labels[q.id]=sl.value; enableNext(true); }); enableNext(!!labels[q.id]); } else if (q.type === 'text'){ var ta = document.getElementById('inp'); ta.addEventListener('input', function(){ labels[q.id]=ta.value; if (q.required && !ta.value.trim()){ enableNext(false); return; } ta.classList.add('sel'); enableNext(true); }); var hasText = !!ta.value.trim(); enableNext(!q.required || hasText); if (hasText) ta.classList.add('sel'); } else if (q.type === 'multi'){ var btns = qArea.querySelectorAll('.multi'); function refreshMultiEnable(){ var cnt = qArea.querySelectorAll('.multi.sel').length; enableNext(cnt > 0); } btns.forEach(function(b){ b.addEventListener('click', function(){ b.classList.toggle('sel'); var sel = qArea.querySelectorAll('.multi.sel'); var arr = []; sel.forEach(function(x){ arr.push(x.getAttribute('data-v')); }); labels[q.id] = q.options.filter(function(o){ return arr.indexOf(o) >= 0; }); refreshMultiEnable(); }); }); refreshMultiEnable(); } else { var btns = qArea.querySelectorAll('.opt'); btns.forEach(function(b){ b.addEventListener('click', function(){ btns.forEach(function(x){ x.classList.remove('sel'); }); b.classList.add('sel'); var i = Number(b.getAttribute('data-i')); var o = q.options[i]; if (typeof o.score === 'number'){ answers[q.id] = o.score; } labels[q.id] = o.label; if (o.flag==='shiftYes' && o.label==='はい'){ meta.shiftYes = true; } if (q.id==='0-5' && o.label==='いいえ'){ meta.shiftYes = false; } enableNext(true); }); }); } navArea.classList.remove('hidden'); btnBack.disabled = (idx===0); btnBack.style.opacity = (idx===0) ? .3 : 1; btnNext.textContent = (idx === QUESTIONS.length-1) ? '結果を見る' : '次へ →'; var answered = 0; QUESTIONS.forEach(function(quest){ var t = quest.type || 'radio'; if (t==='multi'){ if (Array.isArray(labels[quest.id]) && labels[quest.id].length>0) answered++; } else if (t==='radio' || t==='select'){ if (labels[quest.id]!=null && labels[quest.id]!=='') answered++; } else if (t==='text'){ if (labels[quest.id]) answered++; } }); document.getElementById('barFill').style.width = (answered/QUESTIONS.length*100)+'%'; document.getElementById('barCount').textContent = answered + ' / ' + QUESTIONS.length; document.getElementById('barSection').textContent = q.section; window.scrollTo(0,0); } function enableNext(on){ btnNext.disabled = !on; } function buildTsv(r){ var name = sanitize(document.getElementById('userName').value || ''); var base = [new Date().toISOString(), name, r.grade, r.pct, r.total + '/' + r.max, meta.shiftYes ? 'はい' : 'いいえ']; var COL2QID = {'起床時間':'0-1','就寝時間':'0-2','帰宅時間':'0-3','子どもの状況':'0-4','起床の変動':'0-5'}; var rest = SHEET_COLUMNS.slice(6).map(function(col){ var id = COL2QID[col] || col.split('_')[0]; return sanitize(labelOf(id)); }); return base.concat(rest).join('\t'); } function buildLineText(r){ var name = (document.getElementById('userName').value || '(名無)').trim(); var lines = []; lines.push('【面談前ヒアリング】' + name + ' 様'); lines.push('判定:' + r.grade + '(' + r.pct + '%) 内訳:' + r.total + '/' + r.max); if (r.flags.length) lines.push('要注意:' + r.flags.join('/')); lines.push('———'); lines.push('起床 ' + labelOf('0-1') + ' / 消灯 ' + labelOf('0-2') + ' / 帰宅 ' + labelOf('0-3')); lines.push('シフト変動:' + labelOf('0-5')); lines.push('子ども:' + (labelOf('0-4') || '(未記入)')); lines.push('———'); lines.push('A やりたいこと: ' + labelOf('A1') + ' (' + labelOf('A2') + ')'); lines.push('C 夜の外せるもの: ' + labelOf('C4') + '/任せ: ' + labelOf('C5') + '/時間泥棒: ' + labelOf('C6')); lines.push('D 7h逆算: ' + labelOf('D2') + '/夜間割り込み: ' + labelOf('D3') + '/寝かしつけ後: ' + labelOf('D5')); lines.push('E 日中活動: ' + labelOf('E2') + '/カフェイン: ' + labelOf('E3')); lines.push('G 自責: ' + labelOf('G1') + '/続く定義: ' + labelOf('G2') + '/設計視点: ' + labelOf('G3')); lines.push('———'); lines.push('面談で話したいこと(任意):'); return lines.join('\n'); } function buildQaText(){ var lines = []; QUESTIONS.forEach(function(q, i){ var ans = (labels[q.id] != null) ? labelOf(q.id) : '未回答'; lines.push('Q' + (i+1) + '. ' + q.text + ' → ' + ans); }); return lines.join('\n'); } function buildAiPrompt(r){ var lines = []; lines.push('【依頼】あなたは、幼児子育て期(0〜6歳)のパパ・ママ向け「自分時間づくり」を専門とするコンサルタントの補佐AIです。'); lines.push('以下の「診断結果」と「追加情報」だけをもとに、この方にパーソナライズされた「3ヶ月ロードマップ(概要)」を作成してください。'); lines.push(''); lines.push('【診断判定】' + r.grade + '判定(' + r.pct + '%、内訳 ' + r.total + '/' + r.max + ')' + (r.flags.length ? ' / 要注意:' + r.flags.join('・') : '')); lines.push(''); lines.push('【34問の回答全文】'); lines.push(buildQaText()); lines.push(''); lines.push('【追加情報(顧客ライフサイクル等)】※空欄は「特になし」として扱ってください。'); lines.push('・ライフサイクルステージ(例:無料面談予約済み/メルマガ登録/教材購入済み/再相談 など):'); lines.push('・これまでの接触・購入履歴(任意):'); lines.push('・本人の現在の困りごと・補足(任意):'); lines.push(''); lines.push('【作成してほしいもの】'); lines.push('1. 3ヶ月の全体像:各月のテーマとゴール(各1行)'); lines.push('2. 月ごとのマイルストーン:「この時点でこれができていればOK」という判定基準'); lines.push('3. 想定されるつまずきポイントと対処法:回答のどの項目(Q番号)に基づくかを必ず明記'); lines.push('4. 各ステップの所要時間と頻度:1日◯分・週◯回など、子育て中でも現実的な数字'); lines.push('5. 【重要】一人で進める場合に「個別調整・判断が必要で難しい箇所」を箇条書きで明記'); lines.push('6. 最後に「この計画のうち、本人の生活リズムや固定予定に合わせた詰めが必要な箇所」をまとめる'); lines.push(''); lines.push('【禁止事項】'); lines.push('・医療的な診断・治療の示唆をしない'); lines.push('・成果・収益・睡眠改善などの保証表現をしない'); lines.push('・完璧な継続を強要しない(崩れても戻れる設計を重視)'); lines.push('・新造語を作らず、「夜の整理」「7時間逆算」「眠気の貯金」「朝の3ピース」「SUNSUNワーク」など既存教材の用語を使う'); lines.push('・出力は概要レベルに留め、詳細なワークシートまで作らない'); return lines.join('\n'); } function copyToClipboard(text, btn){ var done = function(){ btn.textContent = '✓ コピー済み'; btn.classList.add('copied'); setTimeout(function(){ btn.textContent='コピー'; btn.classList.remove('copied'); }, 2000); }; var fail = function(){ btn.textContent = 'コピー失敗'; btn.classList.add('err'); try{ var ta = document.createElement('textarea'); ta.value = text; ta.style.position='fixed'; ta.style.opacity='0'; document.body.appendChild(ta); ta.select(); var ok = document.execCommand('copy'); document.body.removeChild(ta); if (ok){ done(); btn.classList.remove('err'); } }catch(e){} }; if (navigator.clipboard && window.isSecureContext){ navigator.clipboard.writeText(text).then(done, fail); } else { fail(); } } function showResult(){ var r = computeResult(answers, meta); qArea.style.display = 'none'; navArea.classList.add('hidden'); var res = document.getElementById('resultArea'); res.style.display = 'block'; document.getElementById('userName').focus(); function refreshOutputs(){ document.getElementById('gradeBadge').textContent = r.grade; document.getElementById('gradeBadge').className = 'grade-badge grade-' + r.grade; document.getElementById('scoreNum').textContent = r.pct; document.getElementById('resMsg').textContent = r.reason; var fl = document.getElementById('flagList'); fl.innerHTML = ''; r.flags.forEach(function(f){ var d = document.createElement('div'); d.className = 'flag-item'; d.textContent = '▶ ' + f; fl.appendChild(d); }); document.getElementById('tsvBox').value = buildTsv(r); document.getElementById('lineBox').value = buildLineText(r); document.getElementById('copyAllBox').value = buildLineText(r) + '\n────────────\n【34問の回答全文】\n' + buildQaText() + '\n────────────\n【スプレッドシート用(この1行を新行に貼る)】\n' + buildTsv(r) + '\n────────────\n【専用AI用プロンプト(3ヶ月ロードマップ生成)】\n' + buildAiPrompt(r); var ns = NEXT_STEP[r.grade]; document.getElementById('nsTitle').textContent = ns.title; document.getElementById('nsBody').textContent = ns.body; var ul = document.getElementById('nsList'); ul.innerHTML = ''; ns.points.forEach(function(pt){ var li = document.createElement('li'); li.textContent = pt; ul.appendChild(li); }); } refreshOutputs(); document.getElementById('userName').addEventListener('input', refreshOutputs); document.getElementById('btnCopyAll').addEventListener('click', function(){ copyToClipboard(document.getElementById('copyAllBox').value, this); }); window.scrollTo(0,0); } var STORAGE_KEY = 'lifestyleAnatomV3'; function saveState(){ try{ var nm = ''; var ni = document.getElementById('userName'); if (ni && ni.value) nm = ni.value; localStorage.setItem(STORAGE_KEY, JSON.stringify({v:3,idx:idx,answers:answers,labels:labels,meta:meta,name:nm})); }catch(e){} } function loadState(){ try{ var raw = localStorage.getItem(STORAGE_KEY); if (!raw) return false; var d = JSON.parse(raw); if (!d || !d.labels || !d.answers) return false; if (typeof d.idx === 'number' && d.idx >= 0 && d.idx < QUESTIONS.length){ idx = d.idx; } answers = d.answers; labels = d.labels; meta = d.meta || {shiftYes:false}; var ni = document.getElementById('userName'); if (ni && d.name) ni.value = d.name; return true; }catch(e){ return false; } } function boot(){ if (window.__lifeBooted) return; window.__lifeBooted = true; qArea = document.getElementById('qArea'); navArea = document.getElementById('navArea'); btnBack = document.getElementById('btnBack'); btnNext = document.getElementById('btnNext'); if (!qArea || !navArea || !btnBack || !btnNext) return; loadState(); try{ render(); }catch(e){ console.error(e); } btnNext.addEventListener('click', function(){ if (btnNext.disabled) return; if (idx < QUESTIONS.length-1){ idx++; render(); } else { showResult(); } }); btnBack.addEventListener('click', function(){ if (idx>0){ idx--; render(); } }); document.addEventListener('click', function(e){ var t = e.target; if (!t) return; if (t.id === 'btnNext' || t.id === 'btnBack'){ setTimeout(saveState, 0); return; } if (t.classList && (t.classList.contains('opt') || t.classList.contains('multi'))){ setTimeout(saveState, 0); } }); document.addEventListener('change', function(){ setTimeout(saveState, 0); }); document.addEventListener('input', function(){ setTimeout(saveState, 0); }); } if (document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', boot); } else { boot(); }