@learnpack/learnpack 5.0.351 → 5.0.352
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/lib/utils/packageManifest.d.ts +4 -0
- package/lib/utils/packageManifest.js +36 -6
- package/lib/utils/s3/packageManifestBackfill.d.ts +82 -0
- package/lib/utils/s3/packageManifestBackfill.js +485 -0
- package/package.json +4 -1
- package/src/ui/_app/app.js +2 -2
- package/src/ui/app.tar.gz +0 -0
- package/src/utils/export/README.md +0 -2
- package/src/utils/packageManifest.ts +51 -10
- package/src/utils/s3/packageManifestBackfill.ts +776 -0
package/src/ui/_app/app.js
CHANGED
|
@@ -499,7 +499,7 @@ components:\r
|
|
|
499
499
|
- Maintain professional, clean aesthetic appropriate for learning\r
|
|
500
500
|
example: |\r
|
|
501
501
|
\r
|
|
502
|
-
`,V5=!1,ha="";function Yp(e,t){return e==="localStorage"||e==="scorm"||e==="creatorWeb"&&t!=="creator"}function Ah(e){return e==="localStorage"||e==="scorm"||e==="creatorWeb"}const tvt="https://ai.4geeks.com";function VCe(e){Array.isArray(e)||(e=[e]);const t=new URLSearchParams(window.location.search);let r={};return e.forEach(a=>r[a]=t.get(a)),e.length==1?r[e[0]]:r}const rvt=location.protocol+"//"+location.hostname+(location.port?":"+location.port:""),RC=function(){const e=window.location.pathname.endsWith("/config/index.html");let t=VCe("config");t&&t!==""&&(t=JSON.parse(atob(t)));let r=t?`${t.address}:${t.port}`:VCe("host")||rvt;return e&&(r=window.location.href.replace("/config/index.html","")),r};let Kp="localhost";const GCe=async()=>{var r;const e=RC();if(console.log("DETECTED HOST",e),window.location.pathname.endsWith("/config/index.html"))try{const n=await fetch(`${e}/.learn/config.json`);if(n.ok)return await n.json(),Kp="scorm",document.dispatchEvent(new CustomEvent("environment-change",{detail:{environment:"scorm"}})),console.log("The environment will be scorm"),"scorm"}catch(n){console.error("SCORM config fetch failed, falling back to legacy detection",n)}try{const n=Kr(),a=await fetch(`${e}/config?slug=${n}`),i=(r=a.headers.get("Content-Type"))==null?void 0:r.includes("application/json");if(a.ok&&i){let o="localhost";a.headers.get("X-Creator-Web")&&(o="creatorWeb"),console.log("The environment will be:",o),Kp=o;const l=new CustomEvent("environment-change",{detail:{environment:o}});return document.dispatchEvent(l),o}else throw Error("The response was unsuccessful")}catch{Kp="localStorage";try{const a=await fetch(`${e}/config.json`);if(!a.ok)throw new Error("config.json not found");await a.json(),console.log("The environment will be localStorage");const i=new CustomEvent("environment-change",{detail:{environment:"localStorage"}});return document.dispatchEvent(i),"localStorage"}catch{try{const i=await fetch(`${e}/.learn/config.json`);if(console.log("SCORM CONFIG PATH",i),!i.ok)throw new Error(".learn/config.json not found");await i.json(),Kp="scorm";const o=new CustomEvent("environment-change",{detail:{environment:"scorm"}});return console.log("The environment will be scorm"),document.dispatchEvent(o),"scorm"}catch(i){return console.error("Error fetching scorm config, impossible to detect environment",i),"localStorage"}}}};GCe();const ui="https://rigobot.herokuapp.com",QCe=
|
|
502
|
+
`,V5=!1,ha="";function Yp(e,t){return e==="localStorage"||e==="scorm"||e==="creatorWeb"&&t!=="creator"}function Ah(e){return e==="localStorage"||e==="scorm"||e==="creatorWeb"}const tvt="https://ai.4geeks.com";function VCe(e){Array.isArray(e)||(e=[e]);const t=new URLSearchParams(window.location.search);let r={};return e.forEach(a=>r[a]=t.get(a)),e.length==1?r[e[0]]:r}const rvt=location.protocol+"//"+location.hostname+(location.port?":"+location.port:""),RC=function(){const e=window.location.pathname.endsWith("/config/index.html");let t=VCe("config");t&&t!==""&&(t=JSON.parse(atob(t)));let r=t?`${t.address}:${t.port}`:VCe("host")||rvt;return e&&(r=window.location.href.replace("/config/index.html","")),r};let Kp="localhost";const GCe=async()=>{var r;const e=RC();if(console.log("DETECTED HOST",e),window.location.pathname.endsWith("/config/index.html"))try{const n=await fetch(`${e}/.learn/config.json`);if(n.ok)return await n.json(),Kp="scorm",document.dispatchEvent(new CustomEvent("environment-change",{detail:{environment:"scorm"}})),console.log("The environment will be scorm"),"scorm"}catch(n){console.error("SCORM config fetch failed, falling back to legacy detection",n)}try{const n=Kr(),a=await fetch(`${e}/config?slug=${n}`),i=(r=a.headers.get("Content-Type"))==null?void 0:r.includes("application/json");if(a.ok&&i){let o="localhost";a.headers.get("X-Creator-Web")&&(o="creatorWeb"),console.log("The environment will be:",o),Kp=o;const l=new CustomEvent("environment-change",{detail:{environment:o}});return document.dispatchEvent(l),o}else throw Error("The response was unsuccessful")}catch{Kp="localStorage";try{const a=await fetch(`${e}/config.json`);if(!a.ok)throw new Error("config.json not found");await a.json(),console.log("The environment will be localStorage");const i=new CustomEvent("environment-change",{detail:{environment:"localStorage"}});return document.dispatchEvent(i),"localStorage"}catch{try{const i=await fetch(`${e}/.learn/config.json`);if(console.log("SCORM CONFIG PATH",i),!i.ok)throw new Error(".learn/config.json not found");await i.json(),Kp="scorm";const o=new CustomEvent("environment-change",{detail:{environment:"scorm"}});return console.log("The environment will be scorm"),document.dispatchEvent(o),"scorm"}catch(i){return console.error("Error fetching scorm config, impossible to detect environment",i),"localStorage"}}}};GCe();const ui="https://rigobot.herokuapp.com",QCe=3e4,nvt=2e3,avt=3,ivt=1e3,ovt=3,Lv="https://breathecode.herokuapp.com",svt=()=>{const e=document.querySelector(".sidebar-component");e&&(window.getComputedStyle(e).left==="0px"?(e.classList.remove("sidebar-appear"),e.classList.add("sidebar-disappear")):(e==null||e.classList.remove("sidebar-disappear"),e==null||e.classList.add("sidebar-appear")),e==null||e.offsetWidth)},lvt=async e=>await fetch(`${RC()}/exercise/${e}`),cvt=async(e,t)=>{const r=ui+"/v1/conversation/?purpose="+e,n={method:"POST",headers:{"Content-Type":"application/json",Authorization:"Token "+t}};return await(await fetch(r,n)).json()},WCe=()=>{const e=document.querySelector("#socket-disconnected");e&&(e.style.display="block")},uvt=()=>{const e=document.querySelector("#socket-disconnected");e&&(e.style.display="none")},dvt=()=>{const e=new URLSearchParams(window.location.search);let t={};for(const[r,n]of e.entries())t[r]=n;return t},BC=()=>dvt(),Rl=(e,t)=>{let r,n=null;const a=(...i)=>{n=i,clearTimeout(r),r=setTimeout(()=>{n=null,e(...i)},t)};return a.cancel=()=>{clearTimeout(r),n=null},a.flush=()=>{n!==null&&(clearTimeout(r),e(...n),n=null)},a},YCe=e=>e.replace(/\x1B[@-_][0-?]*[ -/]*[@-~]/g,""),KCe=(e,t,r)=>{const n=new RegExp(t,"g");return e.replace(n,r)},K1=e=>{const t=new URLSearchParams;Object.entries(e).forEach(([a,i])=>{i!=null&&i!==""&&t.set(a,String(i))});const r=t.toString(),n=r?`${window.location.pathname}?${r}${window.location.hash}`:`${window.location.pathname}${window.location.hash}`;window.history.replaceState(null,"",n)};function lce(e,t){return Math.random()*(t-e)+e}class OC extends Error{constructor(t){super(t),this.name="MissingRigobotAccountError"}}class XCe extends Error{constructor(t){super(t),this.name="TokenExpiredError"}}const cce=(e,t="ai-conversation-message")=>{const r=e.voids.find(n=>n.slug===t);return r?r.balance.unit:0},G5=async e=>{const r=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",r);return Array.from(new Uint8Array(n)).map(o=>o.toString(16).padStart(2,"0")).join("")};async function mh(e,t=2e3){const r=Date.now()-e;r<t&&await new Promise(n=>setTimeout(n,t-r))}const hvt=e=>{const t=new URL(window.location.href);t.searchParams.delete(e);const r=new URLSearchParams(t.hash.slice(1));r.delete(e),r.toString()?t.hash=`#${r.toString()}`:t.hash="",window.history.replaceState({},"",t.toString())},ZCe=e=>{Lle.dataLayer(e)},Yu=(e,t)=>`---
|
|
503
503
|
`+oCe(e)+`---
|
|
504
504
|
|
|
505
505
|
`+t,fvt=e=>e==="us"?"en":"es",DC=e=>e==="en"||e==="us"?".md":`.${e}.md`,zo=(e,t="en")=>{try{const r=new Intl.DisplayNames([t],{type:"language"}),n=e==="us"?"en":e;return r.of(n)||e}catch{return e}},pvt=(e,t="")=>e.includes("?")||e.includes("#")?btoa(e+t):btoa(e+"?"+t),gvt="https://storage.googleapis.com/breathecode/learnpack",Bl=e=>{try{const t=Math.floor(Math.random()*2),r=new Audio(`${gvt}/sounds-${e}/${e==="success"?t:0}.mp3`);r.volume=.4,r.play()}catch(t){console.error("Error playing sound",t)}};function Q5(e){const t=/^---\s*[\s\S]*?\s*---\s*/;return e.replace(t,"").trimStart()}function FC(e){const t=parseFloat(e);if(Number.isNaN(t))return e;if(t===0)return"0";const r=t.toString().split(".");return r[0]=r[0].replace(/^0+(?=\d)/,""),r.join(".")}function PC(e,t="en"){var r,n,a,i;return e?typeof e=="string"?e.trim():((r=e[t])==null?void 0:r.trim())||((n=e.en)==null?void 0:n.trim())||((a=e.us)==null?void 0:a.trim())||((i=Object.values(e).find(o=>typeof o=="string"&&o.trim()))==null?void 0:i.trim())||"":""}function Avt(e){let t=e.split("-");t.shift();let r=t.join(" ");return r=r.charAt(0).toUpperCase()+r.slice(1),r}function $C(e,t,r,n){var s;const a=FC(e.split("-")[0]),i=((s=t==null?void 0:t[e])==null?void 0:s[r])||n,o=Avt(i);return{id:a,formattedTitle:o}}function Kr(){const e=window.location.pathname.split("/").filter(Boolean);return e[0]==="preview"&&e[1]?e[1]:e.pop()||null}function JCe(){return`teacherOnboardingClosed_${Kr()||"default"}`}const e9e=async(e,t)=>{console.log("Uploading blob to bucket",e,t);const r=new FormData;r.append("file",e,"preview.png"),r.append("destination",t);const n=await fetch("/upload-image-file",{method:"POST",body:r});if(!n.ok)throw console.error("Error uploading image to bucket",n),new Error("Failed to upload image");return await n.json()},mvt=async e=>{try{return(await Ur.get(`${V5?"http://localhost:3000":""}/check-preview-image/${e}`)).data}catch(t){return console.error("Error checking preview image",t),null}},W5=(e,t=!0)=>{let r=e.toString().normalize("NFD").replace(/[\u0300-\u036F]/g,"").toLowerCase().trim().replace(/[^\d\s._a-z-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-");return t&&(r=r.replace(/^-+|-+$/g,"")),r},yvt=async e=>{try{const t=`${ui}/v1/learnpack/check-slug-availability?slug=${encodeURIComponent(e)}`;return(await Ur.get(t)).data.available}catch(t){throw console.error("Error checking slug availability:",t),t}},t9e=async(e,{prompt:t,callbackUrl:r,context:n})=>{try{return(await Ur.post(`${ui}/v1/learnpack/tools/images`,{prompt:t,context:n,webhook_callback_url:r},{headers:{"Content-Type":"application/json",Authorization:"Token "+e}})).data}catch(a){return console.error("Error generating image:",a),null}};function vvt(e,t="",r=""){let n="Bug";t&&(n=`Bug in ${t}`);const a=`Lesson: ${e}
|
|
@@ -753,7 +753,7 @@ ${t}</body>`,n):(console.log("NO HTML TAG"),`
|
|
|
753
753
|
`+e.slice(o+1):l+=e.slice(a),l.slice(1)}function V5t(e){for(var t="",r,n,a,i=0;i<e.length;i++){if(r=e.charCodeAt(i),r>=55296&&r<=56319&&(n=e.charCodeAt(i+1),n>=56320&&n<=57343)){t+=mEe((r-55296)*1024+n-56320+65536),i++;continue}a=Ho[r],t+=!a&&$v(r)?e[i]:a||mEe(r)}return t}function G5t(e,t,r){var n="",a=e.tag,i,o;for(i=0,o=r.length;i<o;i+=1)e0(e,t,r[i],!1,!1)&&(i!==0&&(n+=","+(e.condenseFlow?"":" ")),n+=e.dump);e.tag=a,e.dump="["+n+"]"}function Q5t(e,t,r,n){var a="",i=e.tag,o,s;for(o=0,s=r.length;o<s;o+=1)e0(e,t+1,r[o],!0,!0)&&((!n||o!==0)&&(a+=$ce(e,t)),e.dump&&iw===e.dump.charCodeAt(0)?a+="-":a+="- ",a+=e.dump);e.tag=i,e.dump=a||"[]"}function W5t(e,t,r){var n="",a=e.tag,i=Object.keys(r),o,s,l,u,d;for(o=0,s=i.length;o<s;o+=1)d="",o!==0&&(d+=", "),e.condenseFlow&&(d+='"'),l=i[o],u=r[l],e0(e,t,l,!1,!1)&&(e.dump.length>1024&&(d+="? "),d+=e.dump+(e.condenseFlow?'"':"")+":"+(e.condenseFlow?"":" "),e0(e,t,u,!1,!1)&&(d+=e.dump,n+=d));e.tag=a,e.dump="{"+n+"}"}function Y5t(e,t,r,n){var a="",i=e.tag,o=Object.keys(r),s,l,u,d,h,f;if(e.sortKeys===!0)o.sort();else if(typeof e.sortKeys=="function")o.sort(e.sortKeys);else if(e.sortKeys)throw new aw("sortKeys must be a boolean or a function");for(s=0,l=o.length;s<l;s+=1)f="",(!n||s!==0)&&(f+=$ce(e,t)),u=o[s],d=r[u],e0(e,t+1,u,!0,!0,!0)&&(h=e.tag!==null&&e.tag!=="?"||e.dump&&e.dump.length>1024,h&&(e.dump&&iw===e.dump.charCodeAt(0)?f+="?":f+="? "),f+=e.dump,h&&(f+=$ce(e,t)),e0(e,t+1,d,!0,h)&&(e.dump&&iw===e.dump.charCodeAt(0)?f+=":":f+=": ",f+=e.dump,a+=f));e.tag=i,e.dump=a||"{}"}function TEe(e,t,r){var n,a,i,o,s,l;for(a=r?e.explicitTypes:e.implicitTypes,i=0,o=a.length;i<o;i+=1)if(s=a[i],(s.instanceOf||s.predicate)&&(!s.instanceOf||typeof t=="object"&&t instanceof s.instanceOf)&&(!s.predicate||s.predicate(t))){if(e.tag=r?s.tag:"?",s.represent){if(l=e.styleMap[s.tag]||s.defaultStyle,lEe.call(s.represent)==="[object Function]")n=s.represent(t,l);else if(cEe.call(s.represent,l))n=s.represent[l](t,l);else throw new aw("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');e.dump=n}return!0}return!1}function e0(e,t,r,n,a,i){e.tag=null,e.dump=r,TEe(e,r,!1)||TEe(e,r,!0);var o=lEe.call(e.dump);n&&(n=e.flowLevel<0||e.flowLevel>t);var s=o==="[object Object]"||o==="[object Array]",l,u;if(s&&(l=e.duplicates.indexOf(r),u=l!==-1),(e.tag!==null&&e.tag!=="?"||u||e.indent!==2&&t>0)&&(a=!1),u&&e.usedDuplicates[l])e.dump="*ref_"+l;else{if(s&&u&&!e.usedDuplicates[l]&&(e.usedDuplicates[l]=!0),o==="[object Object]")n&&Object.keys(e.dump).length!==0?(Y5t(e,t,e.dump,a),u&&(e.dump="&ref_"+l+e.dump)):(W5t(e,t,e.dump),u&&(e.dump="&ref_"+l+" "+e.dump));else if(o==="[object Array]"){var d=e.noArrayIndent&&t>0?t-1:t;n&&e.dump.length!==0?(Q5t(e,d,e.dump,a),u&&(e.dump="&ref_"+l+e.dump)):(G5t(e,d,e.dump),u&&(e.dump="&ref_"+l+" "+e.dump))}else if(o==="[object String]")e.tag!=="?"&&j5t(e,e.dump,t,i);else{if(e.skipInvalid)return!1;throw new aw("unacceptable kind of an object to dump "+o)}e.tag!==null&&e.tag!=="?"&&(e.dump="!<"+e.tag+"> "+e.dump)}return!0}function K5t(e,t){var r=[],n=[],a,i;for(zce(e,r,n),a=0,i=n.length;a<i;a+=1)t.duplicates.push(r[n[a]]);t.usedDuplicates=new Array(i)}function zce(e,t,r){var n,a,i;if(e!==null&&typeof e=="object")if(a=t.indexOf(e),a!==-1)r.indexOf(a)===-1&&r.push(a);else if(t.push(e),Array.isArray(e))for(a=0,i=e.length;a<i;a+=1)zce(e[a],t,r);else for(n=Object.keys(e),a=0,i=n.length;a<i;a+=1)zce(e[n[a]],t,r)}function LEe(e,t){t=t||{};var r=new P5t(t);return r.noRefs||K5t(e,r),e0(r,0,e,!0,!0)?r.dump+`
|
|
754
754
|
`:""}function X5t(e,t){return LEe(e,nw.extend({schema:v5t},t))}Pce.dump=LEe,Pce.safeDump=X5t;var s9=J5,NEe=Pce;function l9(e){return function(){throw new Error("Function "+e+" is deprecated and cannot be used.")}}Ha.Type=eo,Ha.Schema=Bv,Ha.FAILSAFE_SCHEMA=Rce,Ha.JSON_SCHEMA=P9e,Ha.CORE_SCHEMA=$9e,Ha.DEFAULT_SAFE_SCHEMA=rw,Ha.DEFAULT_FULL_SCHEMA=t9,Ha.load=s9.load,Ha.loadAll=s9.loadAll,Ha.safeLoad=s9.safeLoad,Ha.safeLoadAll=s9.safeLoadAll,Ha.dump=NEe.dump,Ha.safeDump=NEe.safeDump,Ha.YAMLException=tw,Ha.MINIMAL_SCHEMA=Rce,Ha.SAFE_SCHEMA=rw,Ha.DEFAULT_SCHEMA=t9,Ha.scan=l9("scan"),Ha.parse=l9("parse"),Ha.compose=l9("compose"),Ha.addConstructor=l9("addConstructor");var Z5t=Ha,J5t=Z5t,MEe=J5t,ewt="\\ufeff?",twt=typeof process<"u"?process.platform:"",rwt="^("+ewt+"(= yaml =|---)$([\\s\\S]*?)^(?:\\2|\\.\\.\\.)\\s*$"+(twt==="win32"?"\\r?":"")+"(?:\\n)?)",IEe=new RegExp(rwt,"m");Nce.exports=nwt,Nce.exports.test=owt;function nwt(e,t){e=e||"";var r={allowUnsafe:!1};t=t instanceof Object?{...r,...t}:r,t.allowUnsafe=!!t.allowUnsafe;var n=e.split(/(\r?\n)/);return n[0]&&/= yaml =|---/.test(n[0])?iwt(e,t.allowUnsafe):{attributes:{},body:e,bodyBegin:1}}function awt(e,t){for(var r=1,n=t.indexOf(`
|
|
755
755
|
`),a=e.index+e[0].length;n!==-1;){if(n>=a)return r;r++,n=t.indexOf(`
|
|
756
|
-
`,n+1)}return r}function iwt(e,t){var r=IEe.exec(e);if(!r)return{attributes:{},body:e,bodyBegin:1};var n=t?MEe.load:MEe.safeLoad,a=r[r.length-1].replace(/^\s+|\s+$/g,""),i=n(a)||{},o=e.replace(r[0],""),s=awt(r,e);return{attributes:i,body:o,bodyBegin:s,frontmatter:a}}function owt(e){return e=e||"",IEe.test(e)}var swt=Nce.exports;const REe=Ta(swt),lwt=1;class cwt{constructor(){mr(this,"name","engagement_indicator")}calculateStepIndicator(t,r){return r.status!=="skipped"&&r.status!=="unread"?Math.min(r.time_spent/3600*100,100):0}calculateGlobalIndicator(t,r){const n={total_time:.3,num_sessions:.2,completion_rate:.3,interactions:.2},a=Math.min(r.total_time_on_platform/36e3,1)*100,i=Math.min(r.num_sessions/5,1)*100,o=r.completion_rate,s=Math.min(r.total_interactions/100,1)*100;return(a*n.total_time+i*n.num_sessions+o*n.completion_rate+s*n.interactions)/100*100}}class uwt{constructor(){mr(this,"name","frustration_indicator")}calculateStepIndicator(t,r){return r.status==="completed"?Math.min((r.comp_struggles+r.test_struggles)/20*100,100):r.status==="attempted"?Math.min(r.time_spent/1800*100,100):r.status==="skipped"?25:0}calculateGlobalIndicator(t,r){const n={steps_not_completed:.3,time_on_incomplete:.2,avg_comp_struggles:.2,avg_test_struggles:.2,skipped_steps:.1},a=r.total_steps>0?r.steps_not_completed/r.total_steps*100:0,i=Math.min(r.time_on_incomplete/18e3,1)*100,o=Math.min(r.avg_comp_struggles/10,1)*100,s=Math.min(r.avg_test_struggles/10,1)*100,l=r.total_steps>0?r.skipped_steps/r.total_steps*100:0;return(a*n.steps_not_completed+i*n.time_on_incomplete+o*n.avg_comp_struggles+s*n.avg_test_struggles+l*n.skipped_steps)/100*100}}function BEe(e){var x,w,C,S,T,N,M,B,D,I,O,F,P,R,U,$;let t=0;e.sessions&&e.sessions.length>0&&(t=e.sessions.reduce((z,q)=>z+q,0));let r=t;!t&&e.completed_at&&e.opened_at&&(r=e.completed_at-e.opened_at,t=r);let n=e.completed_at?"completed":e.opened_at?"attempted":"unread";const a=((x=e.compilations)==null?void 0:x.filter(z=>z.exit_code!==0).length)||0,i=((w=e.compilations)==null?void 0:w.filter(z=>z.exit_code===0).length)||0,o=((C=e.tests)==null?void 0:C.filter(z=>z.exit_code!==0).length)||0,s=((S=e.tests)==null?void 0:S.filter(z=>z.exit_code===0).length)||0,l=((T=e.quiz_submissions)==null?void 0:T.filter(z=>z.status==="ERROR").length)||0,u=((N=e.quiz_submissions)==null?void 0:N.filter(z=>z.status==="SUCCESS").length)||0;let d=0,h=0;for(let z=((M=e.compilations)==null?void 0:M.length)-1;z>=0&&e.compilations[z].exit_code!==0;z--)d++;for(let z=((B=e.compilations)==null?void 0:B.length)-1;z>=0&&e.compilations[z].exit_code===0;z--)h++;let f=0,p=0;for(let z=((D=e.tests)==null?void 0:D.length)-1;z>=0&&e.tests[z].exit_code!==0;z--)f++;for(let z=((I=e.tests)==null?void 0:I.length)-1;z>=0&&e.tests[z].exit_code===0;z--)p++;let g=0,A=0;for(let z=((O=e.quiz_submissions)==null?void 0:O.length)-1;z>=0&&e.quiz_submissions[z].status==="ERROR";z--)g++;for(let z=((F=e.quiz_submissions)==null?void 0:F.length)-1;z>=0&&e.quiz_submissions[z].status==="SUCCESS";z--)A++;const m=e.is_testeable||e.testeable_elements&&e.testeable_elements.length>0,y=(((P=e.quiz_submissions)==null?void 0:P.length)||0)===0&&(((R=e.tests)==null?void 0:R.length)||0)===0&&(((U=e.compilations)==null?void 0:U.length)||0)===0,v=!!m&&y,b=(($=e.ai_interactions)==null?void 0:$.length)||0,_=a+o+l>0&&i+s+u===0;return{status:n,time_spent:r,total_duration:t,comp_struggles:a,comp_success:i,total_comp_attempts:i+a,test_struggles:o,test_success:s,total_test_attempts:s+o,quiz_struggles:l,quiz_success:u,total_quiz_attempts:u+l,streak_comp_struggles:d,streak_comp_success:h,streak_test_struggle:f,streak_test_success:p,streak_quiz_struggles:g,streak_quiz_success:A,user_skipped:v,total_ai_interactions:b,ai_used:b>0,is_abandoned:_}}function dwt(e){const t=e.length,r=e.map(BEe),n=r.filter(g=>g.status==="completed").length,a=r.filter(g=>g.status==="attempted").length,i=r.filter(g=>g.status==="skipped").length,o=r.filter(g=>g.status==="unread").length,s=t?n/t*100:0,l=e.reduce((g,A)=>{var m,y,v,b;return g+(((m=A.compilations)==null?void 0:m.length)||0)+(((y=A.tests)==null?void 0:y.length)||0)+(((v=A.quiz_submissions)==null?void 0:v.length)||0)+(((b=A.ai_interactions)==null?void 0:b.length)||0)},0),u=r.reduce((g,A)=>g+A.time_spent,0),d=a+i+o,h=t?r.reduce((g,A)=>g+A.comp_struggles,0)/t:0,f=t?r.reduce((g,A)=>g+A.test_struggles,0)/t:0;let p=0;for(const g of e){let A=0;for(const m of g.tests||[])m.exit_code===0?A++:A=0,p=Math.max(p,A)}return{total_time_on_platform:u,num_sessions:1,completion_rate:s,total_interactions:l,steps_not_completed:d,time_on_incomplete:u,avg_comp_struggles:h,avg_test_struggles:f,skipped_steps:i,total_steps:t,global_test_success_streak:p}}function Uv(e){const t=[new cwt,new uwt],r=e.steps.map(o=>BEe(o)),n=dwt(e.steps),a=e.steps.map((o,s)=>{const l=r[s],u={engagement_indicator:0,frustration_indicator:0};return t.forEach(d=>{u[d.name]=d.calculateStepIndicator(o,l)}),{slug:o.slug,metrics:l,indicators:u}}),i={engagement_indicator:0,frustration_indicator:0};return t.forEach(o=>{i[o.name]=o.calculateGlobalIndicator(a.map(s=>s.indicators[o.name]),n)}),{algo_version:lwt,global:{metrics:n,indicators:i},steps:a}}function hwt(e,t){var d,h,f,p;if(!e.testeable_elements)return;const r=e.testeable_elements.find(g=>g.hash===t);if(!r)return;const n=r.type==="quiz"?((d=e.quiz_submissions.find(g=>g.quiz_hash===t))==null?void 0:d.ended_at)||e.opened_at||0:((h=e.tests.shift())==null?void 0:h.started_at)||e.opened_at||0,a=r.type==="quiz"?((f=e.quiz_submissions.findLast(g=>g.quiz_hash===t))==null?void 0:f.ended_at)||e.completed_at||1:((p=e.tests.shift())==null?void 0:p.started_at)||e.completed_at||1,i=Number((a-n)/1e3),o=e.ai_interactions.filter(g=>g.started_at>=n&&g.ended_at<=a).length,s=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t).length:e.tests.length,l=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t&&g.status==="ERROR").length:e.tests.filter(g=>g.exit_code!==1).length,u=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t&&g.status==="SUCCESS").length:e.tests.filter(g=>g.exit_code===1).length;return{started_at:n,ended_at:a,resolution_time_seconds:i,n_ai_interactions:o,n_tries:s,n_fail:l,n_success:u}}const OEe={name:"learnpack-ai",private:!0,version:"5.0.399",scripts:{dev:"node src/utils/development.js --turn on && vite",build:"node src/utils/development.js --turn off && tsc && vite build && node src/utils/uploadLearnpack.js && node bin/publish.js && node src/utils/createVersionsFile.js ","dev-build":"node src/utils/development.js --turn on && tsc && vite build",lint:"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",preview:"vite preview",watch:"vite build --watch","compile-command":"tsc src/utils/development.ts && node src/utils/development.js --turn on"},dependencies:{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@monaco-editor/react":"^4.6.0","@radix-ui/react-tooltip":"^1.2.8",axios:"^1.7.7","class-variance-authority":"^0.7.1",clsx:"^2.1.1",dompurify:"^3.3.0","front-matter":"^4.0.2","highlight.js":"^11.11.1",html2canvas:"^1.4.1",i18next:"^23.10.1","js-yaml":"^4.1.0","lucide-react":"^0.545.0",mermaid:"^11.6.0",mitt:"^3.0.1","monaco-editor":"^0.50.0","prompt-sync":"^4.2.0","pusher-js":"7.6.0","radix-ui":"^1.4.3",react:"^18.2.0","react-dom":"^18.2.0","react-draggable":"^4.4.6","react-gtm-module":"^2.0.11","react-hot-toast":"^2.4.1","react-i18next":"^14.1.0","react-markdown":"^9.0.1","react-monaco-editor":"^0.56.1","react-router-dom":"^6.27.0","react-syntax-highlighter":"^15.6.1","rehype-katex":"^7.0.1","remark-emoji":"^5.0.1","remark-gfm":"^4.0.0","remark-math":"^6.0.0","socket.io":"^4.7.2","socket.io-client":"^4.7.2","tailwind-merge":"^3.3.1","tailwindcss-animate":"^1.0.7",uuid:"^10.0.0",zustand:"^4.4.1"},devDependencies:{"@aws-sdk/client-cloudfront":"^3.840.0","@aws-sdk/client-s3":"^3.709.0","@types/dompurify":"^3.0.5","@types/js-yaml":"^4.0.9","@types/markdown-it":"^14.1.2","@types/node":"^24.9.1","@types/react":"^18.2.15","@types/react-dom":"^18.2.7","@types/react-gtm-module":"^2.0.3","@types/react-syntax-highlighter":"^15.5.13","@types/remarkable":"^2.0.3","@types/uuid":"^10.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","@vitejs/plugin-react-swc":"^3.3.2",archiver:"^6.0.1",autoprefixer:"^10.4.21",dotenv:"^16.4.7",eslint:"^8.45.0","eslint-plugin-react-hooks":"^4.6.0","eslint-plugin-react-refresh":"^0.4.3",inquirer:"^9.2.12",postcss:"^8.5.6",tailwindcss:"^3.4.18",typescript:"^5.0.2",vite:"^4.5.13"}};function fwt(e){return{all:e=e||new Map,on:function(t,r){var n=e.get(t);n?n.push(r):e.set(t,[r])},off:function(t,r){var n=e.get(t);n&&(r?n.splice(n.indexOf(r)>>>0,1):e.set(t,[]))},emit:function(t,r){var n=e.get(t);n&&n.slice().map(function(a){a(r)}),(n=e.get("*"))&&n.slice().map(function(a){a(t,r)})}}}const zr=fwt(),Hce=async(e,t)=>{if(!t)throw new Error("Slug is required");const r=`${ui}/v1/learnpack/session/?slug=${t}`;try{return(await Ur.get(r,{headers:{Authorization:`Token ${e}`}})).data}catch(n){throw console.error("Error fetching session:",n),n}},jce=async(e,t,r,n,a)=>{const i=`${ui}/v1/learnpack/session/${a}/`,o={tab_hash:t,config_json:n,package_slug:r};try{return(await Ur.put(i,o,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}})).data}catch(s){throw console.error("Error updating session:",s),s}},pwt=async(e,t,r,n)=>{const a=`${ui}/v1/learnpack/session/`,i={tab_hash:t,config_json:n,package_slug:r};try{return(await Ur.post(a,i,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}})).data}catch(o){throw console.error("Error creating session:",o),o}};async function gwt(e){const t=`${Lv}/v1/payments/me/service/consumable?virtual=true`,r={Authorization:`Token ${e}`};try{return(await Ur.get(t,{headers:r})).data}catch(n){throw console.error("Error fetching consumables:",n),n}}async function Awt(e,t="ai-conversation-message"){const r=`${Lv}/v1/payments/me/service/${t}/consumptionsession`,n={Authorization:`Token ${e}`};try{const a=await Ur.put(r,{},{headers:n});return a.status>=200&&a.status<300?(console.log(a.data),console.log(`Successfully consumed ${t}`),!0):(console.error(`Request failed with status code: ${a.status}`),console.error(`Response: ${a.data}`),!1)}catch(a){return console.error(`Error consuming ${t}:`,a),!1}}function mwt(e){if(!Array.isArray(e))return[];const t=[];for(const r of e){const n=typeof r=="number"?r:Number(r);Number.isFinite(n)&&t.push(n)}return t}async function qce(e,t){var a;const r={id:null,assetIds:[]};if(!(e!=null&&e.trim())||!t)return r;const n=`${ui}/v1/learnpack/package/${encodeURIComponent(t)}/assets/`;try{const o=(await Ur.get(n,{headers:{Authorization:`Token ${e.trim()}`}})).data;return{id:(o==null?void 0:o.id)!=null?String(o.id):null,assetIds:mwt(o==null?void 0:o.asset_ids)}}catch(i){return Ur.isAxiosError(i)&&((a=i.response)==null?void 0:a.status)===404||console.warn("fetchLearnpackPackageInfo failed:",i),r}}const ywt=async(e,t)=>{var a;const r=`${ui}/v1/learnpack/package/${t}/`;console.log("Checking if package is author",r,e);const n={Authorization:`Token ${e}`};try{const i=await Ur.get(r,{headers:n});return{isAuthor:i.status===200,status:i.status}}catch(i){const o=((a=i==null?void 0:i.response)==null?void 0:a.status)||500;return console.error("Error fetching package:",i),{isAuthor:!1,status:o}}},vwt=async(e,t,r=ui)=>{const n=await Ur.get(`${r}/v1/prompting/completion/${t}/`,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}});return console.log("RigoBot completion response:",n.data),n.data};function bwt(e,t){if(t.length===0)return e;const r=e.includes("?")?"&":"?";return`${e}${r}asset_id=${t.join(",")}`}const wwt=async function(e,t,r,n){if(!e||!r){console.error("URL and token are required");return}r=r.trim();const a={"Content-Type":"application/json",Authorization:`Token ${r}`},i=bwt(e,n??[]);try{return(await Ur.post(i,t,{headers:a})).data}catch(o){throw console.error("Error while sending batch telemetry",o),Ur.isAxiosError(o)&&o.response&&(console.error("Response data:",o.response.data),console.error("Response status:",o.response.status),console.error("Response headers:",o.response.headers)),o}},kwt=async function(e,t){const r=`${ui}/v1/learnpack/telemetry`,n={"Content-Type":"application/json",Authorization:`Token ${t}`};try{return(await Ur.post(r,e,{headers:n})).data}catch(a){throw console.error("Error while sending batch telemetry",a),a}},xwt=5e3,_wt=6e4,Cwt=5*60*1e3;async function DEe(e){var u;const{userId:t,packageSlug:r,rigoToken:n}=e;if(!t||!n||!r)return null;const a=n.trim(),i=new URLSearchParams;i.set("user_ids",String(t)),i.set("include_buffer","true"),i.set("include_steps","true"),i.set("package_slug",r);const o=`${ui}/v1/learnpack/telemetry?${i.toString()}`,s=new AbortController,l=setTimeout(()=>s.abort(),xwt);try{const d=await fetch(o,{method:"GET",headers:{Authorization:`Token ${a}`,Accept:"application/json"},signal:s.signal});if(!d.ok)return console.warn("fetchTelemetryFromServer: non-OK response",d.status),null;const h=await d.json(),f=(u=h==null?void 0:h.results)==null?void 0:u[0];return!f||typeof f!="object"?null:f}catch(d){return d.name==="AbortError"?console.warn("fetchTelemetryFromServer: timeout or aborted"):console.warn("fetchTelemetryFromServer: failed",d),null}finally{clearTimeout(l)}}async function Ewt(e){var u;const{userId:t,packageSlug:r,rigoToken:n}=e;if(!t||!n||!r)return{status:"empty"};const a=n.trim(),i=new URLSearchParams;i.set("user_ids",String(t)),i.set("include_buffer","true"),i.set("include_steps","true"),i.set("package_slug",r);const o=`${ui}/v1/learnpack/telemetry?${i.toString()}`,s=new AbortController,l=setTimeout(()=>s.abort(),_wt);try{const d=await fetch(o,{method:"GET",headers:{Authorization:`Token ${a}`,Accept:"application/json"},signal:s.signal});if(!d.ok)return console.warn("fetchTelemetryWithStatus: non-OK response",d.status),{status:"server_error",code:d.status};const h=await d.json(),f=(u=h==null?void 0:h.results)==null?void 0:u[0];return!f||typeof f!="object"?{status:"empty"}:{status:"ok",data:f}}catch(d){return d.name==="AbortError"?(console.warn("fetchTelemetryWithStatus: timeout"),{status:"timeout"}):(console.warn("fetchTelemetryWithStatus: network error",d),{status:"timeout"})}finally{clearTimeout(l)}}function FEe(e){return!e||typeof e.last_interaction_at!="number"?0:e.last_interaction_at}function c9(){return Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,10)}function PEe(e,t){const r=new Map;for(const n of t)n.slug&&r.set(n.slug,n);return e.map(n=>{var o,s,l,u,d,h,f,p,g,A;const a=r.get(n.slug);if(!a)return n;const i={...n};if(!i.completed_at&&a.completed_at&&(i.completed_at=a.completed_at),!i.is_completed&&a.is_completed&&(i.is_completed=!0),!i.opened_at&&a.opened_at&&(i.opened_at=a.opened_at),(o=a.testeable_elements)!=null&&o.length){const m=new Map((i.testeable_elements??[]).map(v=>[v.hash,v])),y=[...i.testeable_elements??[]];for(const v of a.testeable_elements){const b=m.get(v.hash);if(!b)y.push(v);else if(v.is_completed&&!b.is_completed){const _=y.findIndex(x=>x.hash===v.hash);_!==-1&&(y[_]={...b,is_completed:!0,metrics:b.metrics??v.metrics})}}i.testeable_elements=y}if((s=a.quiz_submissions)!=null&&s.length){const m=new Set((i.quiz_submissions??[]).map(v=>v.quiz_hash)),y=a.quiz_submissions.filter(v=>!m.has(v.quiz_hash));y.length>0&&(i.quiz_submissions=[...i.quiz_submissions??[],...y])}return!((l=i.tests)!=null&&l.length)&&((u=a.tests)!=null&&u.length)&&(i.tests=[...a.tests]),!((d=i.compilations)!=null&&d.length)&&((h=a.compilations)!=null&&h.length)&&(i.compilations=[...a.compilations]),!((f=i.ai_interactions)!=null&&f.length)&&((p=a.ai_interactions)!=null&&p.length)&&(i.ai_interactions=[...a.ai_interactions]),!((g=i.sessions)!=null&&g.length)&&((A=a.sessions)!=null&&A.length)&&(i.sessions=[...a.sessions]),i})}function Swt(e,t,r,n,a,i){const o=!!e,s=t&&t.slug===n;if(o&&!s)return{telemetry:t0({...e},r,n,a,i),source:"server"};if(!o&&s)return{telemetry:t0({...t},r,n,a,i),source:"local"};if(o&&s){const u=FEe(e),d=FEe(t),[h,f,p]=d>u?[t,e,"local"]:[e,t,"server"],g=t0({...h},r,n,a,i);return g.steps=PEe(g.steps,f.steps??[]),{telemetry:g,source:p}}const l=Date.now();return{telemetry:t0({telemetry_id:c9(),slug:n,version:`${i}`,agent:a,tutorial_started_at:l,last_interaction_at:l,steps:r,workout_session:[{started_at:l}],fullname:"",cohort_id:null,academy_id:null},r,n,a,i),source:"new"}}function Twt(e,t,r){if(!e||!r)return;const n=r.trim();fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${n}`},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}const Lwt=async function(e,t,r){!e||!r||fetch(e,{method:"POST",body:JSON.stringify(t)}).then(n=>n).catch(n=>{console.log("Error while sending stream Telemetry",n)})},Nwt=async function(){try{return(await Ur.get(`${ha}/telemetry`)).data}catch(e){return console.error("Error while retrieving telemetry from CLI",e),null}},Mwt=async function(e){try{const t=await Ur.post(`${ha}/telemetry`,e);return console.debug("Saved telemetry in CLI",t.data),t.data}catch(t){return console.error("Error while saving telemetry in CLI",t),null}};function Vce(e){if(typeof e!="string")throw new TypeError("Input must be a string");return btoa(encodeURIComponent(e))}const Iwt=(e,t)=>{let r={...t};return typeof r.starting_at<"u"&&typeof r.started_at>"u"&&(r.started_at=r.starting_at,delete r.starting_at),typeof r.ending_at<"u"&&typeof r.ended_at>"u"&&(r.ended_at=r.ending_at,delete r.ending_at),typeof r.started_at>"u"&&e!=="open_step"&&(r.started_at=Date.now()),typeof r.ended_at>"u"&&e!=="open_step"&&(r.ended_at=Date.now()),r.source_code&&(r.source_code=Vce(r.source_code)),r.stdout&&(r.stdout=Vce(r.stdout)),r.stderr&&(r.stderr=Vce(r.stderr)),Object.prototype.hasOwnProperty.call(r,"exitCode")&&(r.exit_code=r.exitCode,r.exitCode=void 0),r},Rwt=["telemetry_id","user_id","fullname","slug","package_id","version","cohort_id","academy_id","agent","tutorial_started_at","last_interaction_at","steps","workout_session","global_metrics","global_indicators"];function $Ee(e){return e==null||typeof e=="string"&&e.trim()===""?null:typeof e=="number"&&!Number.isNaN(e)?String(e):typeof e=="string"?e:null}function Bwt(e,t){if(!Array.isArray(e))return[{started_at:t}];if(e.length===0)return[{started_at:t}];const r=e.filter(n=>!!n&&typeof n=="object"&&typeof n.started_at=="number");return r.length===0?[{started_at:t}]:r}function Owt(e,t){const r=new Map;for(const n of t)n.slug&&r.set(n.slug,n);return e.map(n=>{const a=r.get(n.slug);return a?{slug:n.slug,position:n.position,files:n.files,is_testeable:n.is_testeable,compilations:a.compilations??[],tests:a.tests??[],ai_interactions:a.ai_interactions??[],quiz_submissions:a.quiz_submissions??[],testeable_elements:a.testeable_elements??[],is_completed:a.is_completed??!1,completed_at:a.completed_at,opened_at:a.opened_at,sessions:a.sessions??[]}:n})}function t0(e,t,r,n,a){const i=e,o={};for(const g of Rwt)Object.prototype.hasOwnProperty.call(i,g)&&(o[g]=i[g]);const s=Date.now(),l=r,u=typeof o.version=="string"&&o.version.trim()!==""?o.version:`${a}`,d=typeof o.tutorial_started_at=="number"?o.tutorial_started_at:s,h=typeof o.last_interaction_at=="number"?o.last_interaction_at:s,f=Array.isArray(o.steps)&&o.steps.length>0?Owt(t,o.steps):t,p=Bwt(o.workout_session,s);return{telemetry_id:o.telemetry_id,user_id:o.user_id,fullname:o.fullname,slug:l,package_id:o.package_id,version:u,cohort_id:$Ee(o.cohort_id),academy_id:$Ee(o.academy_id),agent:typeof o.agent=="string"?o.agent:n,tutorial_started_at:d,last_interaction_at:h,steps:f,workout_session:p,global_metrics:o.global_metrics,global_indicators:o.global_indicators}}function UEe(e,t){e.telemetry_id||(e.telemetry_id=c9());const r=Uv(e),n=e.steps.map((a,i)=>{const o=e.telemetry_id||c9();return{...a,telemetry_id:o,metrics:r.steps[i].metrics,indicators:r.steps[i].indicators}});return{...e,steps:n,global_metrics:r.global.metrics,global_indicators:r.global.indicators,user_id:t}}const gr={current:null,urls:{},telemetryKey:"",packageAssetIds:[],listeners:{},agent:"cloud",prevStep:void 0,prevStepStartedAt:void 0,activeHashes:new Map,_lessonRenderedDebounce:null,user:{token:"",rigo_token:"",id:"",fullname:""},tutorialSlug:"",started:!1,reconciling:!1,version:`${OEe.version}`||"CLOUD:0.0.0",salute:e=>{console.log(e)},start:function(e,t,r,n,a,i){return this.activeHashes=new Map,this.packageAssetIds=[],this.telemetryKey=n,this.tutorialSlug=r,this.agent=e,this.user.id=a.user_id,this.user.token=a.token,this.user.rigo_token=a.rigo_token,this.user.fullname=a.fullname,this.current?Promise.resolve():e==="cloud"?(this.reconciling=!0,(async()=>{var s;let o=!1;try{const l=Hr.get(this.telemetryKey),u=String(l==null?void 0:l.user_id)===String(a==null?void 0:a.user_id),d=l&&l.slug===r&&u?l:null,h=!!((s=a.rigo_token)!=null&&s.trim()&&r),f=i!==void 0,[p,g]=await Promise.all([f?Promise.resolve(i):a.rigo_token&&a.user_id?DEe({userId:a.user_id,packageSlug:r,rigoToken:a.rigo_token}):Promise.resolve(null),h?qce(a.rigo_token,r):Promise.resolve({id:null,assetIds:[]})]);this.packageAssetIds=g.assetIds;const{telemetry:A,source:m}=Swt(p,d,t,r,e,this.version);if(this.current=A,this.current.user_id=a.user_id,this.current.fullname=a.fullname,this.current.cohort_id=a.cohort_id||null,this.current.academy_id=a.academy_id||null,this.current.version||(this.current.version=`CLOUD:${this.version}`),g.id!=null&&this.mergePackageIdIfMissing(g.id),this.finishWorkoutSession(),this.save(),this.started=!0,!a.user_id){console.warn("No user ID found, impossible to submit telemetry at start");return}o=m==="local"}catch(l){throw console.log("ERROR: There was a problem starting the Telemetry"),console.error(l),new Error(`There was a problem starting, reload LearnPack
|
|
756
|
+
`,n+1)}return r}function iwt(e,t){var r=IEe.exec(e);if(!r)return{attributes:{},body:e,bodyBegin:1};var n=t?MEe.load:MEe.safeLoad,a=r[r.length-1].replace(/^\s+|\s+$/g,""),i=n(a)||{},o=e.replace(r[0],""),s=awt(r,e);return{attributes:i,body:o,bodyBegin:s,frontmatter:a}}function owt(e){return e=e||"",IEe.test(e)}var swt=Nce.exports;const REe=Ta(swt),lwt=1;class cwt{constructor(){mr(this,"name","engagement_indicator")}calculateStepIndicator(t,r){return r.status!=="skipped"&&r.status!=="unread"?Math.min(r.time_spent/3600*100,100):0}calculateGlobalIndicator(t,r){const n={total_time:.3,num_sessions:.2,completion_rate:.3,interactions:.2},a=Math.min(r.total_time_on_platform/36e3,1)*100,i=Math.min(r.num_sessions/5,1)*100,o=r.completion_rate,s=Math.min(r.total_interactions/100,1)*100;return(a*n.total_time+i*n.num_sessions+o*n.completion_rate+s*n.interactions)/100*100}}class uwt{constructor(){mr(this,"name","frustration_indicator")}calculateStepIndicator(t,r){return r.status==="completed"?Math.min((r.comp_struggles+r.test_struggles)/20*100,100):r.status==="attempted"?Math.min(r.time_spent/1800*100,100):r.status==="skipped"?25:0}calculateGlobalIndicator(t,r){const n={steps_not_completed:.3,time_on_incomplete:.2,avg_comp_struggles:.2,avg_test_struggles:.2,skipped_steps:.1},a=r.total_steps>0?r.steps_not_completed/r.total_steps*100:0,i=Math.min(r.time_on_incomplete/18e3,1)*100,o=Math.min(r.avg_comp_struggles/10,1)*100,s=Math.min(r.avg_test_struggles/10,1)*100,l=r.total_steps>0?r.skipped_steps/r.total_steps*100:0;return(a*n.steps_not_completed+i*n.time_on_incomplete+o*n.avg_comp_struggles+s*n.avg_test_struggles+l*n.skipped_steps)/100*100}}function BEe(e){var x,w,C,S,T,N,M,B,D,I,O,F,P,R,U,$;let t=0;e.sessions&&e.sessions.length>0&&(t=e.sessions.reduce((z,q)=>z+q,0));let r=t;!t&&e.completed_at&&e.opened_at&&(r=e.completed_at-e.opened_at,t=r);let n=e.completed_at?"completed":e.opened_at?"attempted":"unread";const a=((x=e.compilations)==null?void 0:x.filter(z=>z.exit_code!==0).length)||0,i=((w=e.compilations)==null?void 0:w.filter(z=>z.exit_code===0).length)||0,o=((C=e.tests)==null?void 0:C.filter(z=>z.exit_code!==0).length)||0,s=((S=e.tests)==null?void 0:S.filter(z=>z.exit_code===0).length)||0,l=((T=e.quiz_submissions)==null?void 0:T.filter(z=>z.status==="ERROR").length)||0,u=((N=e.quiz_submissions)==null?void 0:N.filter(z=>z.status==="SUCCESS").length)||0;let d=0,h=0;for(let z=((M=e.compilations)==null?void 0:M.length)-1;z>=0&&e.compilations[z].exit_code!==0;z--)d++;for(let z=((B=e.compilations)==null?void 0:B.length)-1;z>=0&&e.compilations[z].exit_code===0;z--)h++;let f=0,p=0;for(let z=((D=e.tests)==null?void 0:D.length)-1;z>=0&&e.tests[z].exit_code!==0;z--)f++;for(let z=((I=e.tests)==null?void 0:I.length)-1;z>=0&&e.tests[z].exit_code===0;z--)p++;let g=0,A=0;for(let z=((O=e.quiz_submissions)==null?void 0:O.length)-1;z>=0&&e.quiz_submissions[z].status==="ERROR";z--)g++;for(let z=((F=e.quiz_submissions)==null?void 0:F.length)-1;z>=0&&e.quiz_submissions[z].status==="SUCCESS";z--)A++;const m=e.is_testeable||e.testeable_elements&&e.testeable_elements.length>0,y=(((P=e.quiz_submissions)==null?void 0:P.length)||0)===0&&(((R=e.tests)==null?void 0:R.length)||0)===0&&(((U=e.compilations)==null?void 0:U.length)||0)===0,v=!!m&&y,b=(($=e.ai_interactions)==null?void 0:$.length)||0,_=a+o+l>0&&i+s+u===0;return{status:n,time_spent:r,total_duration:t,comp_struggles:a,comp_success:i,total_comp_attempts:i+a,test_struggles:o,test_success:s,total_test_attempts:s+o,quiz_struggles:l,quiz_success:u,total_quiz_attempts:u+l,streak_comp_struggles:d,streak_comp_success:h,streak_test_struggle:f,streak_test_success:p,streak_quiz_struggles:g,streak_quiz_success:A,user_skipped:v,total_ai_interactions:b,ai_used:b>0,is_abandoned:_}}function dwt(e){const t=e.length,r=e.map(BEe),n=r.filter(g=>g.status==="completed").length,a=r.filter(g=>g.status==="attempted").length,i=r.filter(g=>g.status==="skipped").length,o=r.filter(g=>g.status==="unread").length,s=t?n/t*100:0,l=e.reduce((g,A)=>{var m,y,v,b;return g+(((m=A.compilations)==null?void 0:m.length)||0)+(((y=A.tests)==null?void 0:y.length)||0)+(((v=A.quiz_submissions)==null?void 0:v.length)||0)+(((b=A.ai_interactions)==null?void 0:b.length)||0)},0),u=r.reduce((g,A)=>g+A.time_spent,0),d=a+i+o,h=t?r.reduce((g,A)=>g+A.comp_struggles,0)/t:0,f=t?r.reduce((g,A)=>g+A.test_struggles,0)/t:0;let p=0;for(const g of e){let A=0;for(const m of g.tests||[])m.exit_code===0?A++:A=0,p=Math.max(p,A)}return{total_time_on_platform:u,num_sessions:1,completion_rate:s,total_interactions:l,steps_not_completed:d,time_on_incomplete:u,avg_comp_struggles:h,avg_test_struggles:f,skipped_steps:i,total_steps:t,global_test_success_streak:p}}function Uv(e){const t=[new cwt,new uwt],r=e.steps.map(o=>BEe(o)),n=dwt(e.steps),a=e.steps.map((o,s)=>{const l=r[s],u={engagement_indicator:0,frustration_indicator:0};return t.forEach(d=>{u[d.name]=d.calculateStepIndicator(o,l)}),{slug:o.slug,metrics:l,indicators:u}}),i={engagement_indicator:0,frustration_indicator:0};return t.forEach(o=>{i[o.name]=o.calculateGlobalIndicator(a.map(s=>s.indicators[o.name]),n)}),{algo_version:lwt,global:{metrics:n,indicators:i},steps:a}}function hwt(e,t){var d,h,f,p;if(!e.testeable_elements)return;const r=e.testeable_elements.find(g=>g.hash===t);if(!r)return;const n=r.type==="quiz"?((d=e.quiz_submissions.find(g=>g.quiz_hash===t))==null?void 0:d.ended_at)||e.opened_at||0:((h=e.tests.shift())==null?void 0:h.started_at)||e.opened_at||0,a=r.type==="quiz"?((f=e.quiz_submissions.findLast(g=>g.quiz_hash===t))==null?void 0:f.ended_at)||e.completed_at||1:((p=e.tests.shift())==null?void 0:p.started_at)||e.completed_at||1,i=Number((a-n)/1e3),o=e.ai_interactions.filter(g=>g.started_at>=n&&g.ended_at<=a).length,s=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t).length:e.tests.length,l=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t&&g.status==="ERROR").length:e.tests.filter(g=>g.exit_code!==1).length,u=r.type==="quiz"?e.quiz_submissions.filter(g=>g.quiz_hash===t&&g.status==="SUCCESS").length:e.tests.filter(g=>g.exit_code===1).length;return{started_at:n,ended_at:a,resolution_time_seconds:i,n_ai_interactions:o,n_tries:s,n_fail:l,n_success:u}}const OEe={name:"learnpack-ai",private:!0,version:"5.0.400",scripts:{dev:"node src/utils/development.js --turn on && vite",build:"node src/utils/development.js --turn off && tsc && vite build && node src/utils/uploadLearnpack.js && node bin/publish.js && node src/utils/createVersionsFile.js ","dev-build":"node src/utils/development.js --turn on && tsc && vite build",lint:"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",preview:"vite preview",watch:"vite build --watch","compile-command":"tsc src/utils/development.ts && node src/utils/development.js --turn on"},dependencies:{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@monaco-editor/react":"^4.6.0","@radix-ui/react-tooltip":"^1.2.8",axios:"^1.7.7","class-variance-authority":"^0.7.1",clsx:"^2.1.1",dompurify:"^3.3.0","front-matter":"^4.0.2","highlight.js":"^11.11.1",html2canvas:"^1.4.1",i18next:"^23.10.1","js-yaml":"^4.1.0","lucide-react":"^0.545.0",mermaid:"^11.6.0",mitt:"^3.0.1","monaco-editor":"^0.50.0","prompt-sync":"^4.2.0","pusher-js":"7.6.0","radix-ui":"^1.4.3",react:"^18.2.0","react-dom":"^18.2.0","react-draggable":"^4.4.6","react-gtm-module":"^2.0.11","react-hot-toast":"^2.4.1","react-i18next":"^14.1.0","react-markdown":"^9.0.1","react-monaco-editor":"^0.56.1","react-router-dom":"^6.27.0","react-syntax-highlighter":"^15.6.1","rehype-katex":"^7.0.1","remark-emoji":"^5.0.1","remark-gfm":"^4.0.0","remark-math":"^6.0.0","socket.io":"^4.7.2","socket.io-client":"^4.7.2","tailwind-merge":"^3.3.1","tailwindcss-animate":"^1.0.7",uuid:"^10.0.0",zustand:"^4.4.1"},devDependencies:{"@aws-sdk/client-cloudfront":"^3.840.0","@aws-sdk/client-s3":"^3.709.0","@types/dompurify":"^3.0.5","@types/js-yaml":"^4.0.9","@types/markdown-it":"^14.1.2","@types/node":"^24.9.1","@types/react":"^18.2.15","@types/react-dom":"^18.2.7","@types/react-gtm-module":"^2.0.3","@types/react-syntax-highlighter":"^15.5.13","@types/remarkable":"^2.0.3","@types/uuid":"^10.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","@vitejs/plugin-react-swc":"^3.3.2",archiver:"^6.0.1",autoprefixer:"^10.4.21",dotenv:"^16.4.7",eslint:"^8.45.0","eslint-plugin-react-hooks":"^4.6.0","eslint-plugin-react-refresh":"^0.4.3",inquirer:"^9.2.12",postcss:"^8.5.6",tailwindcss:"^3.4.18",typescript:"^5.0.2",vite:"^4.5.13"}};function fwt(e){return{all:e=e||new Map,on:function(t,r){var n=e.get(t);n?n.push(r):e.set(t,[r])},off:function(t,r){var n=e.get(t);n&&(r?n.splice(n.indexOf(r)>>>0,1):e.set(t,[]))},emit:function(t,r){var n=e.get(t);n&&n.slice().map(function(a){a(r)}),(n=e.get("*"))&&n.slice().map(function(a){a(t,r)})}}}const zr=fwt(),Hce=async(e,t)=>{if(!t)throw new Error("Slug is required");const r=`${ui}/v1/learnpack/session/?slug=${t}`;try{return(await Ur.get(r,{headers:{Authorization:`Token ${e}`}})).data}catch(n){throw console.error("Error fetching session:",n),n}},jce=async(e,t,r,n,a)=>{const i=`${ui}/v1/learnpack/session/${a}/`,o={tab_hash:t,config_json:n,package_slug:r};try{return(await Ur.put(i,o,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}})).data}catch(s){throw console.error("Error updating session:",s),s}},pwt=async(e,t,r,n)=>{const a=`${ui}/v1/learnpack/session/`,i={tab_hash:t,config_json:n,package_slug:r};try{return(await Ur.post(a,i,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}})).data}catch(o){throw console.error("Error creating session:",o),o}};async function gwt(e){const t=`${Lv}/v1/payments/me/service/consumable?virtual=true`,r={Authorization:`Token ${e}`};try{return(await Ur.get(t,{headers:r})).data}catch(n){throw console.error("Error fetching consumables:",n),n}}async function Awt(e,t="ai-conversation-message"){const r=`${Lv}/v1/payments/me/service/${t}/consumptionsession`,n={Authorization:`Token ${e}`};try{const a=await Ur.put(r,{},{headers:n});return a.status>=200&&a.status<300?(console.log(a.data),console.log(`Successfully consumed ${t}`),!0):(console.error(`Request failed with status code: ${a.status}`),console.error(`Response: ${a.data}`),!1)}catch(a){return console.error(`Error consuming ${t}:`,a),!1}}function mwt(e){if(!Array.isArray(e))return[];const t=[];for(const r of e){const n=typeof r=="number"?r:Number(r);Number.isFinite(n)&&t.push(n)}return t}async function qce(e,t){var a;const r={id:null,assetIds:[]};if(!(e!=null&&e.trim())||!t)return r;const n=`${ui}/v1/learnpack/package/${encodeURIComponent(t)}/assets/`;try{const o=(await Ur.get(n,{headers:{Authorization:`Token ${e.trim()}`}})).data;return{id:(o==null?void 0:o.id)!=null?String(o.id):null,assetIds:mwt(o==null?void 0:o.asset_ids)}}catch(i){return Ur.isAxiosError(i)&&((a=i.response)==null?void 0:a.status)===404||console.warn("fetchLearnpackPackageInfo failed:",i),r}}const ywt=async(e,t)=>{var a;const r=`${ui}/v1/learnpack/package/${t}/`;console.log("Checking if package is author",r,e);const n={Authorization:`Token ${e}`};try{const i=await Ur.get(r,{headers:n});return{isAuthor:i.status===200,status:i.status}}catch(i){const o=((a=i==null?void 0:i.response)==null?void 0:a.status)||500;return console.error("Error fetching package:",i),{isAuthor:!1,status:o}}},vwt=async(e,t,r=ui)=>{const n=await Ur.get(`${r}/v1/prompting/completion/${t}/`,{headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"}});return console.log("RigoBot completion response:",n.data),n.data};function bwt(e,t){if(t.length===0)return e;const r=e.includes("?")?"&":"?";return`${e}${r}asset_id=${t.join(",")}`}const wwt=async function(e,t,r,n){if(!e||!r){console.error("URL and token are required");return}r=r.trim();const a={"Content-Type":"application/json",Authorization:`Token ${r}`},i=bwt(e,n??[]);try{return(await Ur.post(i,t,{headers:a})).data}catch(o){throw console.error("Error while sending batch telemetry",o),Ur.isAxiosError(o)&&o.response&&(console.error("Response data:",o.response.data),console.error("Response status:",o.response.status),console.error("Response headers:",o.response.headers)),o}},kwt=async function(e,t){const r=`${ui}/v1/learnpack/telemetry`,n={"Content-Type":"application/json",Authorization:`Token ${t}`};try{return(await Ur.post(r,e,{headers:n})).data}catch(a){throw console.error("Error while sending batch telemetry",a),a}},xwt=5e3,_wt=6e4,Cwt=5*60*1e3;async function DEe(e){var u;const{userId:t,packageSlug:r,rigoToken:n}=e;if(!t||!n||!r)return null;const a=n.trim(),i=new URLSearchParams;i.set("user_ids",String(t)),i.set("include_buffer","true"),i.set("include_steps","true"),i.set("package_slug",r);const o=`${ui}/v1/learnpack/telemetry?${i.toString()}`,s=new AbortController,l=setTimeout(()=>s.abort(),xwt);try{const d=await fetch(o,{method:"GET",headers:{Authorization:`Token ${a}`,Accept:"application/json"},signal:s.signal});if(!d.ok)return console.warn("fetchTelemetryFromServer: non-OK response",d.status),null;const h=await d.json(),f=(u=h==null?void 0:h.results)==null?void 0:u[0];return!f||typeof f!="object"?null:f}catch(d){return d.name==="AbortError"?console.warn("fetchTelemetryFromServer: timeout or aborted"):console.warn("fetchTelemetryFromServer: failed",d),null}finally{clearTimeout(l)}}async function Ewt(e){var u;const{userId:t,packageSlug:r,rigoToken:n}=e;if(!t||!n||!r)return{status:"empty"};const a=n.trim(),i=new URLSearchParams;i.set("user_ids",String(t)),i.set("include_buffer","true"),i.set("include_steps","true"),i.set("package_slug",r);const o=`${ui}/v1/learnpack/telemetry?${i.toString()}`,s=new AbortController,l=setTimeout(()=>s.abort(),_wt);try{const d=await fetch(o,{method:"GET",headers:{Authorization:`Token ${a}`,Accept:"application/json"},signal:s.signal});if(!d.ok)return console.warn("fetchTelemetryWithStatus: non-OK response",d.status),{status:"server_error",code:d.status};const h=await d.json(),f=(u=h==null?void 0:h.results)==null?void 0:u[0];return!f||typeof f!="object"?{status:"empty"}:{status:"ok",data:f}}catch(d){return d.name==="AbortError"?(console.warn("fetchTelemetryWithStatus: timeout"),{status:"timeout"}):(console.warn("fetchTelemetryWithStatus: network error",d),{status:"timeout"})}finally{clearTimeout(l)}}function FEe(e){return!e||typeof e.last_interaction_at!="number"?0:e.last_interaction_at}function c9(){return Math.random().toString(36).slice(2,10)+Math.random().toString(36).slice(2,10)}function PEe(e,t){const r=new Map;for(const n of t)n.slug&&r.set(n.slug,n);return e.map(n=>{var o,s,l,u,d,h,f,p,g,A;const a=r.get(n.slug);if(!a)return n;const i={...n};if(!i.completed_at&&a.completed_at&&(i.completed_at=a.completed_at),!i.is_completed&&a.is_completed&&(i.is_completed=!0),!i.opened_at&&a.opened_at&&(i.opened_at=a.opened_at),(o=a.testeable_elements)!=null&&o.length){const m=new Map((i.testeable_elements??[]).map(v=>[v.hash,v])),y=[...i.testeable_elements??[]];for(const v of a.testeable_elements){const b=m.get(v.hash);if(!b)y.push(v);else if(v.is_completed&&!b.is_completed){const _=y.findIndex(x=>x.hash===v.hash);_!==-1&&(y[_]={...b,is_completed:!0,metrics:b.metrics??v.metrics})}}i.testeable_elements=y}if((s=a.quiz_submissions)!=null&&s.length){const m=new Set((i.quiz_submissions??[]).map(v=>v.quiz_hash)),y=a.quiz_submissions.filter(v=>!m.has(v.quiz_hash));y.length>0&&(i.quiz_submissions=[...i.quiz_submissions??[],...y])}return!((l=i.tests)!=null&&l.length)&&((u=a.tests)!=null&&u.length)&&(i.tests=[...a.tests]),!((d=i.compilations)!=null&&d.length)&&((h=a.compilations)!=null&&h.length)&&(i.compilations=[...a.compilations]),!((f=i.ai_interactions)!=null&&f.length)&&((p=a.ai_interactions)!=null&&p.length)&&(i.ai_interactions=[...a.ai_interactions]),!((g=i.sessions)!=null&&g.length)&&((A=a.sessions)!=null&&A.length)&&(i.sessions=[...a.sessions]),i})}function Swt(e,t,r,n,a,i){const o=!!e,s=t&&t.slug===n;if(o&&!s)return{telemetry:t0({...e},r,n,a,i),source:"server"};if(!o&&s)return{telemetry:t0({...t},r,n,a,i),source:"local"};if(o&&s){const u=FEe(e),d=FEe(t),[h,f,p]=d>u?[t,e,"local"]:[e,t,"server"],g=t0({...h},r,n,a,i);return g.steps=PEe(g.steps,f.steps??[]),{telemetry:g,source:p}}const l=Date.now();return{telemetry:t0({telemetry_id:c9(),slug:n,version:`${i}`,agent:a,tutorial_started_at:l,last_interaction_at:l,steps:r,workout_session:[{started_at:l}],fullname:"",cohort_id:null,academy_id:null},r,n,a,i),source:"new"}}function Twt(e,t,r){if(!e||!r)return;const n=r.trim();fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${n}`},body:JSON.stringify(t),keepalive:!0}).catch(()=>{})}const Lwt=async function(e,t,r){!e||!r||fetch(e,{method:"POST",body:JSON.stringify(t)}).then(n=>n).catch(n=>{console.log("Error while sending stream Telemetry",n)})},Nwt=async function(){try{return(await Ur.get(`${ha}/telemetry`)).data}catch(e){return console.error("Error while retrieving telemetry from CLI",e),null}},Mwt=async function(e){try{const t=await Ur.post(`${ha}/telemetry`,e);return console.debug("Saved telemetry in CLI",t.data),t.data}catch(t){return console.error("Error while saving telemetry in CLI",t),null}};function Vce(e){if(typeof e!="string")throw new TypeError("Input must be a string");return btoa(encodeURIComponent(e))}const Iwt=(e,t)=>{let r={...t};return typeof r.starting_at<"u"&&typeof r.started_at>"u"&&(r.started_at=r.starting_at,delete r.starting_at),typeof r.ending_at<"u"&&typeof r.ended_at>"u"&&(r.ended_at=r.ending_at,delete r.ending_at),typeof r.started_at>"u"&&e!=="open_step"&&(r.started_at=Date.now()),typeof r.ended_at>"u"&&e!=="open_step"&&(r.ended_at=Date.now()),r.source_code&&(r.source_code=Vce(r.source_code)),r.stdout&&(r.stdout=Vce(r.stdout)),r.stderr&&(r.stderr=Vce(r.stderr)),Object.prototype.hasOwnProperty.call(r,"exitCode")&&(r.exit_code=r.exitCode,r.exitCode=void 0),r},Rwt=["telemetry_id","user_id","fullname","slug","package_id","version","cohort_id","academy_id","agent","tutorial_started_at","last_interaction_at","steps","workout_session","global_metrics","global_indicators"];function $Ee(e){return e==null||typeof e=="string"&&e.trim()===""?null:typeof e=="number"&&!Number.isNaN(e)?String(e):typeof e=="string"?e:null}function Bwt(e,t){if(!Array.isArray(e))return[{started_at:t}];if(e.length===0)return[{started_at:t}];const r=e.filter(n=>!!n&&typeof n=="object"&&typeof n.started_at=="number");return r.length===0?[{started_at:t}]:r}function Owt(e,t){const r=new Map;for(const n of t)n.slug&&r.set(n.slug,n);return e.map(n=>{const a=r.get(n.slug);return a?{slug:n.slug,position:n.position,files:n.files,is_testeable:n.is_testeable,compilations:a.compilations??[],tests:a.tests??[],ai_interactions:a.ai_interactions??[],quiz_submissions:a.quiz_submissions??[],testeable_elements:a.testeable_elements??[],is_completed:a.is_completed??!1,completed_at:a.completed_at,opened_at:a.opened_at,sessions:a.sessions??[]}:n})}function t0(e,t,r,n,a){const i=e,o={};for(const g of Rwt)Object.prototype.hasOwnProperty.call(i,g)&&(o[g]=i[g]);const s=Date.now(),l=r,u=typeof o.version=="string"&&o.version.trim()!==""?o.version:`${a}`,d=typeof o.tutorial_started_at=="number"?o.tutorial_started_at:s,h=typeof o.last_interaction_at=="number"?o.last_interaction_at:s,f=Array.isArray(o.steps)&&o.steps.length>0?Owt(t,o.steps):t,p=Bwt(o.workout_session,s);return{telemetry_id:o.telemetry_id,user_id:o.user_id,fullname:o.fullname,slug:l,package_id:o.package_id,version:u,cohort_id:$Ee(o.cohort_id),academy_id:$Ee(o.academy_id),agent:typeof o.agent=="string"?o.agent:n,tutorial_started_at:d,last_interaction_at:h,steps:f,workout_session:p,global_metrics:o.global_metrics,global_indicators:o.global_indicators}}function UEe(e,t){e.telemetry_id||(e.telemetry_id=c9());const r=Uv(e),n=e.steps.map((a,i)=>{const o=e.telemetry_id||c9();return{...a,telemetry_id:o,metrics:r.steps[i].metrics,indicators:r.steps[i].indicators}});return{...e,steps:n,global_metrics:r.global.metrics,global_indicators:r.global.indicators,user_id:t}}const gr={current:null,urls:{},telemetryKey:"",packageAssetIds:[],listeners:{},agent:"cloud",prevStep:void 0,prevStepStartedAt:void 0,activeHashes:new Map,_lessonRenderedDebounce:null,user:{token:"",rigo_token:"",id:"",fullname:""},tutorialSlug:"",started:!1,reconciling:!1,version:`${OEe.version}`||"CLOUD:0.0.0",salute:e=>{console.log(e)},start:function(e,t,r,n,a,i){return this.activeHashes=new Map,this.packageAssetIds=[],this.telemetryKey=n,this.tutorialSlug=r,this.agent=e,this.user.id=a.user_id,this.user.token=a.token,this.user.rigo_token=a.rigo_token,this.user.fullname=a.fullname,this.current?Promise.resolve():e==="cloud"?(this.reconciling=!0,(async()=>{var s;let o=!1;try{const l=Hr.get(this.telemetryKey),u=String(l==null?void 0:l.user_id)===String(a==null?void 0:a.user_id),d=l&&l.slug===r&&u?l:null,h=!!((s=a.rigo_token)!=null&&s.trim()&&r),f=i!==void 0,[p,g]=await Promise.all([f?Promise.resolve(i):a.rigo_token&&a.user_id?DEe({userId:a.user_id,packageSlug:r,rigoToken:a.rigo_token}):Promise.resolve(null),h?qce(a.rigo_token,r):Promise.resolve({id:null,assetIds:[]})]);this.packageAssetIds=g.assetIds;const{telemetry:A,source:m}=Swt(p,d,t,r,e,this.version);if(this.current=A,this.current.user_id=a.user_id,this.current.fullname=a.fullname,this.current.cohort_id=a.cohort_id||null,this.current.academy_id=a.academy_id||null,this.current.version||(this.current.version=`CLOUD:${this.version}`),g.id!=null&&this.mergePackageIdIfMissing(g.id),this.finishWorkoutSession(),this.save(),this.started=!0,!a.user_id){console.warn("No user ID found, impossible to submit telemetry at start");return}o=m==="local"}catch(l){throw console.log("ERROR: There was a problem starting the Telemetry"),console.error(l),new Error(`There was a problem starting, reload LearnPack
|
|
757
757
|
Run
|
|
758
758
|
$ learnpack start`)}finally{this.reconciling=!1}o&&a.user_id&&await this.submit()})()):this.retrieve().then(async o=>{var s;if(o?(this.current=t0(o,t,r,e,this.version),this.finishWorkoutSession()):(console.debug("No previous telemetry found, creating new one. Agent: ",e),this.current=t0({telemetry_id:c9(),slug:r,version:`${this.version}`,agent:e,tutorial_started_at:Date.now(),last_interaction_at:Date.now(),steps:t,workout_session:[{started_at:Date.now()}],fullname:this.user.fullname,cohort_id:null,academy_id:null},t,r,e,this.version)),this.current.user_id=this.user.id,this.current.fullname=this.user.fullname,this.current.cohort_id=a.cohort_id||null,this.current.academy_id=a.academy_id||null,this.current.version||(this.current.version=`CLOUD:${this.version}`),this.save(),this.started=!0,!this.user.id){console.warn("No user ID found, impossible to submit telemetry at start");return}if((s=this.user.rigo_token)!=null&&s.trim()&&r){const l=await qce(this.user.rigo_token,r);this.packageAssetIds=l.assetIds,l.id!=null&&this.mergePackageIdIfMissing(l.id)}await this.submit()}).catch(o=>{throw console.log("ERROR: There was a problem starting the Telemetry"),console.error(o),new Error(`There was a problem starting, reload LearnPack
|
|
759
759
|
Run
|
package/src/ui/app.tar.gz
CHANGED
|
Binary file
|
|
@@ -8,8 +8,6 @@ This directory contains utilities for exporting courses to different formats.
|
|
|
8
8
|
- **ZIP**: Full course mirror from GCS (includes `.learn/package-manifest.json`)
|
|
9
9
|
- **EPUB**: E-book format for offline reading (does not include `package-manifest.json`)
|
|
10
10
|
|
|
11
|
-
`package-manifest.json` is regenerated on each ZIP/SCORM export with `publishedAt: null`. See [`docs/package-manifest.md`](../../../../docs/package-manifest.md) in the monorepo.
|
|
12
|
-
|
|
13
11
|
## Usage
|
|
14
12
|
|
|
15
13
|
### API Endpoints
|
|
@@ -22,6 +22,7 @@ export type PackageManifestLesson = {
|
|
|
22
22
|
position: number;
|
|
23
23
|
type: LessonType;
|
|
24
24
|
title: Record<string, string>;
|
|
25
|
+
description: Record<string, string | null>;
|
|
25
26
|
video: Record<string, string | null>;
|
|
26
27
|
};
|
|
27
28
|
|
|
@@ -165,6 +166,19 @@ function resolveLessonTitle(
|
|
|
165
166
|
return titles
|
|
166
167
|
}
|
|
167
168
|
|
|
169
|
+
function resolveLessonDescriptions(
|
|
170
|
+
exercise: Exercise
|
|
171
|
+
): Record<string, string | null> {
|
|
172
|
+
const description: Record<string, string | null> = {}
|
|
173
|
+
|
|
174
|
+
for (const lang of Object.keys(exercise.translations)) {
|
|
175
|
+
// TODO: add description content
|
|
176
|
+
description[lang] = null
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return description
|
|
180
|
+
}
|
|
181
|
+
|
|
168
182
|
function resolveLessonVideos(
|
|
169
183
|
exercise: Exercise,
|
|
170
184
|
readmeFrontmatters: Record<string, Record<string, ReadmeFrontmatter>>
|
|
@@ -226,6 +240,7 @@ export function buildPackageManifestFromSources(
|
|
|
226
240
|
courseLang,
|
|
227
241
|
readmeFrontmatters[exercise.slug] ?? {}
|
|
228
242
|
),
|
|
243
|
+
description: resolveLessonDescriptions(exercise),
|
|
229
244
|
video: resolveLessonVideos(exercise, readmeFrontmatters),
|
|
230
245
|
}
|
|
231
246
|
})
|
|
@@ -263,6 +278,40 @@ async function downloadJsonFile<T>(
|
|
|
263
278
|
}
|
|
264
279
|
}
|
|
265
280
|
|
|
281
|
+
export function parseReadmeContent(content: string): ReadmeFrontmatter {
|
|
282
|
+
const parsed = frontMatter(content)
|
|
283
|
+
const attributes = parsed.attributes || {}
|
|
284
|
+
const h1 = extractReadmeH1(parsed.body || "")
|
|
285
|
+
const title = h1 ? normalizeReadmeTitle(h1) : null
|
|
286
|
+
return {
|
|
287
|
+
...(attributes.tutorial ? { tutorial: attributes.tutorial } : {}),
|
|
288
|
+
...(attributes.intro ? { intro: attributes.intro } : {}),
|
|
289
|
+
...(title ? { title } : {}),
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function comparePackageManifests(
|
|
294
|
+
existing: PackageManifest | null,
|
|
295
|
+
next: PackageManifest
|
|
296
|
+
): "created" | "updated" | "skipped" {
|
|
297
|
+
if (existing === null) {
|
|
298
|
+
return "created"
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const { generatedAt: _existingGeneratedAt, ...existingRest } = existing
|
|
302
|
+
const { generatedAt: _nextGeneratedAt, ...nextRest } = next
|
|
303
|
+
|
|
304
|
+
if (JSON.stringify(existingRest) === JSON.stringify(nextRest)) {
|
|
305
|
+
return "skipped"
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return "updated"
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export function serializePackageManifest(manifest: PackageManifest): string {
|
|
312
|
+
return JSON.stringify(manifest, null, 2)
|
|
313
|
+
}
|
|
314
|
+
|
|
266
315
|
async function readReadmeFrontmatter(
|
|
267
316
|
bucket: Bucket,
|
|
268
317
|
exerciseSlug: string,
|
|
@@ -275,18 +324,10 @@ async function readReadmeFrontmatter(
|
|
|
275
324
|
}> {
|
|
276
325
|
try {
|
|
277
326
|
const [buf] = await bucket.file(readmePath).download()
|
|
278
|
-
const parsed = frontMatter(buf.toString())
|
|
279
|
-
const attributes = parsed.attributes || {}
|
|
280
|
-
const h1 = extractReadmeH1(parsed.body || "")
|
|
281
|
-
const title = h1 ? normalizeReadmeTitle(h1) : null
|
|
282
327
|
return {
|
|
283
328
|
exerciseSlug,
|
|
284
329
|
lang,
|
|
285
|
-
frontmatter:
|
|
286
|
-
tutorial: attributes.tutorial,
|
|
287
|
-
intro: attributes.intro,
|
|
288
|
-
...(title ? { title } : {}),
|
|
289
|
-
},
|
|
330
|
+
frontmatter: parseReadmeContent(buf.toString()),
|
|
290
331
|
}
|
|
291
332
|
} catch (error) {
|
|
292
333
|
console.warn(
|
|
@@ -328,7 +369,7 @@ function writeManifestJson(
|
|
|
328
369
|
manifest: PackageManifest,
|
|
329
370
|
localDir?: string
|
|
330
371
|
): string {
|
|
331
|
-
const json =
|
|
372
|
+
const json = serializePackageManifest(manifest)
|
|
332
373
|
|
|
333
374
|
if (localDir) {
|
|
334
375
|
const learnDir = path.join(localDir, ".learn")
|