(function(){'use strict';var PREVIEW_STEPS=2;var RESUME_KEY='rsc-lesson-v1:'+location.pathname;function ready(fn){if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',fn);else fn();} ready(function(){var content=document.getElementById('content')||document.body;var steps=Array.prototype.slice.call(content.querySelectorAll('.lesson-step'));if(!steps.length)return;var body=document.body;var ds=body.dataset||{};var access=(body.getAttribute('data-lesson-access')||'free').toLowerCase();var courseTitle=ds.courseTitle||'Course';var lessonTitle=(function(){var h=steps[0]&&steps[0].querySelector('h2');if(!h)return courseTitle;var c=h.cloneNode(true);Array.prototype.forEach.call(c.querySelectorAll('a'),function(a){if((a.textContent||'').trim()==='#')a.parentNode.removeChild(a);});var t=(c.textContent||'').trim().replace(/^#\s*/,'').replace(/\s*#$/,'').trim();return t||courseTitle;})();var lessonKind=(ds.lessonKind||'').toLowerCase();var showCounter=!!(ds.courseLesson&&ds.courseTotal)&&lessonKind!=='quiz';var landing=ds.courseLanding||'/';var nextHref=ds.courseNext||'';var total=steps.length;var courseId=ds.courseId||'';var curSlug=location.pathname.replace(/^\//,'').replace(/index\.html?$/i,'').replace(/\.html?$/i,'').replace(/\/$/,'');var COURSE_KEY='rsc-course-v1:'+courseId;var railCourse=null;var allCourses=[];var trackIndex=null;var railLevel='lessons';var curSection=null;var viewSection=null;var railWired=false;var state={furthest:0,passed:{}};try{var saved=JSON.parse(localStorage.getItem(RESUME_KEY));if(saved&&typeof saved==='object'){state.furthest=saved.furthest||0;state.passed=saved.passed||{};}}catch(e){} function save(){try{localStorage.setItem(RESUME_KEY,JSON.stringify(state));}catch(e){}} var app=document.createElement('div');app.className='lm-app';app.innerHTML='
'+''+''+''+ esc(courseTitle)+''+''+esc(lessonTitle)+ (showCounter?' · Lesson '+esc(ds.courseLesson)+' of '+esc(ds.courseTotal)+'':'')+''+'
'+'Step 1 / '+total+''+''+'Get certified'+'
'+'
'+'
'+''+'
'+'
'+steps.map(function(){return'';}).join('')+'
'+'
'+'
'+''+''+''+'
'+'
'+'
';var stage=app.querySelector('.lm-stage');steps.forEach(function(s){stage.appendChild(s);});body.appendChild(app);body.classList.add('lesson-js-ready');document.documentElement.style.overflow='hidden';var segEls=Array.prototype.slice.call(app.querySelectorAll('.lm-segs i'));var curEl=app.querySelector('.lm-cur');var midEl=app.querySelector('.lm-mid');var backBtn=app.querySelector('.lm-back');var contBtn=app.querySelector('.lm-cont');var stripped=body.getAttribute('data-stripped')==='1';var locked=((access==='pro')&&!body.classList.contains('pro'))||stripped;if(!stripped){try{sessionStorage.removeItem('rsc-lm-reload:'+location.pathname);}catch(e){}} var gateHold=locked&&!stripped&&hasAuthToken();if(gateHold)setTimeout(function(){if(gateHold){gateHold=false;if(locked)render();}},700);var FREE_PREVIEW_LESSONS=2;var lessonOrder=parseInt(ds.courseLesson||'0',10)||0;function hasAuthToken(){try{if(API&&API.token&&API.token())return true;}catch(e){} try{for(var n=0;n0)return true;}}catch(e){} return body.classList.contains('state-pro');} var signedIn=hasAuthToken();var accountGated=(access!=='pro')&&lessonOrder>FREE_PREVIEW_LESSONS;var accountLocked=accountGated&&!signedIn;var passState=null;document.addEventListener('auth-hydrated',function(e){var me=e.detail&&e.detail.me;passState=(me&&me.pass)||null;if(passState&&passState.active&&locked&&!stripped){locked=false;render();} if(passState&&!passState.active)updateGatePassCopy();renderPassChip();if(me&&me.pro&&locked){if(stripped){try{var rk='rsc-lm-reload:'+location.pathname;if(!sessionStorage.getItem(rk)){sessionStorage.setItem(rk,'1');location.reload();return;}}catch(err){}}else{locked=false;render();}} if(me&&me.user&&accountLocked){accountLocked=false;signedIn=true;render();} if(gateHold){gateHold=false;if(locked)render();} hydrateSolved();});var API=window.RSCExerciseAPI;var hub=API?API.hubSlugFromPath():'';function exerciseId(step){var ex=step.querySelector('.exercise');return ex?ex.getAttribute('data-exercise-id'):'';} function markPassed(idx,solved){if(state.passed[idx])return;state.passed[idx]=true;save();if(solved===false)return;var id=exerciseId(steps[idx]);if(API&&id)API.reportSolve(hub,id,0).then(handleAttemptExtras);} function hydrateSolved(){if(!API)return;API.fetchSolved(hub).then(function(ids){if(!ids||!ids.length)return;steps.forEach(function(step,idx){var id=exerciseId(step);if(id&&ids.indexOf(id)!==-1&&!state.passed[idx]){state.passed[idx]=true;step.classList.add('passed');}});save();render();});} app.querySelectorAll('.lesson-quiz').forEach(function(quiz){var step=quiz.closest('.lesson-step');var idx=steps.indexOf(step);var correct=parseInt(quiz.getAttribute('data-correct'),10);var opts=Array.prototype.slice.call(quiz.querySelectorAll('.lesson-opt'));if(state.passed[idx])step.classList.add('passed');opts.forEach(function(opt){opt.addEventListener('click',function(){if(quiz.classList.contains('answered'))return;quiz.classList.add('answered');var chosen=parseInt(opt.getAttribute('data-i'),10);var right=chosen===correct;opts.forEach(function(o,j){o.classList.add('dim');if((j+1)===correct)o.classList.remove('dim');});opt.classList.remove('dim');opt.classList.add(right?'correct':'wrong');if(!right)opts[correct-1].classList.add('correct');var fb=quiz.querySelector('.lesson-qfb-'+(right?'ok':'no'));if(fb)fb.classList.add('show');step.classList.add('passed');markPassed(idx,right);render();});});});app.querySelectorAll('.lesson-tryit').forEach(function(tryit){var step=tryit.closest('.lesson-step');var idx=steps.indexOf(step);if(state.passed[idx])step.classList.add('passed');var input=tryit.querySelector('.lesson-tryit-input');var checkBtn=tryit.querySelector('.lesson-tryit-check');var ok=tryit.querySelector('.lesson-tryit-ok');var no=tryit.querySelector('.lesson-tryit-no');var re=null;try{re=new RegExp(tryit.getAttribute('data-check-regex'));}catch(e){} if(checkBtn)checkBtn.addEventListener('click',function(){var pass=re?re.test(input.value):true;if(ok)ok.classList.toggle('show',pass);if(no)no.classList.toggle('show',!pass);if(pass){step.classList.add('passed');markPassed(idx,true);render();}});});var completedLesson=(state.furthest||0)>=total-1;var i=completedLesson?0:Math.min(state.furthest||0,total-1);if(locked)i=Math.min(i,PREVIEW_STEPS-1);var showingPaywall=false;function gated(idx){return steps[idx].hasAttribute('data-gate')&&!steps[idx].classList.contains('passed');} var cachedHandle=null;function myHandle(){if(cachedHandle)return Promise.resolve(cachedHandle);try{var tk=API&&API.token&&API.token();if(!tk)return Promise.resolve(null);return fetch('/api/me/profile',{headers:{'Authorization':'Bearer '+tk}}).then(function(r){return r.ok?r.json():null;}).then(function(p){cachedHandle=p&&p.handle;return cachedHandle;}).catch(function(){return null;});}catch(e){return Promise.resolve(null);}} function showNudgeToast(text){try{var el=document.createElement('div');el.className='lm-nudge-toast';el.textContent=text;body.appendChild(el);setTimeout(function(){el.classList.add('on');},30);setTimeout(function(){el.classList.remove('on');setTimeout(function(){el.remove();},400);},5200);}catch(e){}} function showAwardModal(badge){myHandle().then(function(h){try{var wrap=document.createElement('div');wrap.className='lm-award';var profileUrl=h?location.origin+'/u/'+h:location.origin;var cardUrl=h?'/u/'+h+'/badge-card.svg?id='+encodeURIComponent(badge.id):'';wrap.innerHTML='
'+'

Badge earned

'+'

'+esc(badge.name)+'

'+ (cardUrl?''+esc(badge.name)+' share card':'')+'
'+ (h?'Share on LinkedIn':'')+ (h?'Share on X':'')+''+'
'+'
';wrap.addEventListener('click',function(ev){if(ev.target===wrap||(ev.target.classList&&ev.target.classList.contains('keep')))wrap.remove();});body.appendChild(wrap);}catch(e){}});} function handleAttemptExtras(res){if(!res)return;try{if(res.new_badges&&res.new_badges.length){showAwardModal(res.new_badges[0]);}else if(res.nudge){showNudgeToast(res.nudge);} if(res.freeze_used_today){showNudgeToast('A streak freeze saved your streak. Keep it rolling today.');}}catch(e){}} function rsSignal(sig,meta){try{var k='rs-sig:'+sig+':'+location.pathname;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');var a=localStorage.getItem('rsc-aid');if(!a){a=Math.random().toString(36).slice(2,12);localStorage.setItem('rsc-aid',a);} var hdrs={'Content-Type':'application/json'};try{var tk=window.RSCExerciseAPI&&window.RSCExerciseAPI.token&&window.RSCExerciseAPI.token();if(tk)hdrs['Authorization']='Bearer '+tk;}catch(e){} fetch('/api/signal',{method:'POST',keepalive:true,headers:hdrs,body:JSON.stringify({s:sig,p:location.pathname,m:meta||'',a:a})}).catch(function(){});}catch(e){}} function renderPaywall(){showingPaywall=true;rsSignal('paywall_hit',courseId?courseId+':'+lessonOrder:'');steps.forEach(function(s){s.classList.remove('on');});var pw=stage.querySelector('.lm-paywall');if(!pw){pw=document.createElement('div');pw.className='lm-paywall';pw.innerHTML='

Continue this course with Pro

'+'

The first lessons are free. Unlock the full '+esc(courseTitle)+' course, every interactive lesson, and your certificate with Pro.

'+'See plans →';stage.appendChild(pw);} pw.style.display='';curEl.textContent=Math.min(i+1,total);midEl.textContent='Preview complete';backBtn.disabled=false;contBtn.disabled=true;stage.scrollTop=0;} function renderPassChip(){var tr=app.querySelector('.lm-top-right');if(!tr||tr.querySelector('.lm-pass'))return;if(!passState||!passState.active||access!=='pro')return;var a=document.createElement('a');a.className='lm-pass';a.href='/pricing.html';a.textContent='Pass: '+passState.days_left+' day'+ (passState.days_left===1?'':'s')+' left';var cert=tr.querySelector('.lm-cert');if(cert){tr.insertBefore(a,cert);cert.style.display='none';} else tr.appendChild(a);try{if(typeof gtag==='function')gtag('event','pass_chip_view',{lesson:curSlug,days_left:passState.days_left});}catch(e){}} function updateGatePassCopy(){var g=stage.querySelector('.lm-gate');if(!g||body.classList.contains('pro'))return;var h=g.querySelector('h3');if(h&&h.textContent!=='Your 30-day Data Analyst pass has ended'){h.textContent='Your 30-day Data Analyst pass has ended';} if(!g.querySelector('.lm-gate-pass-note')){var n=document.createElement('p');n.className='lm-gate-pass-note';n.textContent='Everything you finished stays on your profile, and the New to R course stays free.';var pos=g.querySelector('.lm-gate-pos')||h;if(pos&&pos.parentNode)pos.parentNode.insertBefore(n,pos.nextSibling);}} function teardownGate(){var g=stage.querySelector('.lm-gate');if(g)g.style.display='none';stage.classList.remove('lm-gatelock');steps.forEach(function(s){s.classList.remove('lm-teaser','lm-teaser-quiz');});var sg=app.querySelector('.lm-segs');if(sg)sg.classList.remove('lm-gated');var sp=app.querySelector('.lm-stepper');if(sp)sp.classList.remove('lm-gated');} function fillGateFreeLink(){var a=stage.querySelector('[data-gate-free]');if(!a||!railCourse||!railCourse.lessons)return;for(var j=0;j1?steps[1]:steps[0];if(teaser){teaser.classList.add('on','lm-teaser');if(lessonKind==='quiz')teaser.classList.add('lm-teaser-quiz');if(window.LessonWidgets){try{window.LessonWidgets.mountAll(teaser);}catch(e){}}} stage.classList.add('lm-gatelock');var g=stage.querySelector('.lm-gate');if(!g){var isProUser=body.classList.contains('pro');var desc='';try{var m=document.querySelector('meta[name="Description"]')||document.querySelector('meta[name="description"]');desc=(m&&m.getAttribute('content'))||'';}catch(e){} var pos=(ds.courseLesson&&ds.courseTotal)?'Lesson '+esc(ds.courseLesson)+' of '+esc(ds.courseTotal)+(courseTitle?' · '+esc(courseTitle):'')+' · '+total+' steps':esc(courseTitle||'');g=document.createElement('div');g.className='lm-gate';g.innerHTML='
'+''+'

'+(isProUser?'This lesson is in a different track':(passState&&!passState.active?'Your 30-day Data Analyst pass has ended':'This is a Pro lesson'))+'

'+ (pos?'

'+pos+'

':'')+ (desc?'

'+esc(desc)+'

':'')+''+(isProUser?'Upgrade to All-Access →':'Unlock with Pro →')+''+'

From $9/month, or $65 for a full year

'+'

14-day money-back guarantee · cancel anytime

'+'
'+'← Back to '+esc(exitLabel())+''+'
';stage.appendChild(g);g.addEventListener('click',function(ev){var t=ev.target.closest&&ev.target.closest('[data-gate-cta],[data-gate-free]');if(!t)return;try{if(typeof gtag==='function')gtag('event','pro_gate_cta',{target:t.hasAttribute('data-gate-cta')?'pricing':'free-lesson',lesson:curSlug});}catch(e){}});try{if(typeof gtag==='function')gtag('event','pro_gate_view',{lesson:curSlug,course:courseId||''});}catch(e){}}else{g.style.display='';} if(passState&&!passState.active)updateGatePassCopy();fillGateFreeLink();segEls.forEach(function(e2){e2.className='';});curEl.textContent=1;midEl.textContent='Pro lesson';backBtn.disabled=true;contBtn.disabled=true;var sg2=app.querySelector('.lm-segs');if(sg2)sg2.classList.add('lm-gated');var sp2=app.querySelector('.lm-stepper');if(sp2)sp2.classList.add('lm-gated');stage.scrollTop=0;} function renderSignInWall(){rsSignal('signin_wall_hit',courseId?courseId+':'+lessonOrder:'');steps.forEach(function(s){s.classList.remove('on');});var w=stage.querySelector('.lm-signin');if(!w){var next=encodeURIComponent(location.pathname+location.search);w=document.createElement('div');w.className='lm-signin';w.innerHTML='

Create a free account to keep going

'+'

You have started '+esc(courseTitle)+'. It is free to continue: a free account unlocks the rest of this course, saves your progress, and lets you pick up on any device.

'+''+''+'';stage.appendChild(w);}else{w.style.display='';} segEls.forEach(function(e){e.className='';});curEl.textContent=Math.min(lessonOrder||(i+1),total);midEl.textContent='Free account needed';backBtn.disabled=true;contBtn.disabled=true;stage.scrollTop=0;} function render(){if(accountLocked){renderSignInWall();return;} if(locked&&!gateHold){renderProGate();return;} teardownGate();var sw=stage.querySelector('.lm-signin');if(sw)sw.style.display='none';if(showingPaywall){var p=stage.querySelector('.lm-paywall');if(p)p.style.display='none';showingPaywall=false;} steps.forEach(function(s,k){s.classList.toggle('on',k===i);});segEls.forEach(function(e,k){e.className=kstate.furthest){state.furthest=i;save();} if(window.LessonWidgets)window.LessonWidgets.mountAll(steps[i]);if(last){if(courseId)markCourseLessonDone(curSlug);showCompleteActions();} stage.scrollTop=0;} function go(delta){var target=i+delta;if(target<0||target>=total){if(target>=total&&i===total-1&&nextHref){location.href=nextHref;} return;} if(locked&&!gateHold){renderProGate();return;} i=target;render();} backBtn.addEventListener('click',function(){if(showingPaywall){render();return;} go(-1);});contBtn.addEventListener('click',function(){go(1);});document.addEventListener('keydown',function(e){var t=e.target;if(t&&(t.isContentEditable||(t.tagName&&/^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName))||(t.closest&&t.closest('.webr-container, .webr-editor, .webr-editor-input, [contenteditable="true"]')))){return;} if(e.key==='ArrowRight'&&!contBtn.disabled)go(1);else if(e.key==='ArrowLeft'&&!backBtn.disabled)go(-1);});function courseState(){try{return JSON.parse(localStorage.getItem(COURSE_KEY))||{};}catch(e){return{};}} function courseSave(s){try{localStorage.setItem(COURSE_KEY,JSON.stringify(s));}catch(e){}} function markCourseLessonDone(slug){if(!slug)return;var s=courseState();s.completed=s.completed||{};if(!s.completed[slug]){s.completed[slug]=true;s.last=slug;courseSave(s);renderRail();rsSignal('lesson_complete',courseId?courseId+':'+lessonOrder:slug);}} function curRoadmap(){return(railCourse&&railCourse.roadmap)||null;} function buildTrackIndex(){var rm=curRoadmap();if(!rm||!rm.track)return null;var idx={track:rm.track,trackLabel:rm.trackLabel||rm.track,sections:{}};allCourses.forEach(function(c){if(!c.roadmap||c.roadmap.track!==rm.track)return;var n=c.roadmap.section;var sec=idx.sections[n]||(idx.sections[n]={n:n,label:c.roadmap.sectionLabel||('Section '+n),courses:[]});sec.courses.push(c);});return idx;} function sectionNums(){return Object.keys(trackIndex.sections).map(Number).sort(function(a,b){return a-b;});} function railLessonRows(course,done,pro){var h='';(course.lessons||[]).forEach(function(l){var cur=l.slug===curSlug,isDone=!!done[l.slug];var lk=String(l.access||'').toLowerCase()==='pro'&&!pro;var soon=l.built===false;var cls='lm-rail-item'+(cur?' current':'')+(isDone?' done':'')+(lk?' locked':'')+(soon?' soon':'');var mk=isDone?'':''+(l.order||'')+'';var badge=soon?'soon':(lk?'Pro':'');var inner=mk+''+esc(l.title)+''+badge;if(cur||soon)h+='
  • '+inner+'
  • ';else h+='
  • '+inner+'
  • ';});return h;} function railUp(label){return'';} function renderLessonsLevel(done,pro,hasUp){var dn=railCourse.lessons.filter(function(l){return done[l.slug];}).length;var rm=curRoadmap();var up=(hasUp&&rm)?railUp(rm.sectionLabel||'This section'):'';return'
    '+up+''+esc(railCourse.title)+''+''+dn+' / '+railCourse.lessons.length+' done
    '+'
      '+railLessonRows(railCourse,done,pro)+'
    ';} function renderSectionLevel(done,pro){var sec=trackIndex.sections[viewSection];if(!sec)return renderLessonsLevel(done,pro,true);var h='
    '+railUp(trackIndex.trackLabel)+'Section '+esc(sec.n)+''+''+esc(sec.label)+'
    ';sec.courses.forEach(function(c){var isCur=c.course_id===courseId;var cdn=(c.lessons||[]).filter(function(l){return done[l.slug];}).length;h+='
    '+'
    '+esc(c.title)+''+cdn+' / '+(c.lessons||[]).length+'
    '+'
      '+railLessonRows(c,done,pro)+'
    ';});return h;} function renderTrackLevel(done,pro){var h='
    '+railUp('The roadmap')+'Track'+''+esc(trackIndex.trackLabel)+'
      ';sectionNums().forEach(function(n){var sec=trackIndex.sections[n],isCur=n===curSection;var nLes=sec.courses.reduce(function(a,c){return a+(c.lessons||[]).length;},0);h+='
    1. ';});return h+'
    Full '+esc(trackIndex.trackLabel)+' roadmap →';} function renderRail(){var rail=app.querySelector('.lm-rail');if(!rail||!railCourse||!railCourse.lessons)return;app.classList.add('lm-has-rail');var st=courseState(),done=st.completed||{},pro=body.classList.contains('pro');if(!curRoadmap()||!trackIndex){rail.innerHTML=renderLessonsLevel(done,pro,false);return;} if(railLevel==='track')rail.innerHTML=renderTrackLevel(done,pro);else if(railLevel==='section')rail.innerHTML=renderSectionLevel(done,pro);else rail.innerHTML=renderLessonsLevel(done,pro,true);} function wireRail(){if(railWired)return;var rail=app.querySelector('.lm-rail');if(!rail)return;railWired=true;rail.addEventListener('click',function(e){if(e.target.closest('.lm-rail-up')){e.preventDefault();if(railLevel==='lessons'){viewSection=curSection;railLevel='section';} else if(railLevel==='section'){railLevel='track';} else{location.href=roadmapTrackUrl(curRoadmap());return;} renderRail();return;} var sb=e.target.closest('[data-rail-section]');if(sb){e.preventDefault();viewSection=parseInt(sb.getAttribute('data-rail-section'),10);railLevel='section';renderRail();}});} function buildRail(){if(!courseId)return;fetch('/courses.json',{cache:'no-cache'}).then(function(r){return r.ok?r.json():null;}).then(function(data){if(!data||!data.courses)return;allCourses=data.courses;for(var k=0;k› ';titleEl.classList.add('lm-crumbs');titleEl.innerHTML='Roadmap'+sep+''+esc(rm.trackLabel||rm.track)+''+sep+''+esc(rm.sectionLabel||'')+''+sep+''+esc(lessonTitle)+''+ (showCounter?' · Lesson '+esc(ds.courseLesson)+' of '+esc(ds.courseTotal)+'':'');}} function showCompleteActions(){var step=steps[total-1];if(!step||step.querySelector('.lm-complete-actions'))return;var prog='';if(railCourse&&railCourse.lessons){var st=courseState(),done=st.completed||{};var dn=railCourse.lessons.filter(function(l){return done[l.slug];}).length;prog='
    '+ (ds.courseLesson&&ds.courseTotal?'Lesson '+esc(ds.courseLesson)+' of '+esc(ds.courseTotal)+' complete':'Lesson complete')+' · '+dn+' / '+railCourse.lessons.length+' done
    ';} var primary=nextHref?'Next lesson →':'Finish ✓';var card=document.createElement('div');card.className='lm-complete-actions';card.innerHTML=prog+'
    '+primary+''+'← '+esc(exitLabel())+'
    ';step.appendChild(card);var rv=card.querySelector('.lm-ca-review');if(rv)rv.addEventListener('click',function(){i=0;render();});} function toggleFs(){try{if(!document.fullscreenElement){if(document.documentElement.requestFullscreen)document.documentElement.requestFullscreen();} else if(document.exitFullscreen)document.exitFullscreen();}catch(e){}} var railToggle=app.querySelector('.lm-rail-toggle');if(railToggle)railToggle.addEventListener('click',function(){app.classList.toggle('rail-open');});var fsBtn=app.querySelector('.lm-fs');if(fsBtn)fsBtn.addEventListener('click',toggleFs);buildRail();if(locked&&i>=PREVIEW_STEPS)i=PREVIEW_STEPS-1;render();document.documentElement.classList.remove('lm-boot');if(API&&API.token&&API.token())hydrateSolved();});function esc(s){return String(s==null?'':s).replace(/[&<>"]/g,function(c){return({'&':'&','<':'<','>':'>','"':'"'})[c];});}})();