@vue-skuilder/platform-ui 0.2.34 → 0.2.35
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/dist/assets/{About-sUaZ0Srj.js → About-BWM7KlDK.js} +2 -2
- package/dist/assets/{About-sUaZ0Srj.js.map → About-BWM7KlDK.js.map} +1 -1
- package/dist/assets/{AdminDashboard-cKNlDTB2.js → AdminDashboard-CO2rxkF5.js} +2 -2
- package/dist/assets/{AdminDashboard-cKNlDTB2.js.map → AdminDashboard-CO2rxkF5.js.map} +1 -1
- package/dist/assets/{AdminLearner-DXeevw2h.js → AdminLearner-CZO2Hlk1.js} +2 -2
- package/dist/assets/{AdminLearner-DXeevw2h.js.map → AdminLearner-CZO2Hlk1.js.map} +1 -1
- package/dist/assets/{ClassroomCtrlPanel-BeSz_WX4.js → ClassroomCtrlPanel-cj6bokz5.js} +2 -2
- package/dist/assets/{ClassroomCtrlPanel-BeSz_WX4.js.map → ClassroomCtrlPanel-cj6bokz5.js.map} +1 -1
- package/dist/assets/{Classrooms-DTBqomQE.js → Classrooms-BIC1PGz0.js} +2 -2
- package/dist/assets/{Classrooms-DTBqomQE.js.map → Classrooms-BIC1PGz0.js.map} +1 -1
- package/dist/assets/{CourseRouter-CL8v2Zdk.js → CourseRouter-CMMxD9us.js} +2 -2
- package/dist/assets/{CourseRouter-CL8v2Zdk.js.map → CourseRouter-CMMxD9us.js.map} +1 -1
- package/dist/assets/{CourseWare-BTFRjgBR-C3GJRVef.js → CourseWare-BTFRjgBR-C3wi5YHa.js} +3 -3
- package/dist/assets/{CourseWare-BTFRjgBR-C3GJRVef.js.map → CourseWare-BTFRjgBR-C3wi5YHa.js.map} +1 -1
- package/dist/assets/{Courses-CUff-WLk.js → Courses-Dw7mgMnI.js} +2 -2
- package/dist/assets/{Courses-CUff-WLk.js.map → Courses-Dw7mgMnI.js.map} +1 -1
- package/dist/assets/{EloModeration-6MUDz-Mu.js → EloModeration-COgCrvb8.js} +2 -2
- package/dist/assets/{EloModeration-6MUDz-Mu.js.map → EloModeration-COgCrvb8.js.map} +1 -1
- package/dist/assets/{JoinCode-CW9Lk23D.js → JoinCode-Fu9Tks7r.js} +2 -2
- package/dist/assets/{JoinCode-CW9Lk23D.js.map → JoinCode-Fu9Tks7r.js.map} +1 -1
- package/dist/assets/{NewCourseDialog-CLm1rQyB.js → NewCourseDialog-C11dSwWM.js} +2 -2
- package/dist/assets/{NewCourseDialog-CLm1rQyB.js.map → NewCourseDialog-C11dSwWM.js.map} +1 -1
- package/dist/assets/{ReleaseNotes-CmITE6hd.js → ReleaseNotes-CeTkuF5d.js} +2 -2
- package/dist/assets/{ReleaseNotes-CmITE6hd.js.map → ReleaseNotes-CeTkuF5d.js.map} +1 -1
- package/dist/assets/{RequestPasswordReset-DPE6S2dU.js → RequestPasswordReset-vTzfGItp.js} +2 -2
- package/dist/assets/{RequestPasswordReset-DPE6S2dU.js.map → RequestPasswordReset-vTzfGItp.js.map} +1 -1
- package/dist/assets/{ResetPassword-Dl6nj4jF.js → ResetPassword-CmGaVYsI.js} +2 -2
- package/dist/assets/{ResetPassword-Dl6nj4jF.js.map → ResetPassword-CmGaVYsI.js.map} +1 -1
- package/dist/assets/{Study-Cf5yVLaY.js → Study-CkJvraIv.js} +2 -2
- package/dist/assets/{Study-Cf5yVLaY.js.map → Study-CkJvraIv.js.map} +1 -1
- package/dist/assets/{TagInformation-tqHJGkyw.js → TagInformation-xZcQ1C1t.js} +2 -2
- package/dist/assets/{TagInformation-tqHJGkyw.js.map → TagInformation-xZcQ1C1t.js.map} +1 -1
- package/dist/assets/{User-DCoA5JMB.js → User-MzKFSneO.js} +2 -2
- package/dist/assets/{User-DCoA5JMB.js.map → User-MzKFSneO.js.map} +1 -1
- package/dist/assets/{UserStats-B25DZy-D.js → UserStats-CioNBbmL.js} +2 -2
- package/dist/assets/{UserStats-B25DZy-D.js.map → UserStats-CioNBbmL.js.map} +1 -1
- package/dist/assets/{VerifyEmail-DyWRQweA.js → VerifyEmail-Bh-T9191.js} +2 -2
- package/dist/assets/{VerifyEmail-DyWRQweA.js.map → VerifyEmail-Bh-T9191.js.map} +1 -1
- package/dist/assets/{admin-Cfzt4Vei.css → admin-CMwKoROX.css} +1 -1
- package/dist/assets/admin-Dt07rW2C.js +21 -0
- package/dist/assets/admin-Dt07rW2C.js.map +1 -0
- package/dist/assets/{chess-E2uOAyQS-CP3XwSpG.js → chess-E2uOAyQS-C8213VIQ.js} +2 -2
- package/dist/assets/{chess-E2uOAyQS-CP3XwSpG.js.map → chess-E2uOAyQS-C8213VIQ.js.map} +1 -1
- package/dist/assets/chess-Lfm7Fsvs-6ElY3d5h.js +1 -0
- package/dist/assets/{common-ui.es-te1li8kU.js → common-ui.es-B9r6QiWN.js} +4 -4
- package/dist/assets/{common-ui.es-te1li8kU.js.map → common-ui.es-B9r6QiWN.js.map} +1 -1
- package/dist/assets/{common-ui.es-DHzI_ZVr.js → common-ui.es-j6sezLNk.js} +1 -1
- package/dist/assets/{dist-BnMJdH50.js → dist-BeppzTWu.js} +2 -2
- package/dist/assets/{dist-BnMJdH50.js.map → dist-BeppzTWu.js.map} +1 -1
- package/dist/assets/dist-C1hpwy00.js +1 -0
- package/dist/assets/{dist-CtnPlm6M.js → dist-CKO_fXB-.js} +3 -3
- package/dist/assets/{dist-CtnPlm6M.js.map → dist-CKO_fXB-.js.map} +1 -1
- package/dist/assets/dist-CkRURFlm.js +1 -0
- package/dist/assets/{edit-ui.es-C7TI7NmB.js → edit-ui.es-B00e6OcT.js} +2 -2
- package/dist/assets/{edit-ui.es-C7TI7NmB.js.map → edit-ui.es-B00e6OcT.js.map} +1 -1
- package/dist/assets/edit-ui.es-BGTYLTZO.js +1 -0
- package/dist/assets/{french-Dk7YG8Td-Bfl4cirn.js → french-Dk7YG8Td-D9eV2DXL.js} +2 -2
- package/dist/assets/{french-Dk7YG8Td-Bfl4cirn.js.map → french-Dk7YG8Td-D9eV2DXL.js.map} +1 -1
- package/dist/assets/french-evUMlbbq-DOmp0PEx.js +1 -0
- package/dist/assets/{index-JRi1udkz.js → index-CDxzcoT1.js} +4 -4
- package/dist/assets/{index-JRi1udkz.js.map → index-CDxzcoT1.js.map} +1 -1
- package/dist/assets/math-DR3fXDcX-Clr1rrj8.js +1 -0
- package/dist/assets/{math-D_8HiEQR-B9oNpF-3.js → math-D_8HiEQR-DdtcYQLB.js} +2 -2
- package/dist/assets/{math-D_8HiEQR-B9oNpF-3.js.map → math-D_8HiEQR-DdtcYQLB.js.map} +1 -1
- package/dist/assets/piano-BN5Btq91-BO9b38qV.js +1 -0
- package/dist/assets/{piano-DF1g6yaX-CjD06Qz8.js → piano-DF1g6yaX-B7f_kt1X.js} +2 -2
- package/dist/assets/{piano-DF1g6yaX-CjD06Qz8.js.map → piano-DF1g6yaX-B7f_kt1X.js.map} +1 -1
- package/dist/assets/{pitch-CgGJFkZ1-C-2hdk99.js → pitch-CgGJFkZ1-CuezrVTg.js} +2 -2
- package/dist/assets/{pitch-CgGJFkZ1-C-2hdk99.js.map → pitch-CgGJFkZ1-CuezrVTg.js.map} +1 -1
- package/dist/assets/pitch-Dn0iNqiS-L0LRhcjZ.js +1 -0
- package/dist/assets/server-BP-NvFg7.js +2 -0
- package/dist/assets/{server-D4lhkoe2.js.map → server-BP-NvFg7.js.map} +1 -1
- package/dist/assets/{sightsing-BFQ7HRig-8K5qd7-K.js → sightsing-BFQ7HRig-CLh3Xcy7.js} +2 -2
- package/dist/assets/{sightsing-BFQ7HRig-8K5qd7-K.js.map → sightsing-BFQ7HRig-CLh3Xcy7.js.map} +1 -1
- package/dist/assets/sightsing-CJX3k0Fd-DiVzeNly.js +1 -0
- package/dist/assets/{typing-BevtfWlp-BT263ZFw.js → typing-BevtfWlp-B__x_Ia1.js} +2 -2
- package/dist/assets/{typing-BevtfWlp-BT263ZFw.js.map → typing-BevtfWlp-B__x_Ia1.js.map} +1 -1
- package/dist/assets/typing-k-ojjO7G-Dn4uH4pS.js +1 -0
- package/dist/assets/{word-work-BOnRlZgd-BFwc1KBd.js → word-work-BOnRlZgd-CxcTzMPz.js} +2 -2
- package/dist/assets/{word-work-BOnRlZgd-BFwc1KBd.js.map → word-work-BOnRlZgd-CxcTzMPz.js.map} +1 -1
- package/dist/assets/word-work-Dd6tIKrt-BOmhWlr6.js +1 -0
- package/dist/index.html +3 -3
- package/dist/sw.js +1 -1
- package/dist/sw.js.map +1 -1
- package/package.json +7 -7
- package/dist/assets/admin-DCvFP6sY.js +0 -4
- package/dist/assets/admin-DCvFP6sY.js.map +0 -1
- package/dist/assets/chess-Lfm7Fsvs-RoJ69a0B.js +0 -1
- package/dist/assets/dist-D4MdLcof.js +0 -1
- package/dist/assets/dist-Db-U8O3Z.js +0 -1
- package/dist/assets/edit-ui.es-CiY2oEH8.js +0 -1
- package/dist/assets/french-evUMlbbq-DuW1vCaS.js +0 -1
- package/dist/assets/math-DR3fXDcX-BFIht0j2.js +0 -1
- package/dist/assets/piano-BN5Btq91-Jqe2eqme.js +0 -1
- package/dist/assets/pitch-Dn0iNqiS-DpEcsscT.js +0 -1
- package/dist/assets/server-D4lhkoe2.js +0 -2
- package/dist/assets/sightsing-CJX3k0Fd-CA3ntnlE.js +0 -1
- package/dist/assets/typing-k-ojjO7G-Bq4IfdFx.js +0 -1
- package/dist/assets/word-work-Dd6tIKrt-tFtMeyu1.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./vue.runtime.esm-bundler--Fxmd6l9.js";import"./dist-V9Xbab2f.js";import{s as e,v as t}from"./MarkdownRenderer-U_iPiA2x-DDruDu7E.js";import"./dist-
|
|
1
|
+
import"./vue.runtime.esm-bundler--Fxmd6l9.js";import"./dist-V9Xbab2f.js";import{s as e,v as t}from"./MarkdownRenderer-U_iPiA2x-DDruDu7E.js";import"./dist-BeppzTWu.js";import"./common-ui.es-B9r6QiWN.js";export{e as MarkdownRenderer,t as piniaPlugin};
|
|
@@ -252,7 +252,7 @@ Example:
|
|
|
252
252
|
Filters:${n}`)}function logTagHydration(e,t){let n=Array.from(t.values()).reduce((e,t)=>e+t.length,0),r=Array.from(t.values()).filter(e=>e.length>0).length;logger.debug(`[Pipeline] Tag hydration: ${e.length} cards, ${r} have tags (${n} total tags) - single batch query`)}function logExecutionSummary(e,t,n,r,a,o){let s=a.length>0?a.map(e=>e.toFixed(2)).join(`, `):`none`,c=``;o.length>0&&(c=`
|
|
253
253
|
Filter impact: ${o.map(e=>{let t=[];return e.boosted>0&&t.push(`+${e.boosted}`),e.penalized>0&&t.push(`-${e.penalized}`),e.passed>0&&t.push(`=${e.passed}`),`${e.name}: ${t.join(`/`)}`}).join(`, `)}`),logger.info(`[Pipeline] Execution: ${e} produced ${t} \u2192 ${n} filters \u2192 ${r} results (top scores: ${s})`+c+`
|
|
254
254
|
💡 Inspect: window.skuilder.pipeline`)}function logResultCards(e){if(!(!VERBOSE_RESULTS||e.length===0)){logger.info(`[Pipeline] Results (${e.length} cards):`);for(let t=0;t<e.length;t++){let n=e[t],r=n.tags?.slice(0,3).join(`, `)||``,a=n.provenance.filter(e=>e.strategy===`hierarchyDefinition`||e.strategy===`priorityDefinition`||e.strategy===`interferenceFilter`||e.strategy===`letterGating`||e.strategy===`ephemeralHint`||e.strategy===`diversityRerank`).map(e=>{let t=e.action===`boosted`?`↑`:e.action===`penalized`?`↓`:`=`;return`${e.strategyName}${t}${e.score.toFixed(2)}`}).join(` | `);logger.info(`[Pipeline] ${String(t+1).padStart(2)}. ${n.score.toFixed(4)} ${n.cardId} [${r}]${a?` {${a}}`:``}`)}}}function logCardProvenance(e,t=3){let n=e.slice(0,t);logger.debug(`[Pipeline] Provenance for top ${n.length} cards:`);for(let e of n){logger.debug(`[Pipeline] ${e.cardId} (final score: ${e.score.toFixed(3)}):`);for(let t of e.provenance){let e=t.score.toFixed(3),n=t.action.padEnd(9);logger.debug(`[Pipeline] ${n} ${e} - ${t.strategyName}: ${t.reason}`)}}}var VERBOSE_RESULTS,Pipeline,init_Pipeline=__esm({"src/core/navigators/Pipeline.ts"(){init_navigators(),init_logger(),init_orchestration(),init_PipelineDebugger(),init_diversityRerank(),init_regulators(),init_SrsDebugger(),VERBOSE_RESULTS=!0,Pipeline=class extends ContentNavigator{constructor(e,t,n,r){super(),_defineProperty(this,`generator`,void 0),_defineProperty(this,`filters`,void 0),_defineProperty(this,`_cachedOrchestration`,null),_defineProperty(this,`strategyHash`,void 0),_defineProperty(this,`_tagCache`,new Map),_defineProperty(this,`_ephemeralHints`,null),_defineProperty(this,`_intakeClock`,null),_defineProperty(this,`_intakeClockWrite`,Promise.resolve()),this.generator=e,this.filters=t,this.user=n,this.course=r,r.getCourseConfig().then(e=>{logger.debug(`[pipeline] Crated pipeline for ${e.name}`)}).catch(e=>{logger.error(`[pipeline] Failed to lookup courseCfg: ${e}`)}),logPipelineConfig(e,t),registerPipelineForDebug(this)}setEphemeralHints(e){this._ephemeralHints=e,logger.info(`[Pipeline] Ephemeral hints set: ${JSON.stringify(e)}`)}async getWeightedCards(e){let t=performance.now(),n=await this.buildContext(),r=performance.now(),a=500;logger.debug(`[Pipeline] Fetching 500 candidates from generator '${this.generator.name}'`);let o=await this.generator.getWeightedCards(500,n),s=o.cards,c=performance.now(),l=s.length;this._ephemeralHints=mergeHints2([this._ephemeralHints,o.hints])??null;let u;if(this.generator.generators){let e=new Map;for(let t of s){let n=t.provenance[0];if(n){let r=n.strategyName;e.has(r)||e.set(r,{cards:[]}),e.get(r).cards.push(t)}}u=Array.from(e.entries()).map(([e,t])=>{let n=t.cards.filter(e=>e.reviewID).length;return{name:e,cardCount:t.cards.length,newCount:t.cards.length-n,reviewCount:n,topScore:Math.max(...t.cards.map(e=>e.score),0)}})}logger.debug(`[Pipeline] Generator returned ${l} candidates`),s=await this.hydrateTags(s);let d=performance.now(),p=[...s],m=this._ephemeralHints;if(m?.requireCards?.length){let e=new Set(p.map(e=>e.cardId)),t=m.requireCards.filter(t=>!t.includes(`*`)&&!e.has(t));if(t.length>0){let e=await this.course.getAppliedTagsBatch(t),n=this.course.getCourseID();for(let r of t)p.push({cardId:r,courseId:n,score:1,tags:e.get(r)??[],provenance:[]});logger.info(`[Pipeline] Pre-fetched ${t.length} required card(s) into pool: ${t.join(`, `)}`)}}let g=new Set(s.filter(e=>e.provenance.some(e=>e.strategy===`prescribed`)).map(e=>e.cardId)),_=[],v=new Map(s.map(e=>[e.cardId,e.score])),y=new Set;for(let e of this.filters){let t=s.length,r=new Map(s.map(e=>[e.cardId,e.score]));s=await e.transform(s,n);let a=0,o=0,c=0,l=t-s.length,u=e.kind??`gate`;for(let e of s){let t=r.get(e.cardId)??0;e.score>t?a++:e.score<t?(o++,u===`gate`&&y.add(e.cardId)):c++}if(_.push({name:e.name,kind:u,boosted:a,penalized:o,passed:c,removed:l}),g.size>0){let t=new Set(s.map(e=>e.cardId)),n=[...g].filter(e=>!t.has(e)),r=s.filter(e=>g.has(e.cardId)&&e.score===0).map(e=>e.cardId);(n.length>0||r.length>0)&&(logger.info(`[Pipeline] Filter '${e.name}' impact on prescribed cards: `+(n.length>0?`removed=[${n.join(`, `)}] `:``)+(r.length>0?`zeroed=[${r.join(`, `)}]`:``)),n.forEach(e=>g.delete(e)))}logger.debug(`[Pipeline] Filter '${e.name}': ${r.size} \u2192 ${s.length} cards (\u2191${a} \u2193${o} =${c})`)}let b=s;s=s.filter(e=>e.score>0);let x=await this.regulate(s,v,y),S=this._ephemeralHints;S&&(this._ephemeralHints=null,s=this.applyHints(s,S,p)),s=diversityRerank(s),s.sort((e,t)=>t.score-e.score);let C=performance.now(),w=s.slice(0,e);logger.info(`[Pipeline:timing] total=${(C-t).toFixed(0)}ms (context=${(r-t).toFixed(0)} generate=${(c-r).toFixed(0)} hydrate=${(d-c).toFixed(0)} filter=${(C-d).toFixed(0)})`);let T=w.slice(0,3).map(e=>e.score);logExecutionSummary(this.generator.name,l,this.filters.length,w.length,T,_),logResultCards(w),logCardProvenance(w,3);try{let e=await this.course?.getCourseConfig().catch(()=>void 0),t=e?.name,r=buildRunReport(this.course?.getCourseID()||`unknown`,t,this.generator.name,u,l,_,s,w,n.userElo,S??void 0,b,x),a={...this.strategyHash?{strategies:this.strategyHash}:{},...e?.contentVersion?{content:e.contentVersion}:{}};captureRun({...r,...Object.keys(a).length?{versions:a}:{}})}catch(e){logger.debug(`[Pipeline] Failed to capture debug run: ${e}`)}return{cards:w}}async hydrateTags(e){if(e.length===0)return e;let t=[];for(let n of e)this._tagCache.has(n.cardId)||t.push(n.cardId);if(t.length>0){let e=await this.course.getAppliedTagsBatch(t);for(let[t,n]of e)this._tagCache.set(t,n)}let n=new Map;for(let t of e)n.set(t.cardId,this._tagCache.get(t.cardId)??[]);return logTagHydration(e,n),e.map(e=>({...e,tags:this._tagCache.get(e.cardId)??[]}))}applyHints(e,t,n){let r=e.length;if(t.excludeCards?.length&&(e=e.filter(e=>!t.excludeCards.some(t=>globMatch(e.cardId,t)))),t.excludeTags?.length&&(e=e.filter(e=>!t.excludeTags.some(t=>cardMatchesTagPattern(e,t)))),t.boostTags)for(let[n,r]of Object.entries(t.boostTags))for(let a of e)cardMatchesTagPattern(a,n)&&(a.score*=r,a.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:t._label?`Replan Hint (${t._label})`:`Replan Hint`,action:`boosted`,score:a.score,reason:`boostTag ${n} \xD7${r}`}));if(t.boostCards)for(let[n,r]of Object.entries(t.boostCards))for(let a of e)globMatch(a.cardId,n)&&(a.score*=r,a.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:t._label?`Replan Hint (${t._label})`:`Replan Hint`,action:`boosted`,score:a.score,reason:`boostCard ${n} \xD7${r}`}));let a=new Set(e.map(e=>e.cardId)),o=new Map(e.map(e=>[e.cardId,e])),s=t._label?`Replan Hint (${t._label})`:`Replan Hint`,applyRequirement=(t,n)=>{let r=1/0,c=o.get(t.cardId);c?c.score<r&&(c.score=r,c.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:s,action:`boosted`,score:r,reason:`${n} (upgrade to mandatory score)`})):(e.push({...t,score:r,provenance:[...t.provenance,{strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:s,action:`boosted`,score:r,reason:n}]}),a.add(t.cardId),o.set(t.cardId,e[e.length-1]))};if(t.requireCards?.length)for(let e of t.requireCards){for(let t of a)globMatch(t,e)&&applyRequirement(o.get(t),`requireCard ${e}`);for(let t of n)globMatch(t.cardId,e)&&applyRequirement(t,`requireCard ${e}`)}if(t.requireTags?.length)for(let e of t.requireTags){for(let t of a){let n=o.get(t);cardMatchesTagPattern(n,e)&&applyRequirement(n,`requireTag ${e}`)}for(let t of n)cardMatchesTagPattern(t,e)&&applyRequirement(t,`requireTag ${e}`)}return logger.info(`[Pipeline] Hints applied: ${r} \u2192 ${e.length} cards`),e}async regulate(e,t,n){let r=DEFAULT_REGULATOR_CONFIG,a=e.filter(e=>e.reviewID),o=e.filter(e=>!e.reviewID),s=o.filter(e=>!n.has(e.cardId)),c=reviewMassReading(a,t,r.reviewMass);applyReading(a,c),noteReviewPressure(this.course.getCourseID(),{mass:c.urgency,healthyMass:r.reviewMass.healthyMass,rate:r.reviewMass.rate,multiplier:c.multiplier});let l=Date.now(),u=await this.loadIntakeClock(l),d=stepIntakeClock(u,l,s.length);d!==u&&this.saveIntakeClock(d);let p=intakeReading(d,l,{eligibleNew:s.length,newCandidates:o.length},r.intake);return applyReading(s,p),logger.info(`[Pipeline:regulators] review mass ${c.urgency.toFixed(1)} over ${a.length} due \u2192 \xD7${c.multiplier.toFixed(2)}; intake ${p.urgency.toFixed(1)}h, ${s.length}/${o.length} new eligible \u2192 \xD7${p.multiplier.toFixed(2)}`),[c,p]}notePresented(e){e.status!==`new`||e.courseId!==this.course?.getCourseID()||this.saveIntakeClock(resetIntakeClock(Date.now()))}async loadIntakeClock(e){if(this._intakeClock)return this._intakeClock;let t=null;try{t=await this.user.getStrategyState(this.course.getCourseID(),INTAKE_CLOCK_KEY)}catch(e){logger.warn(`[Pipeline:regulators] Could not read the intake clock: ${e}`)}return t?this._intakeClock=t:this.saveIntakeClock(resetIntakeClock(e)),this._intakeClock}saveIntakeClock(e){this._intakeClock=e;let t=this.course.getCourseID();this._intakeClockWrite=this._intakeClockWrite.then(()=>this.user.putStrategyState(t,INTAKE_CLOCK_KEY,e)).catch(e=>logger.warn(`[Pipeline:regulators] Could not save the intake clock: ${e}`))}async buildContext(){let e=1e3,t;try{t=toCourseElo((await this.user.getCourseRegDoc(this.course.getCourseID())).elo),e=t.global.score}catch(e){logger.debug(`[Pipeline] Could not get user ELO, using default: ${e}`)}this._cachedOrchestration||(this._cachedOrchestration=await createOrchestrationContext(this.user,this.course));let n=this._cachedOrchestration;return{user:this.user,course:this.course,userElo:e,...t?{userCourseElo:t}:{},orchestration:n}}getCourseID(){return this.course.getCourseID()}async getOrchestrationContext(){return createOrchestrationContext(this.user,this.course)}getStrategyIds(){let e=[],extractId=e=>e.strategyId?e.strategyId:null,t=extractId(this.generator);t&&e.push(t),this.generator.generators&&Array.isArray(this.generator.generators)&&this.generator.generators.forEach(t=>{let n=extractId(t);n&&e.push(n)});for(let t of this.filters){let n=extractId(t);n&&e.push(n)}return[...new Set(e)]}async getTagEloStatus(e){let t=toCourseElo((await this.user.getCourseRegDoc(this.course.getCourseID())).elo),n={};if(e){let r=Array.isArray(e)?e:[e];for(let e of r){let r=globToRegex(e);for(let[e,a]of Object.entries(t.tags))r.test(e)&&(n[e]={score:a.score,count:a.count})}}else for(let[e,r]of Object.entries(t.tags))n[e]={score:r.score,count:r.count};return n}async forecast(e){let t=e?.threshold??.1,n=e?.unseenOnly??!0,r=this.course.getCourseID(),a=(await this.course.getAllCardIds()).map(e=>({cardId:e,courseId:r,score:1,provenance:[]}));a=await this.hydrateTags(a);let o=a.slice(),s=await this.buildContext();for(let e of this.forecastFilters())a=await e.transform(a,s);if(e?.hints&&(a=this.applyHints(a,e.hints,o)),a=a.filter(e=>e.score>=t),n){let e;try{e=new Set(await this.user.getSeenCards(r))}catch{e=new Set}a=a.filter(t=>!e.has(t.cardId))}return a.sort((e,t)=>t.score-e.score),e?.limit?a.slice(0,e.limit):a}forecastFilters(){return this.filters.filter(e=>!e.liveOnly)}async diagnoseCardSpace(e){let t=e?.threshold??.1,n=performance.now(),r=await this.course.getAllCardIds(),a=r.map(e=>({cardId:e,courseId:this.course.getCourseID(),score:1,provenance:[]}));a=await this.hydrateTags(a);let o=await this.buildContext(),s=[];for(let e of this.forecastFilters()){a=await e.transform(a,o);let n=a.filter(e=>e.score>=t).length;s.push({name:e.name,wellIndicated:n})}let c=a.filter(e=>e.score>=t),l=new Set(c.map(e=>e.cardId)),u;try{let e=this.course.getCourseID(),t=await this.user.getSeenCards(e);u=new Set(t)}catch{u=new Set}let d=c.filter(e=>!u.has(e.cardId)),p=new Map;for(let e of a){let n=e.cardId.split(`-`)[1]||`unknown`;p.has(n)||p.set(n,{total:0,wellIndicated:0,new:0});let r=p.get(n);r.total++,e.score>=t&&(r.wellIndicated++,u.has(e.cardId)||r.new++)}let m=performance.now()-n,g={totalCards:r.length,threshold:t,wellIndicated:l.size,encountered:u.size,wellIndicatedNew:d.length,byType:Object.fromEntries(p),filterBreakdown:s,elapsedMs:Math.round(m)};logger.info(`[Pipeline:diagnose] Card space scan (${g.elapsedMs}ms):`),logger.info(`[Pipeline:diagnose] Total cards: ${g.totalCards}`),logger.info(`[Pipeline:diagnose] Well-indicated (score >= ${t}): ${g.wellIndicated}`),logger.info(`[Pipeline:diagnose] Encountered: ${g.encountered}`),logger.info(`[Pipeline:diagnose] Well-indicated & new: ${g.wellIndicatedNew}`),logger.info(`[Pipeline:diagnose] By type:`);for(let[e,t]of p)logger.info(`[Pipeline:diagnose] ${e}: ${t.wellIndicated}/${t.total} well-indicated, ${t.new} new`);logger.info(`[Pipeline:diagnose] After each filter:`);for(let e of s)logger.info(`[Pipeline:diagnose] ${e.name}: ${e.wellIndicated} well-indicated`);return g}}}});function setAppVersion(e){hostAppVersion=e}function sessionVersions(){return{framework:FRAMEWORK_VERSION,...hostAppVersion?{app:hostAppVersion}:{}}}function stableStringify(e){return Array.isArray(e)?`[${e.map(stableStringify).join(`,`)}]`:e&&typeof e==`object`?`{${Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e<t?-1:e>t?1:0).map(([e,t])=>`${JSON.stringify(e)}:${stableStringify(t)}`).join(`,`)}}`:JSON.stringify(e)}function strategyHash(e){if(e.length===0)return DEFAULT_STRATEGY_HASH;let t=e.map(e=>{let{_rev:t,...n}=e;return stableStringify(n)}).sort().join(`
|
|
255
|
-
`),n=2166136261;for(let e=0;e<t.length;e++)n^=t.charCodeAt(e),n=Math.imul(n,16777619);return(n>>>0).toString(16).padStart(8,`0`)}var FRAMEWORK_VERSION,hostAppVersion,DEFAULT_STRATEGY_HASH,init_versionStamps=__esm({"src/core/versionStamps.ts"(){FRAMEWORK_VERSION=`0.2.34`,DEFAULT_STRATEGY_HASH=`default`}}),defaults_exports={};__export(defaults_exports,{createDefaultEloDistanceStrategy:()=>createDefaultEloDistanceStrategy,createDefaultEloStrategy:()=>createDefaultEloStrategy,createDefaultPipeline:()=>createDefaultPipeline,createDefaultSrsStrategy:()=>createDefaultSrsStrategy});function createDefaultEloStrategy(e){return{_id:`NAVIGATION_STRATEGY-ELO-default`,docType:`NAVIGATION_STRATEGY`,name:`ELO (default)`,description:`Default ELO-based navigation strategy for new cards`,implementingClass:`elo`,course:e,serializedData:``}}function createDefaultSrsStrategy(e){return{_id:`NAVIGATION_STRATEGY-SRS-default`,docType:`NAVIGATION_STRATEGY`,name:`SRS (default)`,description:`Default SRS-based navigation strategy for reviews`,implementingClass:`srs`,course:e,serializedData:``}}function createDefaultEloDistanceStrategy(e){return{_id:`NAVIGATION_STRATEGY-eloDistance-default`,docType:`NAVIGATION_STRATEGY`,name:`ELO Distance (default)`,description:`Scales every candidate, new or review, by its distance from the learner's ELO`,implementingClass:`eloDistance`,course:e,serializedData:JSON.stringify(DEFAULT_ELO_DISTANCE_CONFIG)}}function createDefaultPipeline(e,t){let n=t.getCourseID(),r=new ELONavigator(e,t,createDefaultEloStrategy(n)),a=new SRSNavigator(e,t,createDefaultSrsStrategy(n)),o=new CompositeGenerator([r,a]),s=new EloDistanceFilter(e,t,createDefaultEloDistanceStrategy(n)),c=new Pipeline(o,[s],e,t);return c.strategyHash=DEFAULT_STRATEGY_HASH,c}var init_defaults=__esm({"src/core/navigators/defaults.ts"(){init_navigators(),init_Pipeline(),init_CompositeGenerator(),init_elo(),init_srs(),init_eloDistance(),init_types_legacy(),init_versionStamps()}}),pipelinePlan_exports={};__export(pipelinePlan_exports,{PIPELINE_STAGES:()=>PIPELINE_STAGES,planPipeline:()=>planPipeline});function planned(e,t,n){let r=t===`filter`?getRegisteredFilterKind(e.implementingClass):void 0;return{role:t,origin:n,name:e.name,implementingClass:e.implementingClass,strategy:e,...r?{kind:r}:{}}}function planPipeline(e,t){if(e.length===0)return{kind:`default`,generators:[planned(createDefaultEloStrategy(t),`generator`,`default-pipeline`),planned(createDefaultSrsStrategy(t),`generator`,`default-pipeline`)],filters:[planned(createDefaultEloDistanceStrategy(t),`filter`,`default-pipeline`)],skipped:[],warnings:[],notes:[],regulators:DEFAULT_REGULATOR_CONFIG};let n=[],r=[],a=[],o=[];for(let t of e)isGenerator(t.implementingClass)?n.push(planned(t,`generator`,`strategy-doc`)):isFilter(t.implementingClass)?r.push(planned(t,`filter`,`strategy-doc`)):(a.push({strategy:t,reason:`not a registered generator or filter`}),o.push(`Unknown strategy type '${t.implementingClass}', skipping: ${t.name}`));let s=new Set(n.map(e=>e.implementingClass));s.has(createDefaultEloStrategy(t).implementingClass)||n.push(planned(createDefaultEloStrategy(t),`generator`,`assembler-default`)),s.has(createDefaultSrsStrategy(t).implementingClass)||n.push(planned(createDefaultSrsStrategy(t),`generator`,`assembler-default`));let c=createDefaultEloDistanceStrategy(t);return r.some(e=>e.implementingClass===c.implementingClass)||r.push(planned(c,`filter`,`assembler-default`)),r.sort((e,t)=>e.name.localeCompare(t.name)),{kind:`assembled`,generators:n,filters:r,skipped:a,warnings:o,notes:[],regulators:DEFAULT_REGULATOR_CONFIG}}var PIPELINE_STAGES,init_pipelinePlan=__esm({"src/core/navigators/pipelinePlan.ts"(){init_navigators(),init_regulators(),init_defaults(),PIPELINE_STAGES=[{key:`generate`,title:`Generate`,summary:`Each generator proposes candidates (up to 500 in all), scored on what is specific to its source. A card proposed by several generators keeps their mean score, raised 10% per extra generator.`},{key:`filter`,title:`Filter`,summary:`Each filter multiplies candidate scores, in the order shown. A gate says a card is not ready yet; a signal expresses preference. Gates usually penalize rather than remove, so a gated card stays in the pool at a low score.`},{key:`drop-zero`,title:`Drop zero scores`,summary:`Candidates whose score reached 0 leave the pool.`},{key:`regulate`,title:`Regulate`,summary:`Balances reviews against new cards. Review mass: the due reviews weighed by their filtered scores; above a healthy level, every review is lifted. Intake: hours since a new card was last presented; new cards no gate penalized are lifted, and the clock stops while there are none.`},{key:`hints`,title:`Apply hints`,summary:`The session's hints (from the app: an intro's follow-up, a difficulty boost) exclude, boost, or require cards. Required cards skip the filters entirely.`},{key:`diversity`,title:`Diversity re-rank`,summary:`Demotes candidates that repeat a distinctive tag already ranked above them, so one concept or answer cannot take the whole head of the queue. Sees this run only, not what the session already served.`},{key:`select`,title:`Select`,summary:`Highest scores first, up to the run's limit. The session mixes them into its supply queue.`}]}}),PipelineAssembler_exports={};__export(PipelineAssembler_exports,{PipelineAssembler:()=>PipelineAssembler});var PipelineAssembler,init_PipelineAssembler=__esm({"src/core/navigators/PipelineAssembler.ts"(){init_navigators(),init_WeightedFilter(),init_Pipeline(),init_logger(),init_CompositeGenerator(),init_pipelinePlan(),init_versionStamps(),PipelineAssembler=class{async assemble(e){let{strategies:t,user:n,course:r}=e,a=[];if(t.length===0)return{pipeline:null,generatorStrategies:[],filterStrategies:[],warnings:a};let o=planPipeline(t,r.getCourseID());a.push(...o.warnings);for(let e of[...o.generators,...o.filters])e.origin===`assembler-default`&&logger.debug(`[PipelineAssembler] No ${e.implementingClass} ${e.role} configured, adding default`);let s=o.generators.map(e=>e.strategy),c=o.filters.map(e=>e.strategy);if(s.length===0)return a.push(`No generator strategy found`),{pipeline:null,generatorStrategies:[],filterStrategies:[],warnings:a};let l;s.length===1?(l=await ContentNavigator.create(n,r,s[0]),logger.debug(`[PipelineAssembler] Using single generator: ${s[0].name}`)):(logger.debug(`[PipelineAssembler] Using CompositeGenerator for ${s.length} generators: ${s.map(e=>e.name).join(`, `)}`),l=await CompositeGenerator.fromStrategies(n,r,s));let u=[];for(let e of c)try{let t=await ContentNavigator.create(n,r,e);if(`transform`in t&&typeof t.transform==`function`){let n=t;e.learnable&&(n=new WeightedFilter(n,e.learnable,e.staticWeight,e._id)),u.push(n),logger.debug(`[PipelineAssembler] Added filter: ${e.name}`)}else a.push(`Filter '${e.name}' does not implement CardFilter.transform(), skipping`)}catch(t){a.push(`Failed to instantiate filter '${e.name}': ${t}`)}let d=new Pipeline(l,u,n,r);return d.strategyHash=strategyHash(t),logger.debug(`[PipelineAssembler] Assembled pipeline with ${s.length} generator(s) and ${u.length} filter(s)`),{pipeline:d,generatorStrategies:s,filterStrategies:c,warnings:a}}}}}),globImport,init_3=__esm({'import("./**/*") in src/core/navigators/index.ts'(){globImport=__glob({"./Pipeline.ts":()=>Promise.resolve().then(()=>(init_Pipeline(),Pipeline_exports)),"./PipelineAssembler.ts":()=>Promise.resolve().then(()=>(init_PipelineAssembler(),PipelineAssembler_exports)),"./PipelineDebugger.ts":()=>Promise.resolve().then(()=>(init_PipelineDebugger(),PipelineDebugger_exports)),"./SrsDebugger.ts":()=>Promise.resolve().then(()=>(init_SrsDebugger(),SrsDebugger_exports)),"./StrategyPressureDebugger.ts":()=>Promise.resolve().then(()=>(init_StrategyPressureDebugger(),StrategyPressureDebugger_exports)),"./defaults.ts":()=>Promise.resolve().then(()=>(init_defaults(),defaults_exports)),"./diversityRerank.ts":()=>Promise.resolve().then(()=>(init_diversityRerank(),diversityRerank_exports)),"./filters/WeightedFilter.ts":()=>Promise.resolve().then(()=>(init_WeightedFilter(),WeightedFilter_exports)),"./filters/eloDistance.ts":()=>Promise.resolve().then(()=>(init_eloDistance(),eloDistance_exports)),"./filters/hierarchyDefinition.ts":()=>Promise.resolve().then(()=>(init_hierarchyDefinition(),hierarchyDefinition_exports)),"./filters/index.ts":()=>Promise.resolve().then(()=>(init_filters(),filters_exports)),"./filters/inferredPreferenceStub.ts":()=>Promise.resolve().then(()=>(init_inferredPreferenceStub(),inferredPreferenceStub_exports)),"./filters/interferenceMitigator.ts":()=>Promise.resolve().then(()=>(init_interferenceMitigator(),interferenceMitigator_exports)),"./filters/relativePriority.ts":()=>Promise.resolve().then(()=>(init_relativePriority(),relativePriority_exports)),"./filters/types.ts":()=>Promise.resolve().then(()=>(init_types2(),types_exports2)),"./filters/userGoalStub.ts":()=>Promise.resolve().then(()=>(init_userGoalStub(),userGoalStub_exports)),"./filters/userTagPreference.ts":()=>Promise.resolve().then(()=>(init_userTagPreference(),userTagPreference_exports)),"./generators/CompositeGenerator.ts":()=>Promise.resolve().then(()=>(init_CompositeGenerator(),CompositeGenerator_exports)),"./generators/elo.ts":()=>Promise.resolve().then(()=>(init_elo(),elo_exports)),"./generators/index.ts":()=>Promise.resolve().then(()=>(init_generators(),generators_exports)),"./generators/prescribed.ts":()=>Promise.resolve().then(()=>(init_prescribed(),prescribed_exports)),"./generators/srs.ts":()=>Promise.resolve().then(()=>(init_srs(),srs_exports)),"./generators/types.ts":()=>Promise.resolve().then(()=>(init_types(),types_exports)),"./index.ts":()=>Promise.resolve().then(()=>(init_navigators(),navigators_exports)),"./pipelinePlan.ts":()=>Promise.resolve().then(()=>(init_pipelinePlan(),pipelinePlan_exports)),"./regulators.ts":()=>Promise.resolve().then(()=>(init_regulators(),regulators_exports))})}}),navigators_exports={};__export(navigators_exports,{ContentNavigator:()=>ContentNavigator,DIVERSITY_FLOOR:()=>DIVERSITY_FLOOR,DIVERSITY_STRENGTH:()=>DIVERSITY_STRENGTH,NavigatorRole:()=>NavigatorRole,NavigatorRoles:()=>NavigatorRoles,Navigators:()=>Navigators,captureStrategyPressure:()=>captureStrategyPressure,clearSrsBacklogDebug:()=>clearSrsBacklogDebug,clearStrategyPressureDebug:()=>clearStrategyPressureDebug,diversityRerank:()=>diversityRerank,drainCapturedRuns:()=>drainCapturedRuns,getActivePipeline:()=>getActivePipeline,getCardOrigin:()=>getCardOrigin,getRegisteredFilterKind:()=>getRegisteredFilterKind,getRegisteredNavigator:()=>getRegisteredNavigator,getRegisteredNavigatorNames:()=>getRegisteredNavigatorNames,getRegisteredNavigatorRole:()=>getRegisteredNavigatorRole,getRunsForSession:()=>getRunsForSession,getSrsBacklogDebug:()=>getSrsBacklogDebug,getStrategyPressureDebug:()=>getStrategyPressureDebug,hasRegisteredNavigator:()=>hasRegisteredNavigator,initializeNavigatorRegistry:()=>initializeNavigatorRegistry,isFilter:()=>isFilter,isGenerator:()=>isGenerator,mountPipelineDebugger:()=>mountPipelineDebugger,pipelineDebugAPI:()=>pipelineDebugAPI,registerNavigator:()=>registerNavigator,setDebugSessionId:()=>setDebugSessionId});function registerNavigator(e,t,n){navigatorRegistry.set(e,{constructor:t,role:n}),logger.debug(`[NavigatorRegistry] Registered: ${e}${n?` (${n})`:``}`)}function getRegisteredNavigator(e){return navigatorRegistry.get(e)?.constructor}function hasRegisteredNavigator(e){return navigatorRegistry.has(e)}function getRegisteredNavigatorRole(e){return navigatorRegistry.get(e)?.role}function getRegisteredFilterKind(e){return navigatorRegistry.get(e)?.constructor?.kind}function getRegisteredNavigatorNames(){return Array.from(navigatorRegistry.keys())}async function initializeNavigatorRegistry(){logger.debug(`[NavigatorRegistry] Initializing built-in navigators...`);let[e,t]=await Promise.all([Promise.resolve().then(()=>(init_elo(),elo_exports)),Promise.resolve().then(()=>(init_srs(),srs_exports))]),n=await Promise.resolve().then(()=>(init_prescribed(),prescribed_exports));registerNavigator(`elo`,e.default),registerNavigator(`srs`,t.default),registerNavigator(`prescribed`,n.default);let[r,a,o,s,c]=await Promise.all([Promise.resolve().then(()=>(init_hierarchyDefinition(),hierarchyDefinition_exports)),Promise.resolve().then(()=>(init_interferenceMitigator(),interferenceMitigator_exports)),Promise.resolve().then(()=>(init_relativePriority(),relativePriority_exports)),Promise.resolve().then(()=>(init_userTagPreference(),userTagPreference_exports)),Promise.resolve().then(()=>(init_eloDistance(),eloDistance_exports))]);registerNavigator(`hierarchyDefinition`,r.default),registerNavigator(`interferenceMitigator`,a.default),registerNavigator(`relativePriority`,o.default),registerNavigator(`userTagPreference`,s.default),registerNavigator(`eloDistance`,c.default),logger.debug(`[NavigatorRegistry] Initialized ${navigatorRegistry.size} navigators: ${getRegisteredNavigatorNames().join(`, `)}`)}function getCardOrigin(e){if(e.provenance.length===0)throw Error(`Card has no provenance - cannot determine origin`);let t=e.provenance[0].reason.toLowerCase();return t.includes(`failed`)?`failed`:t.includes(`review`)?`review`:`new`}function isGenerator(e){return NavigatorRoles[e]===`generator`?!0:getRegisteredNavigatorRole(e)===`generator`}function isFilter(e){return NavigatorRoles[e]===`filter`?!0:getRegisteredNavigatorRole(e)===`filter`}var navigatorRegistry,Navigators,NavigatorRole,NavigatorRoles,ContentNavigator,init_navigators=__esm({"src/core/navigators/index.ts"(){init_diversityRerank(),init_PipelineDebugger(),init_SrsDebugger(),init_StrategyPressureDebugger(),init_logger(),init_(),init_2(),init_3(),navigatorRegistry=new Map,Navigators=(e=>(e.ELO=`elo`,e.SRS=`srs`,e.PRESCRIBED=`prescribed`,e.HIERARCHY=`hierarchyDefinition`,e.INTERFERENCE=`interferenceMitigator`,e.RELATIVE_PRIORITY=`relativePriority`,e.USER_TAG_PREFERENCE=`userTagPreference`,e.ELO_DISTANCE=`eloDistance`,e))(Navigators||{}),NavigatorRole=(e=>(e.GENERATOR=`generator`,e.FILTER=`filter`,e))(NavigatorRole||{}),NavigatorRoles={elo:`generator`,srs:`generator`,prescribed:`generator`,hierarchyDefinition:`filter`,interferenceMitigator:`filter`,relativePriority:`filter`,userTagPreference:`filter`,eloDistance:`filter`},ContentNavigator=class{constructor(e,t,n){_defineProperty(this,`user`,void 0),_defineProperty(this,`course`,void 0),_defineProperty(this,`strategyName`,void 0),_defineProperty(this,`strategyId`,void 0),_defineProperty(this,`learnable`,void 0),_defineProperty(this,`staticWeight`,void 0),this.user=e,this.course=t,n&&(this.strategyName=n.name,this.strategyId=n._id,this.learnable=n.learnable,this.staticWeight=n.staticWeight)}get strategyKey(){return this.constructor.name}async getStrategyState(){if(!this.user||!this.course)throw Error(`Cannot get strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.`);return this.user.getStrategyState(this.course.getCourseID(),this.strategyKey)}async putStrategyState(e){if(!this.user||!this.course)throw Error(`Cannot put strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.`);return this.user.putStrategyState(this.course.getCourseID(),this.strategyKey,e)}static async create(e,t,n){let r=n.implementingClass,a=getRegisteredNavigator(r);if(a)return logger.debug(`[ContentNavigator.create] Using registered navigator: ${r}`),new a(e,t,n);logger.debug(`[ContentNavigator.create] Navigator not in registry, attempting dynamic import: ${r}`);let o;for(let e of[`.ts`,`.js`,``]){try{if(o=(await globImport_generators(`./generators/${r}${e}`)).default,o)break}catch(t){logger.debug(`Failed to load generator ${r}${e}:`,t)}try{if(o=(await globImport_filters(`./filters/${r}${e}`)).default,o)break}catch(t){logger.debug(`Failed to load filter ${r}${e}:`,t)}try{if(o=(await globImport(`./${r}${e}`)).default,o)break}catch(t){logger.debug(`Failed to load legacy ${r}${e}:`,t)}if(o)break}if(!o)throw Error(`Could not load navigator implementation for: ${r}`);return new o(e,t,n)}async getWeightedCards(e){throw Error(`${this.constructor.name} must implement getWeightedCards(). `)}setEphemeralHints(e){}}}});function randIntWeightedTowardZero(e){return Math.floor(Math.random()*Math.random()*Math.random()*e)}async function getCourseTagStubs(e){logger.debug(`Getting tag stubs for course: ${e}`);let t=await filterAllDocsByPrefix(getCourseDB2(e),`TAG`.valueOf()+`-`);return t.rows.forEach(e=>{logger.debug(` Tag stub for doc: ${e.id}`)}),t}async function createTag(e,t,n){logger.debug(`Creating tag: ${t}...`);let r=getTagID(t);return await getCourseDB2(e).put({course:e,docType:`TAG`,name:t,snippet:``,taggedCards:[],wiki:``,author:n,_id:r})}async function updateTag(e){let t=await getTag(e.course,e.name);return await getCourseDB2(e.course).put({...e,_rev:t._rev})}async function getTag(e,t){let n=getTagID(t);return getCourseDB2(e).get(n)}async function removeTagFromCard(e,t,n){n=getTagID(n);let r=getCourseDB2(e),a=await r.get(n);return a.taggedCards=a.taggedCards.filter(e=>t!==e),r.put(a)}async function getAppliedTags(e,t){return await getCourseDB2(e).query(`getTags`,{startkey:t,endkey:t})}async function updateCredentialledCourseConfig(e,t){logger.debug(`Updating course config:
|
|
255
|
+
`),n=2166136261;for(let e=0;e<t.length;e++)n^=t.charCodeAt(e),n=Math.imul(n,16777619);return(n>>>0).toString(16).padStart(8,`0`)}var FRAMEWORK_VERSION,hostAppVersion,DEFAULT_STRATEGY_HASH,init_versionStamps=__esm({"src/core/versionStamps.ts"(){FRAMEWORK_VERSION=`0.2.35`,DEFAULT_STRATEGY_HASH=`default`}}),defaults_exports={};__export(defaults_exports,{createDefaultEloDistanceStrategy:()=>createDefaultEloDistanceStrategy,createDefaultEloStrategy:()=>createDefaultEloStrategy,createDefaultPipeline:()=>createDefaultPipeline,createDefaultSrsStrategy:()=>createDefaultSrsStrategy});function createDefaultEloStrategy(e){return{_id:`NAVIGATION_STRATEGY-ELO-default`,docType:`NAVIGATION_STRATEGY`,name:`ELO (default)`,description:`Default ELO-based navigation strategy for new cards`,implementingClass:`elo`,course:e,serializedData:``}}function createDefaultSrsStrategy(e){return{_id:`NAVIGATION_STRATEGY-SRS-default`,docType:`NAVIGATION_STRATEGY`,name:`SRS (default)`,description:`Default SRS-based navigation strategy for reviews`,implementingClass:`srs`,course:e,serializedData:``}}function createDefaultEloDistanceStrategy(e){return{_id:`NAVIGATION_STRATEGY-eloDistance-default`,docType:`NAVIGATION_STRATEGY`,name:`ELO Distance (default)`,description:`Scales every candidate, new or review, by its distance from the learner's ELO`,implementingClass:`eloDistance`,course:e,serializedData:JSON.stringify(DEFAULT_ELO_DISTANCE_CONFIG)}}function createDefaultPipeline(e,t){let n=t.getCourseID(),r=new ELONavigator(e,t,createDefaultEloStrategy(n)),a=new SRSNavigator(e,t,createDefaultSrsStrategy(n)),o=new CompositeGenerator([r,a]),s=new EloDistanceFilter(e,t,createDefaultEloDistanceStrategy(n)),c=new Pipeline(o,[s],e,t);return c.strategyHash=DEFAULT_STRATEGY_HASH,c}var init_defaults=__esm({"src/core/navigators/defaults.ts"(){init_navigators(),init_Pipeline(),init_CompositeGenerator(),init_elo(),init_srs(),init_eloDistance(),init_types_legacy(),init_versionStamps()}}),pipelinePlan_exports={};__export(pipelinePlan_exports,{PIPELINE_STAGES:()=>PIPELINE_STAGES,planPipeline:()=>planPipeline});function planned(e,t,n){let r=t===`filter`?getRegisteredFilterKind(e.implementingClass):void 0;return{role:t,origin:n,name:e.name,implementingClass:e.implementingClass,strategy:e,...r?{kind:r}:{}}}function planPipeline(e,t){if(e.length===0)return{kind:`default`,generators:[planned(createDefaultEloStrategy(t),`generator`,`default-pipeline`),planned(createDefaultSrsStrategy(t),`generator`,`default-pipeline`)],filters:[planned(createDefaultEloDistanceStrategy(t),`filter`,`default-pipeline`)],skipped:[],warnings:[],notes:[],regulators:DEFAULT_REGULATOR_CONFIG};let n=[],r=[],a=[],o=[];for(let t of e)isGenerator(t.implementingClass)?n.push(planned(t,`generator`,`strategy-doc`)):isFilter(t.implementingClass)?r.push(planned(t,`filter`,`strategy-doc`)):(a.push({strategy:t,reason:`not a registered generator or filter`}),o.push(`Unknown strategy type '${t.implementingClass}', skipping: ${t.name}`));let s=new Set(n.map(e=>e.implementingClass));s.has(createDefaultEloStrategy(t).implementingClass)||n.push(planned(createDefaultEloStrategy(t),`generator`,`assembler-default`)),s.has(createDefaultSrsStrategy(t).implementingClass)||n.push(planned(createDefaultSrsStrategy(t),`generator`,`assembler-default`));let c=createDefaultEloDistanceStrategy(t);return r.some(e=>e.implementingClass===c.implementingClass)||r.push(planned(c,`filter`,`assembler-default`)),r.sort((e,t)=>e.name.localeCompare(t.name)),{kind:`assembled`,generators:n,filters:r,skipped:a,warnings:o,notes:[],regulators:DEFAULT_REGULATOR_CONFIG}}var PIPELINE_STAGES,init_pipelinePlan=__esm({"src/core/navigators/pipelinePlan.ts"(){init_navigators(),init_regulators(),init_defaults(),PIPELINE_STAGES=[{key:`generate`,title:`Generate`,summary:`Each generator proposes candidates (up to 500 in all), scored on what is specific to its source. A card proposed by several generators keeps their mean score, raised 10% per extra generator.`},{key:`filter`,title:`Filter`,summary:`Each filter multiplies candidate scores, in the order shown. A gate says a card is not ready yet; a signal expresses preference. Gates usually penalize rather than remove, so a gated card stays in the pool at a low score.`},{key:`drop-zero`,title:`Drop zero scores`,summary:`Candidates whose score reached 0 leave the pool.`},{key:`regulate`,title:`Regulate`,summary:`Balances reviews against new cards. Review mass: the due reviews weighed by their filtered scores; above a healthy level, every review is lifted. Intake: hours since a new card was last presented; new cards no gate penalized are lifted, and the clock stops while there are none.`},{key:`hints`,title:`Apply hints`,summary:`The session's hints (from the app: an intro's follow-up, a difficulty boost) exclude, boost, or require cards. Required cards skip the filters entirely.`},{key:`diversity`,title:`Diversity re-rank`,summary:`Demotes candidates that repeat a distinctive tag already ranked above them, so one concept or answer cannot take the whole head of the queue. Sees this run only, not what the session already served.`},{key:`select`,title:`Select`,summary:`Highest scores first, up to the run's limit. The session mixes them into its supply queue.`}]}}),PipelineAssembler_exports={};__export(PipelineAssembler_exports,{PipelineAssembler:()=>PipelineAssembler});var PipelineAssembler,init_PipelineAssembler=__esm({"src/core/navigators/PipelineAssembler.ts"(){init_navigators(),init_WeightedFilter(),init_Pipeline(),init_logger(),init_CompositeGenerator(),init_pipelinePlan(),init_versionStamps(),PipelineAssembler=class{async assemble(e){let{strategies:t,user:n,course:r}=e,a=[];if(t.length===0)return{pipeline:null,generatorStrategies:[],filterStrategies:[],warnings:a};let o=planPipeline(t,r.getCourseID());a.push(...o.warnings);for(let e of[...o.generators,...o.filters])e.origin===`assembler-default`&&logger.debug(`[PipelineAssembler] No ${e.implementingClass} ${e.role} configured, adding default`);let s=o.generators.map(e=>e.strategy),c=o.filters.map(e=>e.strategy);if(s.length===0)return a.push(`No generator strategy found`),{pipeline:null,generatorStrategies:[],filterStrategies:[],warnings:a};let l;s.length===1?(l=await ContentNavigator.create(n,r,s[0]),logger.debug(`[PipelineAssembler] Using single generator: ${s[0].name}`)):(logger.debug(`[PipelineAssembler] Using CompositeGenerator for ${s.length} generators: ${s.map(e=>e.name).join(`, `)}`),l=await CompositeGenerator.fromStrategies(n,r,s));let u=[];for(let e of c)try{let t=await ContentNavigator.create(n,r,e);if(`transform`in t&&typeof t.transform==`function`){let n=t;e.learnable&&(n=new WeightedFilter(n,e.learnable,e.staticWeight,e._id)),u.push(n),logger.debug(`[PipelineAssembler] Added filter: ${e.name}`)}else a.push(`Filter '${e.name}' does not implement CardFilter.transform(), skipping`)}catch(t){a.push(`Failed to instantiate filter '${e.name}': ${t}`)}let d=new Pipeline(l,u,n,r);return d.strategyHash=strategyHash(t),logger.debug(`[PipelineAssembler] Assembled pipeline with ${s.length} generator(s) and ${u.length} filter(s)`),{pipeline:d,generatorStrategies:s,filterStrategies:c,warnings:a}}}}}),globImport,init_3=__esm({'import("./**/*") in src/core/navigators/index.ts'(){globImport=__glob({"./Pipeline.ts":()=>Promise.resolve().then(()=>(init_Pipeline(),Pipeline_exports)),"./PipelineAssembler.ts":()=>Promise.resolve().then(()=>(init_PipelineAssembler(),PipelineAssembler_exports)),"./PipelineDebugger.ts":()=>Promise.resolve().then(()=>(init_PipelineDebugger(),PipelineDebugger_exports)),"./SrsDebugger.ts":()=>Promise.resolve().then(()=>(init_SrsDebugger(),SrsDebugger_exports)),"./StrategyPressureDebugger.ts":()=>Promise.resolve().then(()=>(init_StrategyPressureDebugger(),StrategyPressureDebugger_exports)),"./defaults.ts":()=>Promise.resolve().then(()=>(init_defaults(),defaults_exports)),"./diversityRerank.ts":()=>Promise.resolve().then(()=>(init_diversityRerank(),diversityRerank_exports)),"./filters/WeightedFilter.ts":()=>Promise.resolve().then(()=>(init_WeightedFilter(),WeightedFilter_exports)),"./filters/eloDistance.ts":()=>Promise.resolve().then(()=>(init_eloDistance(),eloDistance_exports)),"./filters/hierarchyDefinition.ts":()=>Promise.resolve().then(()=>(init_hierarchyDefinition(),hierarchyDefinition_exports)),"./filters/index.ts":()=>Promise.resolve().then(()=>(init_filters(),filters_exports)),"./filters/inferredPreferenceStub.ts":()=>Promise.resolve().then(()=>(init_inferredPreferenceStub(),inferredPreferenceStub_exports)),"./filters/interferenceMitigator.ts":()=>Promise.resolve().then(()=>(init_interferenceMitigator(),interferenceMitigator_exports)),"./filters/relativePriority.ts":()=>Promise.resolve().then(()=>(init_relativePriority(),relativePriority_exports)),"./filters/types.ts":()=>Promise.resolve().then(()=>(init_types2(),types_exports2)),"./filters/userGoalStub.ts":()=>Promise.resolve().then(()=>(init_userGoalStub(),userGoalStub_exports)),"./filters/userTagPreference.ts":()=>Promise.resolve().then(()=>(init_userTagPreference(),userTagPreference_exports)),"./generators/CompositeGenerator.ts":()=>Promise.resolve().then(()=>(init_CompositeGenerator(),CompositeGenerator_exports)),"./generators/elo.ts":()=>Promise.resolve().then(()=>(init_elo(),elo_exports)),"./generators/index.ts":()=>Promise.resolve().then(()=>(init_generators(),generators_exports)),"./generators/prescribed.ts":()=>Promise.resolve().then(()=>(init_prescribed(),prescribed_exports)),"./generators/srs.ts":()=>Promise.resolve().then(()=>(init_srs(),srs_exports)),"./generators/types.ts":()=>Promise.resolve().then(()=>(init_types(),types_exports)),"./index.ts":()=>Promise.resolve().then(()=>(init_navigators(),navigators_exports)),"./pipelinePlan.ts":()=>Promise.resolve().then(()=>(init_pipelinePlan(),pipelinePlan_exports)),"./regulators.ts":()=>Promise.resolve().then(()=>(init_regulators(),regulators_exports))})}}),navigators_exports={};__export(navigators_exports,{ContentNavigator:()=>ContentNavigator,DIVERSITY_FLOOR:()=>DIVERSITY_FLOOR,DIVERSITY_STRENGTH:()=>DIVERSITY_STRENGTH,NavigatorRole:()=>NavigatorRole,NavigatorRoles:()=>NavigatorRoles,Navigators:()=>Navigators,captureStrategyPressure:()=>captureStrategyPressure,clearSrsBacklogDebug:()=>clearSrsBacklogDebug,clearStrategyPressureDebug:()=>clearStrategyPressureDebug,diversityRerank:()=>diversityRerank,drainCapturedRuns:()=>drainCapturedRuns,getActivePipeline:()=>getActivePipeline,getCardOrigin:()=>getCardOrigin,getRegisteredFilterKind:()=>getRegisteredFilterKind,getRegisteredNavigator:()=>getRegisteredNavigator,getRegisteredNavigatorNames:()=>getRegisteredNavigatorNames,getRegisteredNavigatorRole:()=>getRegisteredNavigatorRole,getRunsForSession:()=>getRunsForSession,getSrsBacklogDebug:()=>getSrsBacklogDebug,getStrategyPressureDebug:()=>getStrategyPressureDebug,hasRegisteredNavigator:()=>hasRegisteredNavigator,initializeNavigatorRegistry:()=>initializeNavigatorRegistry,isFilter:()=>isFilter,isGenerator:()=>isGenerator,mountPipelineDebugger:()=>mountPipelineDebugger,pipelineDebugAPI:()=>pipelineDebugAPI,registerNavigator:()=>registerNavigator,setDebugSessionId:()=>setDebugSessionId});function registerNavigator(e,t,n){navigatorRegistry.set(e,{constructor:t,role:n}),logger.debug(`[NavigatorRegistry] Registered: ${e}${n?` (${n})`:``}`)}function getRegisteredNavigator(e){return navigatorRegistry.get(e)?.constructor}function hasRegisteredNavigator(e){return navigatorRegistry.has(e)}function getRegisteredNavigatorRole(e){return navigatorRegistry.get(e)?.role}function getRegisteredFilterKind(e){return navigatorRegistry.get(e)?.constructor?.kind}function getRegisteredNavigatorNames(){return Array.from(navigatorRegistry.keys())}async function initializeNavigatorRegistry(){logger.debug(`[NavigatorRegistry] Initializing built-in navigators...`);let[e,t]=await Promise.all([Promise.resolve().then(()=>(init_elo(),elo_exports)),Promise.resolve().then(()=>(init_srs(),srs_exports))]),n=await Promise.resolve().then(()=>(init_prescribed(),prescribed_exports));registerNavigator(`elo`,e.default),registerNavigator(`srs`,t.default),registerNavigator(`prescribed`,n.default);let[r,a,o,s,c]=await Promise.all([Promise.resolve().then(()=>(init_hierarchyDefinition(),hierarchyDefinition_exports)),Promise.resolve().then(()=>(init_interferenceMitigator(),interferenceMitigator_exports)),Promise.resolve().then(()=>(init_relativePriority(),relativePriority_exports)),Promise.resolve().then(()=>(init_userTagPreference(),userTagPreference_exports)),Promise.resolve().then(()=>(init_eloDistance(),eloDistance_exports))]);registerNavigator(`hierarchyDefinition`,r.default),registerNavigator(`interferenceMitigator`,a.default),registerNavigator(`relativePriority`,o.default),registerNavigator(`userTagPreference`,s.default),registerNavigator(`eloDistance`,c.default),logger.debug(`[NavigatorRegistry] Initialized ${navigatorRegistry.size} navigators: ${getRegisteredNavigatorNames().join(`, `)}`)}function getCardOrigin(e){if(e.provenance.length===0)throw Error(`Card has no provenance - cannot determine origin`);let t=e.provenance[0].reason.toLowerCase();return t.includes(`failed`)?`failed`:t.includes(`review`)?`review`:`new`}function isGenerator(e){return NavigatorRoles[e]===`generator`?!0:getRegisteredNavigatorRole(e)===`generator`}function isFilter(e){return NavigatorRoles[e]===`filter`?!0:getRegisteredNavigatorRole(e)===`filter`}var navigatorRegistry,Navigators,NavigatorRole,NavigatorRoles,ContentNavigator,init_navigators=__esm({"src/core/navigators/index.ts"(){init_diversityRerank(),init_PipelineDebugger(),init_SrsDebugger(),init_StrategyPressureDebugger(),init_logger(),init_(),init_2(),init_3(),navigatorRegistry=new Map,Navigators=(e=>(e.ELO=`elo`,e.SRS=`srs`,e.PRESCRIBED=`prescribed`,e.HIERARCHY=`hierarchyDefinition`,e.INTERFERENCE=`interferenceMitigator`,e.RELATIVE_PRIORITY=`relativePriority`,e.USER_TAG_PREFERENCE=`userTagPreference`,e.ELO_DISTANCE=`eloDistance`,e))(Navigators||{}),NavigatorRole=(e=>(e.GENERATOR=`generator`,e.FILTER=`filter`,e))(NavigatorRole||{}),NavigatorRoles={elo:`generator`,srs:`generator`,prescribed:`generator`,hierarchyDefinition:`filter`,interferenceMitigator:`filter`,relativePriority:`filter`,userTagPreference:`filter`,eloDistance:`filter`},ContentNavigator=class{constructor(e,t,n){_defineProperty(this,`user`,void 0),_defineProperty(this,`course`,void 0),_defineProperty(this,`strategyName`,void 0),_defineProperty(this,`strategyId`,void 0),_defineProperty(this,`learnable`,void 0),_defineProperty(this,`staticWeight`,void 0),this.user=e,this.course=t,n&&(this.strategyName=n.name,this.strategyId=n._id,this.learnable=n.learnable,this.staticWeight=n.staticWeight)}get strategyKey(){return this.constructor.name}async getStrategyState(){if(!this.user||!this.course)throw Error(`Cannot get strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.`);return this.user.getStrategyState(this.course.getCourseID(),this.strategyKey)}async putStrategyState(e){if(!this.user||!this.course)throw Error(`Cannot put strategy state: navigator not properly initialized. Ensure user and course are provided to constructor.`);return this.user.putStrategyState(this.course.getCourseID(),this.strategyKey,e)}static async create(e,t,n){let r=n.implementingClass,a=getRegisteredNavigator(r);if(a)return logger.debug(`[ContentNavigator.create] Using registered navigator: ${r}`),new a(e,t,n);logger.debug(`[ContentNavigator.create] Navigator not in registry, attempting dynamic import: ${r}`);let o;for(let e of[`.ts`,`.js`,``]){try{if(o=(await globImport_generators(`./generators/${r}${e}`)).default,o)break}catch(t){logger.debug(`Failed to load generator ${r}${e}:`,t)}try{if(o=(await globImport_filters(`./filters/${r}${e}`)).default,o)break}catch(t){logger.debug(`Failed to load filter ${r}${e}:`,t)}try{if(o=(await globImport(`./${r}${e}`)).default,o)break}catch(t){logger.debug(`Failed to load legacy ${r}${e}:`,t)}if(o)break}if(!o)throw Error(`Could not load navigator implementation for: ${r}`);return new o(e,t,n)}async getWeightedCards(e){throw Error(`${this.constructor.name} must implement getWeightedCards(). `)}setEphemeralHints(e){}}}});function randIntWeightedTowardZero(e){return Math.floor(Math.random()*Math.random()*Math.random()*e)}async function getCourseTagStubs(e){logger.debug(`Getting tag stubs for course: ${e}`);let t=await filterAllDocsByPrefix(getCourseDB2(e),`TAG`.valueOf()+`-`);return t.rows.forEach(e=>{logger.debug(` Tag stub for doc: ${e.id}`)}),t}async function createTag(e,t,n){logger.debug(`Creating tag: ${t}...`);let r=getTagID(t);return await getCourseDB2(e).put({course:e,docType:`TAG`,name:t,snippet:``,taggedCards:[],wiki:``,author:n,_id:r})}async function updateTag(e){let t=await getTag(e.course,e.name);return await getCourseDB2(e.course).put({...e,_rev:t._rev})}async function getTag(e,t){let n=getTagID(t);return getCourseDB2(e).get(n)}async function removeTagFromCard(e,t,n){n=getTagID(n);let r=getCourseDB2(e),a=await r.get(n);return a.taggedCards=a.taggedCards.filter(e=>t!==e),r.put(a)}async function getAppliedTags(e,t){return await getCourseDB2(e).query(`getTags`,{startkey:t,endkey:t})}async function updateCredentialledCourseConfig(e,t){logger.debug(`Updating course config:
|
|
256
256
|
|
|
257
257
|
${JSON.stringify(t)}
|
|
258
258
|
`);let n=getCourseDB2(e),r=await getCredentialledCourseConfig(e);return await n.put({...t,_rev:r._rev})}function isSuccessRow(e){return`doc`in e&&e.doc!==null&&e.doc!==void 0}var CoursesDB,CourseDB,init_courseDB=__esm({"src/impl/couch/courseDB.ts"(){init_couch(),init_updateQueue(),init_types_legacy(),init_logger(),init_clientCache(),init_courseAPI(),init_courseLookupDB(),init_navigators(),init_PipelineAssembler(),init_defaults(),CoursesDB=class{constructor(e){_defineProperty(this,`_courseIDs`,void 0),e&&e.length>0?this._courseIDs=e:this._courseIDs=void 0}async getCourseList(){let e=await CourseLookup.allCourseWare();return logger.debug(`AllCourses: ${e.map(e=>e.name+`, `+e._id+`
|
|
@@ -377,4 +377,4 @@ Examples:
|
|
|
377
377
|
window.skuilder.userdb.queryByType('SCHEDULED_CARD', 10)
|
|
378
378
|
window.skuilder.userdb.raw(db => db.allDocs({ limit: 5 }))
|
|
379
379
|
`)}},mountUserDBDebugger()}}),init_core=__esm({"src/core/index.ts"(){init_interfaces(),init_types_legacy(),init_user(),init_strategyState(),init_userOutcome(),init_studySession(),init_hydration(),init_Loggable(),init_util(),init_navigators(),init_bulkImport(),init_orchestration(),init_UserDBDebugger()}});init_core(),init_pipelinePlan(),init_regulators(),init_courseLookupDB(),init_logger();function isDataShapeRegistered(e,t){let n=NameSpacer.getDataShapeString({dataShape:e.name,course:e.course});return t.dataShapes.find(e=>e.name===n)!==void 0}function isDataShapeSchemaAvailable(e,t){let n=NameSpacer.getDataShapeString({dataShape:e.name,course:e.course}),r=t.dataShapes.find(e=>e.name===n);return r!==void 0&&r.serializedZodSchema!==void 0}function isQuestionTypeRegistered(e,t){let n=NameSpacer.getQuestionString({course:e.course,questionType:e.name});return t.questionTypes.some(e=>e.name===n)}function processCustomQuestionsData(e){let t=[],n=[],r=e.courses.map(e=>e.name);return e.questionClasses.forEach(a=>{let o=r.length>0?r[0]:e.meta.packageName;a.dataShapes&&Array.isArray(a.dataShapes)&&a.dataShapes.forEach(e=>{t.push({name:e.name,course:o,dataShape:e})}),n.push({name:a.name,course:o,questionClass:a,dataShapes:a.dataShapes||[],views:a.views||[]})}),{dataShapes:t,questions:n}}function registerDataShape(e,t){let n=NameSpacer.getDataShapeString({dataShape:e.name,course:e.course}),r;try{r=toZodJSON(e.dataShape)}catch(e){logger.warn(`Failed to generate schema for ${n}:`,e),r=void 0}let a=t.dataShapes.findIndex(e=>e.name===n);if(a!==-1){let o=t.dataShapes[a];return o.serializedZodSchema===r?(logger.info(`DataShape '${e.name}' from '${e.course}' already registered with identical schema`),!1):(o.serializedZodSchema?logger.info(`DataShape '${e.name}' from '${e.course}' schema has changed, updating...`):logger.info(`DataShape '${e.name}' from '${e.course}' already registered, but with no schema. Adding schema to existing entry`),t.dataShapes[a]={name:n,questionTypes:o.questionTypes,serializedZodSchema:r},logger.info(`Updated DataShape: ${n}`),!0)}return t.dataShapes.push({name:n,questionTypes:[],serializedZodSchema:r}),logger.info(`Registered DataShape: ${n}`),!0}function registerQuestionType(e,t){if(isQuestionTypeRegistered(e,t))return logger.info(`QuestionType '${e.name}' from '${e.course}' already registered`),!1;let n=NameSpacer.getQuestionString({course:e.course,questionType:e.name}),r=e.views.map(e=>e.name?e.name:`unnamedComponent`),a=e.dataShapes.map(t=>NameSpacer.getDataShapeString({course:e.course,dataShape:t.name}));return t.questionTypes.push({name:n,viewList:r,dataShapeList:a}),e.dataShapes.forEach(r=>{let a=NameSpacer.getDataShapeString({course:e.course,dataShape:r.name});for(let e of t.dataShapes)e.name===a&&e.questionTypes.push(n)}),logger.info(`Registered QuestionType: ${n}`),!0}function removeDataShape(e,t){let n=t.dataShapes.findIndex(t=>t.name===e);return n===-1?(logger.info(`DataShape '${e}' not found in course config`),!1):(t.dataShapes.splice(n,1),t.questionTypes.forEach(t=>{let n=t.dataShapeList.indexOf(e);n!==-1&&t.dataShapeList.splice(n,1)}),logger.info(`Removed DataShape: ${e}`),!0)}function removeQuestionType(e,t){let n=t.questionTypes.findIndex(t=>t.name===e);return n===-1?(logger.info(`QuestionType '${e}' not found in course config`),!1):(t.questionTypes.splice(n,1),t.dataShapes.forEach(t=>{let n=t.questionTypes.indexOf(e);n!==-1&&t.questionTypes.splice(n,1)}),logger.info(`Removed QuestionType: ${e}`),!0)}async function removeCustomQuestionTypes(e,t,n,r){try{logger.info(`Beginning custom question removal`),logger.info(`Removing ${e.length} data shapes and ${t.length} question types`);let a=0;for(let e of t)removeQuestionType(e,n)&&a++;for(let t of e)removeDataShape(t,n)&&a++;logger.info(`Updating course configuration...`);let o=await r.updateCourseConfig(n);if(!o.ok)throw Error(`Failed to update course config: ${JSON.stringify(o)}`);return logger.info(`Custom question removal complete: ${a} items removed`),{success:!0,removedCount:a}}catch(e){let t=e instanceof Error?e.message:String(e);return logger.error(`Custom question removal failed: ${t}`),{success:!1,removedCount:0,errorMessage:t}}}async function registerSeedData(e,t,n){if(e.questionClass.seedData&&Array.isArray(e.questionClass.seedData)){logger.info(`Registering seed data for question: ${e.name}`);try{if(e.dataShapes.length>0)for(let r of e.questionClass.seedData){let a=e.questionClass.seedMeta?.(r)??{};await t.addNote(e.course,e.dataShapes[0],r,n,a.tags??[],void 0,a.elo===void 0?void 0:toCourseElo(a.elo))}logger.info(`Seed data registered for question: ${e.name}`)}catch(t){logger.warn(`Failed to register seed data for question '${e.name}': ${t instanceof Error?t.message:String(t)}`)}}}async function registerBlanksCard(e,t,n,r,a){try{logger.info(`Registering BlanksCard data shapes and question type...`);let o=0,s=`default`;for(let e of t)registerDataShape({name:e.name,course:s,dataShape:e},n)&&o++;let c={name:e.name,course:s,questionClass:{name:e.name,dataShapes:t,views:e.views||[]},dataShapes:t,views:e.views||[]};registerQuestionType(c,n)&&o++,logger.info(`Updating course configuration with BlanksCard...`);let l=await r.updateCourseConfig(n);if(!l.ok)throw Error(`Failed to update course config: ${JSON.stringify(l)}`);return a&&await registerSeedData(c,r,a),logger.info(`BlanksCard registration complete: ${o} items registered`),{success:!0}}catch(e){let t=e instanceof Error?e.message:String(e);return logger.error(`BlanksCard registration failed: ${t}`),{success:!1,errorMessage:t}}}async function registerCustomQuestionTypes(e,t,n,r){try{logger.info(`Beginning custom question registration`),logger.info(`Processing ${e.questionClasses.length} question classes`);let{dataShapes:a,questions:o}=processCustomQuestionsData(e);logger.info(`Found ${a.length} data shapes and ${o.length} questions`);let s=0;logger.info(`Registering data shapes...`);for(let e of a)registerDataShape(e,t)&&s++;logger.info(`Registering question types...`);for(let e of o)registerQuestionType(e,t)&&s++;logger.info(`Updating course configuration...`);let c=await n.updateCourseConfig(t);if(!c.ok)throw Error(`Failed to update course config: ${JSON.stringify(c)}`);if(r){logger.info(`Registering seed data...`);for(let e of o)await registerSeedData(e,n,r)}return logger.info(`Custom question registration complete: ${s} items registered`),{success:!0,registeredCount:s}}catch(e){let t=e instanceof Error?e.message:String(e);return logger.error(`Custom question registration failed: ${t}`),{success:!1,registeredCount:0,errorMessage:t}}}init_study(),init_util2(),init_factory(),init_userDBHelpers();export{getRegisteredNavigatorNames as $,validateMigration as $t,clearSrsBacklogDebug as A,processCustomQuestionsData as At,endSessionTracking as B,resetIntakeClock as Bt,StaticToCouchDBMigrator as C,mountPipelineDebugger as Ct,buildStrategyStateId as D,newSessionId as Dt,areQuestionRecords as E,newInterval as Et,computeOutcomeSignal as F,registerNavigator as Ft,getAppDataDirectory as G,setDebugSessionId as Gt,frozenMsAt as H,reviewWeight as Ht,computeSpread as I,registerQuestionType as It,getDataLayer as J,stepIntakeClock as Jt,getCardHistoryID as K,snapshotQueues as Kt,createOrchestrationContext as L,registerSeedData as Lt,clearStrategyPressureDebug as M,recordUserOutcome as Mt,computeDeviation as N,registerActiveController as Nt,captureMixerRun as O,pipelineDebugAPI as Ot,computeEffectiveWeight as P,registerDataShape as Pt,getRegisteredNavigator as Q,userDBDebugAPI as Qt,diversityRerank as R,removeDataShape as Rt,SessionController as S,mountMixerDebugger as St,applyReading as T,mountUserDBDebugger as Tt,getActiveController as U,scoreAccuracyInZone as Ut,ensureAppDataDirectory as V,reviewMassReading as Vt,getActivePipeline as W,sessionDebugAPI as Wt,getLapses as X,updateLearningState as Xt,getDbPath as Y,toggleSessionOverlay as Yt,getRegisteredFilterKind as Z,updateStrategyWeight as Zt,NavigatorRoles as _,isReview as _t,DIVERSITY_FLOOR as a,getStudySource as at,QuotaRoundRobinMixer as b,makeStudySessionId as bt,DocTypePrefixes as c,initializeDataDirectory as ct,GuestUsername as d,intakeHours as dt,validateProcessorConfig as en,getRegisteredNavigatorRole as et,HYDRATION_MARKER_ID as f,intakeReading as ft,NavigatorRole as g,isQuestionTypeRegistered as gt,NOT_SET as h,isQuestionRecord as ht,DEFAULT_REGULATOR_CONFIG as i,getStreak as it,clearStaleSessionDebugState as j,recordCardPresentation as jt,captureStrategyPressure as k,planPipeline as kt,ENV as l,initializeDataLayer as lt,Loggable as m,isGenerator as mt,CouchDBToStaticPacker as n,getSrsBacklogDebug as nt,DIVERSITY_STRENGTH as o,hasRegisteredNavigator as ot,INTAKE_CLOCK_KEY as p,isFilter as pt,getCardOrigin as q,startSessionTracking as qt,CourseLookup as r,getStrategyPressureDebug as rt,DocType as s,importParsedCards as st,ContentNavigator as t,validateStaticCourse as tn,getRunsForSession as tt,FileSystemError as u,initializeNavigatorRegistry as ut,Navigators as v,log as vt,TagFilteredContentSource as w,mountSessionDebugger as wt,REVIEW_TIME_FORMAT2 as x,mixerDebugAPI as xt,PIPELINE_STAGES as y,makeScheduledCardId as yt,drainCapturedRuns as z,removeQuestionType as zt};
|
|
380
|
-
//# sourceMappingURL=dist-
|
|
380
|
+
//# sourceMappingURL=dist-BeppzTWu.js.map
|